一、Mybatis的各种查询功能
1.若查询结果只有一条时 (1)可以使用实体类对象接收 (2)也可以使用list和map集合接收; 2.若查询结果有多条 (1)使用实体类类型的的list集合接收 (2)使用map类型的list集合接收 (3)可以在mapper接口的方法上添加@MapKey注解,此时可以将map集合作为值,以某个唯一字段的值作为键,放在同一个map集合中
二、特殊SQL的执行
1.模糊查询
<select id="getUserByLike" resultType="com.jd.wds.pojo.User">
select * from user where username like "%"#{username}"%"
</select>
2.批量删除
<delete id="deleteMore">
delete from user where id in (${id})
</delete>
3.动态设置表名
<select id="getUserByTableName" resultType="com.jd.wds.pojo.User">
select * from ${tableName}
</select>
4.字段名和属性名不一致 根据不同的规范,创建表时字段选用下划线命名,创建类的属性名选用小驼峰命名,此时就会出现字段名和属性名不完全对应,三种解决方法:
<select id="getAllEmp" resultType="com.jd.wds.pojo.Emp">
select eid,emp_name empName,age,sex,email from t_emp
</select>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
<resultMap id="empResultMap" type="com.jd.wds.pojo.Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</resultMap>
<select id="getAllEmp" resultMap="empResultMap">
select * from t_emp
</select>
5.多对一的映射关系 多对一对应对象,一对多对应集合 举个栗子:查询某个员工信息及所在的部门信息(多个员工对应一个部门,典型的多对一) 方法1:resultMap通过级联属性赋值处理
<resultMap id="empAndDeptOne" type="com.jd.wds.pojo.Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<result property="dept.did" column="did"></result>
<result property="dept.deptName" column="dept_name"></result>
</resultMap>
<select id="getEmpAndDept" resultMap="empAndDeptOne">
SELECT * FROM t_emp LEFT JOIN t_dept ON t_emp.did = t_dept.did WHERE t_emp.eid = #{eid}
</select>
方法2:使用association专门处理级联属性赋值
<resultMap id="empAndDeptTwo" type="com.jd.wds.pojo.Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<association javaType="com.jd.wds.pojo.Dept" property="dept">
<result property="did" column="did"></result>
<result property="deptName" column="dept_name"></result>
</association>
</resultMap>
<select id="getEmpAndDept" resultMap="empAndDeptTwo">
SELECT * FROM t_emp LEFT JOIN t_dept ON t_emp.did = t_dept.did WHERE t_emp.eid = #{eid}
</select>
方法3:使用分步查询解决
<resultMap id="EmpAndDeptByStepOne" type="com.jd.wds.pojo.Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<association property="dept" select="com.jd.wds.mapper.DeptMapper.getEmpAndDeptByStepTwo" column="did"></association>
</resultMap>
<select id="getEmpAndDeptByStepOne" resultMap="EmpAndDeptByStepOne">
select * from t_emp where eid=#{eid}
</select>
<select id="getEmpAndDeptByStepTwo" resultType="com.jd.wds.pojo.Dept">
select * from t_dept where did = #{did}
</select>
分步查询的好处:可以实现延迟加载,提高SQL的复用,必须在配置文件中开启才可使用,默认不开启延时加载。 6.一对多的映射关系 多对一对应对象,一对多对应集合 举个栗子:查询某个部门以及部门中员工的信息(一个部门可以有多个员工,典型的一对多) 方法1:使用collection处理一对多的结果映射
<resultMap id="DeptAndEmp" type="com.jd.wds.pojo.Dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps" ofType="com.jd.wds.pojo.Emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
</collection>
</resultMap>
<select id="getDeptAndEmp" resultMap="DeptAndEmp">
select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did}
</select>
方法2:使用分步查询处理一对多的结果映射
<resultMap id="getDeptAndEmpByStep" type="com.jd.wds.pojo.Dept">
<id property="did" column="did" ></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps" select="com.jd.wds.mapper.EmpMapper.getDeptAndEmpByStepTwo" column="did">
</collection>
</resultMap>
<select id="getDeptAndEmpByStepOne" resultMap="getDeptAndEmpByStep">
select * from t_dept where did = #{did}
</select>
<select id="getDeptAndEmpByStepTwo" resultType="com.jd.wds.pojo.Emp">
select * from t_emp where did = #{did}
</select>
三、动态SQL
1.< if > 元素 根据标签中test属性所对应的表达式来确定标签中的内容是否要拼接到SQL中。
<select id="getEmpDynamicCondition" resultType="com.jd.wds.pojo.Emp">
select * from t_emp where 1=1
<if test="empName != null and empName !=''">
and emp_name = #{empName}
</if>
<if test="age != null and age !=''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="email != null and email != ''">
and email = #{email}
</if>
</select>
2.< where >元素 当标签中有内容时,将自动生成where关键字,将内容之前的and或or去掉;当标签中没有内容时,where没有任何效果。(and或or在内容之后会报错)
<select id="getEmpDynamicCondition" resultType="com.jd.wds.pojo.Emp">
select * from t_emp
<where>
<if test="empName != null and empName !=''">
and emp_name = #{empName}
</if>
<if test="age != null and age !=''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="email != null and email != ''">
and email = #{email}
</if>
</where>
</select>
3.< trim >元素 若标签中有内容: prefix/suffix:将trim标签中内容前面或后面添加指定内容 suffixoverrides /prefixoverrides : 将trim标签中内容前面或后面去掉指定内容 若标签中没有内容,trim标签没有任何效果。
<select id="getEmpDynamicCondition" resultType="com.jd.wds.pojo.Emp">
select * from t_emp
<trim prefix="where" prefixOverrides="and|or">
<if test="empName != null and empName !=''">
and emp_name = #{empName}
</if>
<if test="age != null and age !=''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
<if test="email != null and email != ''">
and email = #{email}
</if>
</trim>
</select>
4.< choose > < when > < otherwise >元素 相当于if,else if,else if,else
<select id="getEmpDynamicCondition" resultType="com.jd.wds.pojo.Emp">
select * from t_emp where 1=1
<choose>
<when test="empName != null and empName !=''">
and emp_name = #{empName}
</when>
<when test="age != null and age !=''">
and age = #{age}
</when>
<when test="sex != null and sex != ''">
and sex = #{sex}
</when>
<when test="email != null and email != ''">
and email = #{email}
</when>
<otherwise>
did = 1
</otherwise>
</choose>
</select>
5.< foreach >元素 foreach用于遍历操作,经常用于批量删除、批量添加等操作。
<delete id="deleteMoreUser">
delete from t_emp where eid in
<foreach collection="eids" open="(" close=")" separator="," item="eid">
#{eid}
</foreach>
delete from t_emp where
<foreach collection="eids" item="eid" separator="or">
eid = #{eid}
</foreach>
</delete>
<insert id="insertMoreUser">
insert into t_emp values
<foreach collection="emps" separator="," item="emp">
(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},#{emp.did})
</foreach>
</insert>
6.SQL标签 用于设置SQL片段,在需要的位置进行引用即可。
<sql id="columns">eid,emp_name,age,sex,email</sql>
<select id="selectAllUser" resultType="com.jd.wds.pojo.Emp">
select <include refid="colums"></include> from t_emp where eid = #{eid}
</select>
四、Mybatis缓存
1.Mybatis的一级缓存
缓存只是针对查询功能,一级缓存是SqlSession级别的,默认开启,下次使用相同的SqlSession查询相同的数据时,直接从缓存中获取,不会从数据库中查询(只执行一次SQL语句,有两个相同的结果)。 一级缓存失效的4种情况: (1)不同的SqlSession对应的一级缓存 (2)同一个SqlSession对应的查询条件不同 (3)同一个SqlSession两次查询之间执行了任何一次增删改操作 (4)同一个SqlSesion两次查询之间手动清理了缓存
sqlSession.clearCache();
2.Mybatis的二级缓存
二级缓存是SqlSessionFactory级别,通过同一个SqlSessionFactory创建的SqlSession的查询结果会被缓存,此后若执行相同的查询语句,结果就会从缓存中获取。 (1)二级缓存开启的条件: ① 在核心配置文件中,设置全局配置属性cacheEnabled=“true”
<setting name="cachedEnable" value="true"/>
② 在映射文件中设置标签< cache /> ③ 二级缓存必须在SqlSession关闭或提交后生效、 ④ 查询的数据所转换的实体类类型必须实现序列化接口 (2)二级缓存失效的条件 两次查询之间执行了任意的增删改操作,会使一二级缓存同时失效。 (3)二级缓存的相关配置 (4)缓存查询的顺序
|