特殊SQL的执行
#{} 和 ${} 的区别
#{} 解析过后会自动添加'',而${} 相当于字符串凭借,不会自动生成''
模糊查询
select * from t_user where username like '%${username}%'
select * from t_user where username like concat('%',#{username},'%')
select * from t_user where username like "%"#{username}"%"
批量删除
delete from t_user where id in(${ids})
动态设置表名
select * from ${tablename} ...
添加功能获取自增的主键
<insert id = "insertUser" useGenerateKeys="true" keyProperty="id">
insert into t_user values(null,#{username},#{password},#{age},#{age},#{sex},#{email})
</insert>
# useGenerateKeys:设置当前标签中的sql使用了自增的主键
# keyProperty:将自增的主键的值赋值给传输到映射文件中参数的某个属性
自定义映射resultMap
解决字段名和属性名不一致的情况
-
为字段起别名,保持和属性名的一致
-
设置全局配置,将_自动映射为驼峰
-
通过resultMap设置自定义的映射关系
处理多对一映射关系方式
-
级联属性赋值
<resultMap id = "empAndDeptResultMap" type = "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.depeName" column="dept_name"></result> </resultMap> <select id = "getEmpAndDept" resultMap="empAndDeptResultMap"> select * from t_emp left join on t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid} </select>
-
association
<resultMap id = "empAndDeptResultMap" type = "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" javaType"Dept"> <id property="did" column="did"></id> <result property="deptName" column="dept_name"></result> </association> </resultMap> # association:处理多对一映射关系 # property:需要处理多对的映射关系的属性名 # javaType:该属性的类型 <select id = "getEmpAndDept" resultMap="empAndDeptResultMap"> select * from t_emp left join on t_dept on t_emp.did = t_dept.did where t_emp.eid = #{eid} </select>
-
分步查询
<resultMap id = "empAndDeptResultMap" type = "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.lzf.mybatis.mapper.DeptMapper.getEmpAndDeptByStep" column="did"> </association> </resultMap>
分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置信息 lazyLoadingEnabled:延迟加载的开关,当开启时,所有关联对象都会延迟加载 aggressivelazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性,否则,每个属性会按需加载 此时就可以实现按需加载,获取的数据是什么,就只会执行相应的SQL,此时可通过association和collection中的fetchType属性设置当前的分步查询是否使用延迟加载,fetchType = "lazy"(延迟加载) | "eager"(立即加载)
处理一对多映射关系
-
collection
<resultMap id="deptAndEmpResultMap" type="Dept"> <id property="did" column="did"></did> <result property="deptName" column="dept_name"></result> <collection perperty="emps" ofType="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="emain"></result> </collection> </resultMap> <select id="getDeptAndEmp" resultMap="deptAndEmpResultMap"> select * from t_dept left join t_emp on t_dept.did = t_emp.did where t_dept.did = #{did} </select>
-
分步查询
<resultMap id = "deptAndEmpByStep" type="Dept"> <id property="did" column="did"></id> <result property="deptName" column="dept_name"></result> <collection property="emps" select"com.lzf.mybatis.mapper.EmpMapper" column="did"> </collection> </resultMap>
动态SQL
mybatis 框架的动态SQL技术是一种根据特定条件动态拼接SQL语句的功能,它存在的意义是为了解决拼接SQL语句字符串的痛点问题
if
根据标签中test属性所对应的表达式决定标签中的内容是否需要拼接到SQL中
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp where 1 = 1
<if test="empName != null and empName != ''">
emp_name = #{empName}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
</select>
where
当where标签中有内容时,会自动生成where关键字,并且将内容前多余的and或or去掉
当where标签中没有内容时,此时where标签没有任何效果
注意:where标签不能将其中内容后面多余的and或or去掉
<select id="getEmpByCondition" resultType="Emp">
select * from t_emp
<where>
<if test="empName != null and empName != ''">
emp_name = #{empName}
</if>
<if test="age != null and age != ''">
and age = #{age}
</if>
<if test="sex != null and sex != ''">
and sex = #{sex}
</if>
</where>
</select>
trim
-
prefix | suffix:将trim标签中内容前面 | 后面添加指定内容
-
prefixOverrides | suffixOverrides:将trim标签中内容前面 | 后面去掉指定内容
<select id="getEmpByCondition" resultMap= "Emp">
select * from t_emp
<trim prefix="where" suffixOverrides="and|or">
<if test="empName != null and empName != ''">
emp_name = #{empName} and
</if>
<if test="age != null and age != ''">
age = #{age} or
</if>
<if test="sex != null and sex != ''">
sex = #{sex} and
</if>
</trim>
</select>
foreach
<delete id="deleteMoreByArray">
delete from t_emp where eid in
(
<foreach collection="eids" item="eid" separator=",">
#{eid}
<foreach>
)
</delete>
<delete id="deleteMoreByArray">
delete from t_emp where
<foreach collection="eids" item="eid" separator="or">
eid = #{eid}
</foreach>
</delete>
mybatis的缓存
Mybatis的一级缓存
一级缓存是SqlSession级别的,通过一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问
使一级缓存失效的四种情况:
-
不同的SqlSession对应不同的以及缓存
-
同一个SqlSession但是查询条件不同
-
同一个SqlSession两次查询期间执行了任何一次增删改操作
-
同一个SqlSession两次查询期间手动清空了缓存
Mybatis二级缓存
二级缓存是SqlSessionFactory级别,通过一个SqlSessionFactory创建SqlSession查询的结果会被缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取
分页插件
分页插件的使用步骤
-
添加依赖
<dependency> <groupId>com.github.pagehelpher</groupId> <artifactId>pagehelper</artifactId> <version>5.2.0</version> </dependency>
-
配置分页插件
在mybatis的核心配置文件中配置插件
<plugins> <!--设置分页插件--> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>