(12).处理多对一映射关系
-
级联的方式
<resultMap id="empAndDept" type="Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="emp_gender" property="empGender"></result> <result column="emp_age" property="empAge"></result> <result column="dept_id" property="dept.deptId"></result> <result column="dept_name" property="dept.deptName"></result> </resultMap> <select id="getEmp" resultMap="empAndDept"> select * from emp e left join dept d on e.dept_id = d.dept_id where e.emp_id = #{id} </select>
-
association的方式:处理多对一和一对一(处理实体类类型的属性)
<resultMap id="empAndDept" type="Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="emp_gender" property="empGender"></result> <result column="emp_age" property="empAge"></result> <association property="dept" javaType="Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_Name" property="deptName"></result> </association> </resultMap> <select id="getEmp" resultMap="empAndDept"> select * from emp e left join dept d on e.dept_id = d.dept_id where e.emp_id = #{id} </select>
-
使用分步查询的方式
<resultMap id="empAndDeptStep" type="Emp">
<id column="emp_id" property="empId"></id>
<result column="emp_name" property="empName"></result>
<result column="emp_gender" property="empGender"></result>
<result column="emp_age" property="empAge"></result>
<association property="dept" select="com.xs.mybatis.mapper.DeptMapper.getDeptStepTow" column="dept_id">
</association>
</resultMap>
<!-- Emp getEmpStepOne(@Param("id") int id);-->
<select id="getEmpStepOne" resultMap="empAndDeptStep">
select *from emp where emp_id = #{id}
</select>
<!-- Dept getDeptStepTow(@Param("id") int id);-->
<select id="getDeptStepTow" resultType="Dept">
select * from dept where dept_id = #{id}
</select>
(13).延迟加载
Mybatis -config.xml文件中全局配置
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true"/>
<!--开启按需加载-->
<setting name="aggressiveLazyLoading" value="false"/>
<!--
fetchType:在开启了延迟加载的环境中,设置是否启用延迟家长
fetchType="eager(立即加载) | lazy(延迟加载) "
-->
<association property="dept" fetchType="eager" select="com.xs.mybatis.mapper.DeptMapper.getDeptStepTow" column="dept_id"
association>
(14).处理一对多的映射关系
-
通过collection处理
<resultMap id="deptAndEmp" type="Dept"> <id column="dept_id" property="deptId"></id> <result column="dept_name" property="deptName"></result> <!-- ofType:定义集合数据的类型 --> <collection property="emps" ofType="Emp"> <id column="emp_id" property="empId"></id> <result column="emp_name" property="empName"></result> <result column="emp_gender" property="empGender"></result> <result column="emp_age" property="empAge"></result> </collection> </resultMap> <!-- Dept getDepAndEmp(@Param("id") int id);--> <select id="getDepAndEmp" resultMap="deptAndEmp"> select * from dept d left join emp e on d.dept_id = e.dept_id where d.dept_id = #{id} </select>
(15).动态SQL
-
if
<!-- List<Emp> getEmpByCondition(Emp emp);--> <select id="getEmpByCondition" resultType="Emp"> select *from emp where <if test="empName != null and empName != ''"> emp_name =#{empName} </if> <if test="empAge != null and empAge != ''"> and emp_age =#{empAge} </if> <if test="empGender != null and empGender != ''"> and emp_gender =#{empGender} </if> </select>
-
where
<!-- where和if一般结合使用: a>==若where标签中的if条件都不满足,则where标签没有任何功能,即不会添加where关键字== *b>若where标签中的if条件满足,**则where标签会自动添加where关键字,==并将条件最前方多余的==** ==***and去掉***== 注意:***where标签不能去掉条件最后多余的and*** --> <select id="getEmpByCondition" resultType="Emp"> select *from emp <where> <if test="empName != null and empName != ''"> emp_name =#{empName} </if> <if test="empAge != null and empAge != ''"> and emp_age =#{empAge} </if> <if test="empGender != null and empGender != ''"> and emp_gender =#{empGender} </if> </where> </select>
-
trim
<!-- 常用属性: prefix:在**trim标签**中的内容的前面==添加==某些内容 prefixOverrides:在**trim标签**中的内容的前面==去掉==某些内容 suffix:在**trim标签**中的内容的后面==添加==某些内容 suffixOverrides:在**trim标签**中的内容的后面==去掉==某些内容 --> <select id="getEmpByCondition" resultType="Emp"> select *from emp <trim prefix="where" suffixOverrides="and"> <if test="empName != null and empName != ''"> emp_name =#{empName} and </if> <if test="empAge != null and empAge != ''"> emp_age =#{empAge} and </if> <if test="empGender != null and empGender != ''"> emp_gender =#{empGender} </if> </trim> </select>
-
choose when otherwise 相当于 if else if
<!--List<Emp> getEmpListByChoose(Emp emp);--> <select id="getEmpListByChoose" resultType="Emp"> select <include refid="empColumns"></include> from t_emp <where> <choose> <when test="ename != '' and ename != null"> ename = #{ename} </when> <when test="age != '' and age != null"> age = #{age} </when> <when test="sex != '' and sex != null"> sex = #{sex} </when> <when test="email != '' and email != null"> email = #{email} </when> <otherwise> uname=#{name} </otherwise> </choose> </where> </select>
-
foreach
-
批量添加
<insert id="inserMoreEmp">
insert into emp values
<foreach collection="emps" item="emp" separator=",">
(null,#{emp.empName},#{emp.empGender},#{emp.empAge},null)
</foreach>
</insert>
批量删除
<!-- int deleteMoreEmp(@Param("emps")Emp[] emps);-->
<delete id="deleteMoreEmp">
delete from emp where emp_id in
<foreach collection="emps" item="item" separator="," open="(" close=")">
#{item}
</foreach>
</delete>
6.SQL
<sql id="empColumns">
eid,ename,age,sex,did
</sql>
select <include refid="empColumns"></include> from t_emp
(16).Mybatis缓存
16.1一级缓存(默认开启):
一级缓存是***SqlSession级别的***,通过同一个SqlSession查询的数据会被缓存,下次查询相同的数据,就会从缓存中直接获取,不会从数据库重新访问,默认开启着的
使一级缓存失效的四种情况:
- 不同的SqlSession对应不同的一级缓存
- 同一个SqlSession但是查询条件不同
- 同一个SqlSession两次查询期间执行了任何一次增删改操作(不管是不是针对你缓存的表)
- 同一个SqlSession两次查询期间手动清空了缓存****:sqlSession.clearCache(); //手动清空了缓存*****
16.2二级缓存:
*二级缓存是**SqlSessionFactory级别,***通过同一个SqlSessionFactory创建的SqlSession查询的结果会被
缓存;此后若再次执行相同的查询语句,结果就会从缓存中获取**
二级缓存开启的条件:
a>在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
b>在映射文件中设置标签
c>二级缓存必须在SqlSession关闭或提交(手动提交)之后有效(才能真正进入缓存)
d>查询的数据所转换的实体类类型必须实现序列化的接口
使二级缓存失效的情况:
两次查询之间执行了任意的增删改,会使一级和二级缓存同时失效
(17).分页
limit index,pageSize
pageSize:每页显示的条数
pageNum:当前页的页码
index:当前页的起始索引,index=(pageNum-1)*pageSize
count:总记录数
totalPage:总页数
totalPage = count / pageSize;
if(count % pageSize != 0){
totalPage += 1;
}
pageSize=4,pageNum=1,index=0 limit 0,4
pageSize=4,pageNum=3,index=8 limit 8,4
pageSize=4,pageNum=6,index=20 limit 8,4
首页 上一页 2 3 4 5 6 下一页 末页
①添加依赖
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.2.0</version>
</dependency>
②配置分页插件
在MyBatis的核心配置文件中配置插件
<plugins>
<!--设置分页插件-->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
分页插件的使用
a>在查询功能之前使用PageHelper.startPage(int pageNum, int pageSize)开启分页功能
pageNum:当前页的页码
pageSize:每页显示的条数
b>在查询获取list集合之后,使用PageInfo pageInfo = new PageInfo<>(List list, int
navigatePages)获取分页相关数据,更深层次获取分页属性
list:分页之后的数据
navigatePages:导航分页的页码数
c>分页相关数据
PageInfo{
pageNum=8, pageSize=4, size=2, startRow=29, endRow=30, total=30, pages=8,
list=Page{count=true, pageNum=8, pageSize=4, startRow=28, endRow=32, total=30,
pages=8, reasonable=false, pageSizeZero=false},
prePage=7, nextPage=0, isFirstPage=false, isLastPage=true, hasPreviousPage=true,
hasNextPage=false, navigatePages=5, navigateFirstPage4, navigateLastPage8,
navigatepageNums=[4, 5, 6, 7, 8]
}
pageNum:当前页的页码
pageSize:每页显示的条数
size:当前页显示的真实条数
total:总记录数
pages:总页数
prePage:上一页的页码
nextPage:下一页的页码
isFirstPage/isLastPage:是否为第一页/最后一页
hasPreviousPage/hasNextPage:是否存在上一页/下一页
navigatePages:导航分页的页码数
navigatepageNums:导航分页的页码,[1,2,3,4,5]
@Test
public void test4() throws IOException {
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);
StarMapper mapper = sqlSession.getMapper(StarMapper.class);
Page<Object> page = PageHelper.startPage(2, 3); //page中封装了分页的信息。可以没有page返回值,PageHelper.startPage(2, 3)是开启分页的必要功能,并且要放在查询zhi'qian
List<Star> stars = mapper.selectByExample(null);
PageInfo<Star> pageInfo = new PageInfo<>(stars,2); //pageinfo中封装了比page更详细的分页信息,但是是查询功能之后,不是查询功能之前
stars.forEach(System.out::println);
System.out.println(page);
System.out.println(pageInfo);
}