MyBatis 设置缓存。
缓存。内存中的一块存储空间,服务于某个应用程序。旨在将频繁读取的数据临时保存在内存中,便于二次快速访问。
无缓存。用户在访问相同数据时,需要发起多次对数据库的直接访问,导致产生大量IO、读写硬盘的操作,效率低下。
有缓存。首次访问时,查询数据库,将数据存储到缓存中。再次访问时,直接访问缓存,减少IO、硬盘读写次数、提高效率。
一级缓存。默认开启。SqlSession级别的缓存,同一个SqlSession的发起多次同构查询,会将数据保存在一级缓存中。
@Test
public void getEmpByEmpno() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
IEmpMapper mapper = sqlSession.getMapper(IEmpMapper.class);
Emp empRes = mapper.getEmpByEmpno(7369);
System.out.println(empRes);
System.out.println("--- ---");
// 取消缓存
// sqlSession.clearCache();
Emp empRes2 = mapper.getEmpByEmpno(7369);
System.out.println(empRes2);
sqlSession.close();
SqlSession sqlSession3 = MybatisUtils.getSqlSession();
IEmpMapper mapper3 = sqlSession3.getMapper(IEmpMapper.class);
Emp empRes3 = mapper3.getEmpByEmpno(7369);
System.out.println(empRes3);
sqlSession.close();
}
取消缓存时。会再次查询数据库。
二级缓存。SqlSessionFactory级别的缓存,同一个SqlSessionFactory构建的SqlSession发起的多次同构查询,会将数据保存在二级缓存中。在sqlSession.commit()或者sqlSession.close()之后生效。
// IEmpMapper.mapper
<mapper namespace="com.baidu.day.text.mapper.IEmpMapper">
<!-- 开启二级缓存 -->
<cache />
</mapper>
//Emp.java 实体类要实现序列化。
@Data
public class Emp implements Serializable {
}
开启全局缓存。默认开启。
// mabatis-config.xml
<configuration>
<properties resource="jdbc.properties"></properties>
<!-- 注意写的位置 true开启,false 关闭 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
</configuration>
关闭全局缓存,只能关闭二级缓存。
这是关闭全局缓存或不写二级缓存的打印。
Druid 连接池。
Druid 是阿里巴巴开源平台上的一个项目,整个项目由数据库连接池、插件框架和 SQL 解析器组成。该项目主要是为了扩展 JDBC 的一些限制,可以让程序员实现一些特殊的需求,比如向密钥服务请求凭证、统计 SQL 信息、SQL 性能收集、SQL 注入检查、SQL 翻译等,程序员可以通过定制来实现自己需要的功能。
// pom.xml
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.12</version>
</dependency>
// MyBatisDataSource.java
public class MyBatisDataSource extends PooledDataSourceFactory {
public MyBatisDataSource() {
System.out.println("MyBatisDataSource");
this.dataSource = new DruidDataSource();
}
}
// mabatis-config.xml
<environment id="d2">
<transactionManager type="JDBC"/>
<!-- <dataSource type="POOLED">-->
<!-- 设置自定义连接池 name的参数从 new DruidDataSource() ,commond + 点击 进去查找 -->
<dataSource type="com.baidu.day.text.utils.MyBatisDataSource">
<!-- ${} 动态参数-->
<property name="driverClassName" value="${jdbc.driverClass}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
MyBatis注解操作。
// IEmpMapper.xml
<mapper namespace="com.baidu.day.text.mapper.IEmpMapper">
<!-- 开启二级缓存 -->
<cache />
</mapper>
// IEmpMapper.java
public interface IEmpMapper {
@Select("select * from emp where empno = #{empno}")
public Emp selectEmp(Emp emp);
@Update("update emp set ename = #{ename}, job = #{job} where empno = #{empno}")
public int update(Emp emp);
@Delete("delete from emp where empno = #{empno}")
public int deleteEmp(Emp emp);
@Insert("insert into emp(ename,job) values(#{ename}, #{job})")
public int addEmp(Emp emp);
}
// 测试
@Test
public void testAddEmp() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
IEmpMapper mapper = sqlSession.getMapper(IEmpMapper.class);
Emp emp = new Emp();
emp.setEname("zs张三");
emp.setJob("yy");
int i = mapper.addEmp(emp);
System.out.println(i);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testDeleteEmp() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
IEmpMapper mapper = sqlSession.getMapper(IEmpMapper.class);
Emp emp = new Emp();
emp.setEmpno(7844);
int i = mapper.deleteEmp(emp);
System.out.println(i);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testSelectEmp() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
IEmpMapper mapper = sqlSession.getMapper(IEmpMapper.class);
Emp emp = new Emp();
emp.setEmpno(7369);
Emp empRes = mapper.selectEmp(emp);
System.out.println(empRes);
sqlSession.close();
}
@Test
public void testUpdateEmp() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
IEmpMapper mapper = sqlSession.getMapper(IEmpMapper.class);
Emp emp = new Emp();
emp.setEmpno(7499);
emp.setEname("ALLEN1");
emp.setJob("SMAN");
int i = mapper.update(emp);
System.out.println(i);
sqlSession.commit();
sqlSession.close();
}
级联查询。嵌套查询。
查询某部门的多个员工,并储存到部门实体类里。一对多查询的另一种实现方法。
代码结构。
@Data
public class Dept implements Serializable {
private Integer deptno;
private String dname;
private String loc;
private List<Emp> list;
}
@Data
public class Emp implements Serializable {
private Integer empno; // 编码
private String ename; // 姓名
private Integer deptno; //部门编号
private Double sal; // 公司
private Double comm; // 奖金
private Integer mgr; // 领导编号
private Date hiredate; // 入职时间
private String job; // 职位
}
// IDeptMapper.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.baidu.day.text.mapper.IDeptMapper">
<cache />
<sql id="base_dept">
deptno,
dname,
loc
</sql>
<resultMap id="deptResultMapper" type="dept">
<id property="deptno" column="deptno"/>
<result property="ename" column="ename"/>
<result property="job" column="job"/>
<!--
property: 实体属性
ofType: list 储存的对象
select: 级联id方法
column: 级联id方法的参数
-->
<collection property="list" ofType="Emp" column="deptno" select="com.baidu.day.text.mapper.IEmpMapper.getEmpByDeptno">
</collection>
</resultMap>
<select id="getDeptByDeptno" resultMap="deptResultMapper">
select
<include refid="base_dept" />
from dept where deptno = #{deptno}
</select>
</mapper>
// IEmpMapper.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.baidu.day.text.mapper.IEmpMapper">
<cache />
<sql id="base_emp">
empno,
ename,
job,
sal,
comm,
hiredate,
mgr,
deptno
</sql>
<select id="getEmpByDeptno" resultType="Emp">
select
<include refid="base_emp" />
from emp where deptno = #{deptno}
</select>
</mapper>
// mybatis-config.xml 部分变动代码
<mappers>
<mapper resource="mapper/IDeptMapper.xml"/>
<mapper resource="mapper/IEmpMapper.xml"/>
</mappers>
// IEmpMapperTest.java
public class IEmpMapperTest {
@Test
public void testGetDeptByDeptno() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
IDeptMapper mapper = sqlSession.getMapper(IDeptMapper.class);
Dept deptRes = mapper.getDeptByDeptno(10);
System.out.println(deptRes);
for (Emp emp : deptRes.getList()) {
System.out.println(emp);
}
sqlSession.close();
}
}
PageHelper,是适用于MyBatis框架的一个分页插件。(链接,https://pagehelper.github.io/)。
// pom.xml
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.1.10</version>
</dependency>
// mybatis-config.xml 部分变动代码
<typeAliases>
<package name="com.baidu.day.text.entity"/>
</typeAliases>
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin>
</plugins>
// 测试
@Test
public void testGetEmpList() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
IEmpMapper mapper = sqlSession.getMapper(IEmpMapper.class);
// 第一页 每页5条数据
Page<Emp> pages = PageHelper.startPage(2, 5);
List<Emp> empList = mapper.getEmpList();
for (Emp emp : empList) {
System.out.println(emp);
}
// 一般使用 pageInfo, 因为 pages 既可以是数组又可以是 Page 对象
PageInfo<Emp> pageInfo = new PageInfo<>(pages);
// 页码 从1开始
System.out.println(pageInfo.getPageNum());
// 期望查询每页个数
System.out.println(pageInfo.getPageSize());
// 实际查询到的个数,即数组个数
System.out.println(pageInfo.getSize());
// 总页数
System.out.println(pageInfo.getPages());
// 在总数中的起始值 从1开始
System.out.println(pageInfo.getStartRow());
// 在总数中的结束值
System.out.println(pageInfo.getEndRow());
}
注意。
只有在PageHelper.startPage()方法之后的第一个查询会有执行分页;
分页插件不支持带有“for update”的查询语句。
分页插件不支持“嵌套查询”,由于嵌套结果方式会导致结果集被折叠,所以无法保证分页结果数量正确。