可以通过sql标签提高sql代码的复用性
定义代码片段
<sql id="sql_count">select count(*)</sql>
使用代码片段
<select id="selectUserCount" resultType="String">
<include refid="sql_count"/> from t_user
</select>
进行条件判断,判断成功会把if内部SQL拼接到外部SQL中,否则不拼接
<if test="条件">
SQL语句
</if>
问题:直接使用if会出现多余的where和and、or等关键词
用于配置条件,会去掉多余的where、and、or关键词
select * from xx
<where>
<if test="条件">
SQL语句
</if>
</where>
用于配置update语句,用于去掉多余的,
update xx
<set>
<if test="条件">
列 = 值,
</if>
<if test="条件">
列 = 值,
</if>
...
</set>
where 条件
可以删除或添加前缀和后缀,用来拼接SQL
<trim prefix="添加前缀" suffix="添加后缀" prefixOverride="删除后缀" suffixOverride="删除后缀">
<if>...</if>
</trim>
用trim代替set
<trim prefix="set" suffixOverride=",">
..
</trim>
用于循环拼接SQL
<foreach collection="集合参数名称" item="变量名" open="开始符号" close="结束符号" seprator="分割符" index="下标">
#{变量名}
</foreach>
List<Employee> selectByIds(List<Long> ids);
--->
select * from employee where id in (1,2,3,4)
<select id="selectByIds" resultType="Employee">
<include refid="mySelect"></include>
where emp_id in
<foreach collection="ids" item="id" separator="," open="(" close=")" index="i">
#{id}
</foreach>
</select>
表之间有几种关联关系:
在进行数据库查询时,会遇到多张表相互关联的情况,下面以书籍和类型为例,配置最常见的一对多关系。
MyBatis映射文件中,在ResultMap里可以配置关联关系
主要有两种标签来映射关联属性:
collection 配置集合类型的属性
association 配置单独对象的属性
collection和association的相关参数:
配置一的一方,查询书籍类型时,能同时查询到该类型的所有书籍
1) 给类型添加书籍集合,这里需要使用collection
public class BookType {
private long id;
private String type;
//书籍的集合
private List<Book> books;
..
}
2) 书籍类型Mapper接口
public interface IBookTypeDAO {
/**
* 按id查书籍类型
* @param typeId
* @return
*/
BookType selectBookTypeById(int typeId);
}
3) 在Book映射接口中定义方法
/**
* 根据类型id查询所有书籍
* @param typeId
* @return
*/
List<Book> selectBooksByTypeId(int typeId);
4) BookType的映射文件
<resultMap id="bookTypeMap" type="BookType" >
<id property="id" column="id"></id>
<result property="type" column="type"></result>
<!--配置集合 property是集合属性 select是查询方法 javaType是集合类型
ofType是集合的数据类型 column外建列作为参数传入查询方法-->
<collection property="books" select="com.blb.bookms.dao.IBookDAO.selectBooksByTypeId"
javaType="java.util.List" ofType="Book" column="id">
</collection>
</resultMap>
<select id="selectBookTypeById" resultMap="bookTypeMap" parameterType="java.lang.Integer">
select * from tb_book_type where id = #{typeId}
</select>
这里使用的是子查询的机制,在查询书籍类型后,将每个类型id作为参数,调用书籍接口的selectBooksByTypeId方法查询书籍集合。
连接查询方式
<resultMap id="deptMap" type="Department">
<id property="deptId" column="dept_id"></id>
<result property="deptName" column="dept_name"></result>
<!--
员工集合的配置 property属性名 column子查询使用的字段
javaType集合类型 ofType集合的对象类型
select是子查询的方法
-->
<collection property="employees"
javaType="java.util.List" ofType="Employee">
<id property="empId" column="emp_id"></id>
<result property="empNo" column="emp_no"></result>
<result property="empName" column="emp_name"></result>
<result property="empAge" column="emp_age"></result>
<result property="empGender" column="emp_gender"></result>
<result property="empInfo" column="emp_info"></result>
<result property="empAddress" column="emp_address"></result>
<result property="empDeptId" column="emp_dept_id"></result>
</collection>
</resultMap>
<sql id="deptSelect">
select d.*,e.* from department d join employee e on d.dept_id = e.emp_dept_id
</sql>
<select id="selectAll" resultMap="deptMap">
<include refid="deptSelect"></include>
</select>
配置多的一方,通过书籍查询到它所属的类型
/**
* 书籍
*/
public class Book {
...
/书籍类型
private BookType bookType;
2)书籍映射文件中,使用association配置bookType属性
<resultMap id="bookMap" type="Book">
<id property="id" column="id"></id>
<result property="bookName" column="book_name"></result>
<result property="price" column="price"></result>
<result property="typeId" column="type_id"></result>
<result property="author" column="author"></result>
<result property="publishOrg" column="publish_org"></result>
<result property="publishTime" column="publish_time"></result>
<result property="state" column="state"></result>
<result property="bookImage" column="book_image"></result>
<!--映射一对一 类型-->
<association property="bookType" javaType="BookType"
select="com.blb.bookms.dao.IBookTypeDAO.selectBookTypeById" column="type_id">
</association>
</resultMap>
<select id="selectBookById" parameterType="java.lang.Integer" resultMap="bookMap">
select * from tb_book where id = #{id}
</select>
连接查询
<resultMap id="empMap" type="Employee" autoMapping="true">
<!-- <id property="empId" column="emp_id"></id>-->
<!-- <result property="empNo" column="emp_no"></result>-->
<!-- <result property="empName" column="emp_name"></result>-->
<!-- <result property="empAge" column="emp_age"></result>-->
<!-- <result property="empGender" column="emp_gender"></result>-->
<!-- <result property="empInfo" column="emp_info"></result>-->
<!-- <result property="empAddress" column="emp_address"></result>-->
<!-- <result property="empDeptId" column="emp_dept_id"></result>-->
<!--单独对象映射-->
<association property="department" javaType="Department" autoMapping="true">
<!-- <id property="deptId" column="dept_id"></id>-->
<!-- <result property="deptName" column="dept_name"></result>-->
</association>
</resultMap>
<!--sql语句重用-->
<sql id="mySelect">
-- select * from employee
select d.*,e.* from department d join employee e on d.dept_id = e.emp_dept_id
</sql>