一对多
关键字:collection ofType List
比如部门和员工的关系,一个部门下可以有多个员工
1)定义实体
public class Emp {
private int empno;
private String ename;
private String job;
private int mgr;
private String hiredate;
private int sal;
private int comm;
private int deptno;
......
}
public class Dept {
private int deptno;
private String dname;
private String loc;
private List<Emp> emp;
......
}
2)接口
package com.neuedu.day02.mapper;
import com.neuedu.pojo.Dept;
public interface DeptMapper {
public Dept findDeptById(int deptno);
}
3)映射DeptMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.neuedu.day02.mapper.DeptMapper">
<select id="findDeptById" parameterType="int" resultMap="deptMap">
SELECT d.DEPTNO,d.DNAME,d.LOC,e.EMPNO,e.ENAME,e.MGR,e.HIREDATE,e.sal,e.comm
from dept d,emp e
where d.DEPTNO=e.DEPTNO
and d.DEPTNO=#{deptno}
</select>
<resultMap type="dept" id="deptMap">
<id property="deptno" column="deptno" />
<result property="dname" column="dname" />
<result property="loc" column="loc" />
<collection property="emp" ofType="Emp">
<id property="empno" column="empno" />
<result property="ename" column="ename" />
<result property="job" column="job" />
<result property="mgr" column="mgr" />
<result property="hiredate" column="hiredate"/>
</collection>
</resultMap>
</mapper>
4)测试类
@Test
public void findDeptById() throws IOException {
// 第一步读取SqlMapConfig
// 指定文件位置
String resource = "config/SqlMapConfig.xml";
// 读取配置文件
InputStream is = Resources.getResourceAsStream(resource);
// 创建工厂s
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// 从工厂里得到sqlsession
SqlSession session = factory.openSession();
// 执行查询
DeptMapper wifedao=session.getMapper(DeptMapper.class);
Dept dept=wifedao.findDeptById(10);
List<Emp> emps=dept.getEmp();
for(Emp emp:emps){
System.out.println(emp.getEmpno());
System.out.println(emp.getEname());
System.out.println("---------------------------->");
}
session.close();
}
返回map方式(同一对一最后那种方式)
接口里的方法
public List<Map<String,Object>> findDeptByIdMap(int deptno);
xml##
<select id="findDeptByIdMap" parameterType="int" resultType="map">
SELECT d.DEPTNO,d.DNAME,d.LOC,e.EMPNO,e.ENAME,e.MGR,e.HIREDATE,e.sal,e.comm
from dept d,emp e
where d.DEPTNO=e.DEPTNO
and d.DEPTNO=#{deptno}
</select>
测试类
@Test
public void findDeptByIdMap() throws IOException {
// 第一步读取SqlMapConfig
// 指定文件位置
String resource = "config/SqlMapConfig.xml";
// 读取配置文件
InputStream is = Resources.getResourceAsStream(resource);
// 创建工厂s
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
// 从工厂里得到sqlsession
SqlSession session = factory.openSession();
// 执行查询
DeptMapper wifedao=session.getMapper(DeptMapper.class);
List<Map<String,Object>> deptlist=wifedao.findDeptByIdMap(10);
System.out.println(deptlist.size());
session.close();
}
缓存管理
1)一级缓存:默认支持一级缓存,不需要特殊配置 一级缓存是 session级别的
测试类
@Test
public void testCache() throws IOException{
SqlSession session=factory.openSession();
//执行查询
IWifeAndHus mapper=session.getMapper(IWifeAndHus.class);
WifeAndHus result=mapper.findAllByWname("马伊俐");
System.out.println(result.getW_name()+"------>"+result.getH_name());
WifeAndHus result2=mapper.findAllByWname("马伊俐");
System.out.println(result2.getW_name()+"------>"+result2.getH_name());
//关闭连接
session.close();
}
结果分析:
一级缓存测试,执行两次查询,观察后台查询数据库执行情况,发现第一次查询时查询数据库,第二次直接返回的结果。说明第一次查询结果被缓存。
2)二级缓存
二级缓存需要配置,是mapper级别的。
设置分以下几步:
1)确认ehcache的jar包依赖
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.2</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>2.10.1</version>
</dependency>
2)类路径(src/main/resource)下增加ehcache.xml
完整代码
<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="ehcache.xsd"
updateCheck="true" monitoring="autodetect"
dynamicConfig="true">
<diskStore path="D:\develop\ehcache" />
<defaultCache
maxElementsInMemory="1000"
maxElementsOnDisk="10000000"
eternal="false"
overflowToDisk="true"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU">
</defaultCache>
</ehcache>
<!-- Cache配置说明
name:Cache的唯一标识
maxElementsInMemory:内存中最大缓存对象数。
maxElementsOnDisk:磁盘中最大缓存对象数,若是0表示无穷大。
eternal:Element是否永久有效,一但设置了,timeout将不起作用。
overflowToDisk:配置此属性,当内存中Element数量达到maxElementsInMemory时,Ehcache将会Element写到磁盘中。
timeToIdleSeconds:设置Element在失效前的允许闲置时间。仅当element不是永久有效时使用,可选属性,默认值是0,也就是可闲置时间无穷大。
timeToLiveSeconds:设置Element在失效前允许存活时间。最大时间介于创建时间和失效时间之间。仅当element不是永久有效时使用,默认是0.,也就是element存活时间无穷大。
diskExpiryThreadIntervalSeconds:磁盘失效线程运行时间间隔,默认是120秒。
diskSpoolBufferSizeMB:这个参数设置DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区。
memoryStoreEvictionPolicy:当达到maxElementsInMemory限制时,Ehcache将会根据指定的策略去清理内存。默认策略是LRU(最近最少使用)。你可以设置为FIFO(先进先出)或是LFU(较少使用)。 -->
3)SqlMapConfig.xml
<!-- 打开二级缓存开关-->
<setting name="cacheEnabled" value="true"/>
4)mapper.xml里增加以下配置,开启二级缓存
<cache type="org.mybatis.caches.ehcache.EhcacheCache"></cache>
5)pojo类需要实现实例化接口
public class Wife implements Serializable
6)测试用例:
@Test
public void testCacheSec() throws IOException{
SqlSession session=factory.openSession();
SqlSession session2=factory.openSession();
//执行查询
IWifeAndHus mapper=session.getMapper(IWifeAndHus.class);
Wife result=mapper.findAllByWnameM2("马伊俐");
System.out.println(result.getW_name());
//这行必须加,否则还会查询两次
session.close();
IWifeAndHus mapper2=session2.getMapper(IWifeAndHus.class);
Wife result2=mapper2.findAllByWnameM2("马伊俐");
System.out.println(result2.getW_name());
//关闭连接
session2.close();
}