内容导读
mybatis中线程池的应用
mybatis中缓存的应用
mybatis分页应用
一、mybatis中线程池的应用
线程池用于提高数据库操作的并发和性能。通过使用线程池,MyBatis 可以重用线程来执行多个查询或更新,而不是每次执行操作时都创建新的线程。
1、操作步骤
(1)创建基于SSM项目,导入mybatis、mysql及lombok依赖
(2)设置mybatis-config.xml核心配置,mysql.properties文件
(3)编写StudentMapper接口与StudentMapper.xml映射文件,别忘了在mybatis-config中登记StudentMapper.xml映射文件,否则会出现找到不类的情况。
2、案例解析
(1)创建MyTools
public class MyTools {
//声明数据库操作的工厂对象
private static SqlSessionFactory factory;
//使用线程池来管理数据库操作对象SqlSession,它代替PreparedStatement对象功能
private static ThreadLocal<SqlSession> local = new ThreadLocal<SqlSession>();
static {
try {
//拿到配置文件的字节流
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
//直接通过工厂构建对象生成工厂对象
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
//通过线程池管理数据库操作对象
public static SqlSession getSqlSession() {
//从线程池拿已有的数据库操作对象
SqlSession ss = local.get();
//如果从线程池中取的对象为空则创建数据库操作对象
if (ss == null) {
//生成对象并设置数据库事务管理不自动提交
ss = factory.openSession(false);
//再放入线程池
local.set(ss);
}
return ss;
}
}
(2)MyTest测试类
public class MyTest {
@Test
public void getCount(){//查询记录条数
SqlSession ss = MyTools.getSqlSession();
//生成数据库操作接口引用的对象
StudentMapper sm = ss.getMapper(StudentMapper.class);
//查询记录条数
int n = sm.selectCount();
System.out.println("条数:"+n);
}
}
二、mybatis中缓存的应用
1、mybatis缓存简介
缓存用于单独管理的程序内存,能大大提高查询的性能。
mybatis有二级缓存:分别为一级缓存与二级缓存。
(1)一级缓存,mybatis自动打开的,是由SqlSession对象来管理
(2)二级缓存,mybatis没有自动打开,需要手动打开,是由SqlSessionFactory对象管理,针对大型项目建议打开,而且查询的实体类必须实现Serializable接口进行序列化,否则二级缓存也无效。
2、缓存手动打开步骤
在mybatis-config.xml中进行设置
<settings>
<!--打开二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
StudentMapper.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.mysoft.mapper.StuMapper">
<!--此文件中使用二级缓存,之后的查询语句都用二级缓存-->
<cache/>
<select id="selectCount" resultType="int" useCache="true">
select count(id)
from stu;
</select>
</mapper>
3、单元测试,事务管理与二级缓存
public class MyTest {
@Test
public void getCount() {//查询记录条数
SqlSession ss = MyTools.getSqlSession();
//生成数据库操作接口引用的对象
StudentMapper sm = ss.getMapper(StudentMapper.class);
//查询记录条数
int n = sm.selectCount();
System.out.println("条数:" + n);
}
//查询所有学生记录,同时使用事务管理
@Test
public void selectStus() {
SqlSession ss = null;
try {
//生成数据库操作对象
ss = MyTools.getSqlSession();
//生成数据库操作接口引用的对象
StudentMapper sm = ss.getMapper(StudentMapper.class);
System.out.println(sm.selectStudents());
//(1)进行事务管理
ss.commit();
} catch (Exception e) {
//(2)一旦出现异常,则将执行此处的代码,回滚恢复到初始状态
System.err.println("回滚啦!");
ss.rollback();
}
}
}
说明:当前流行在Spring boot中使用mybatis,因此,缓存的配置都在application.properties文件中进行设置。
三、mybatis分页插件
mybatis分页插件可以很方便让我们实现数据分页显示效果,提高开发效率。
3.1 pom.xml文件添加如下依赖
<!-- https://mvnrepository.com/artifact/com.github.pagehelper/pagehelper -->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
<!-- https://mvnrepository.com/artifact/com.github.jsqlparser/jsqlparser -->
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>4.0</version>
</dependency>
3.2 在Mybatis配置xml中配置拦截器插件
<plugins>
<!-- com.github.pagehelper为PageHelper类所在包名 -->
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="mysql"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,会将RowBounds第一个参数offset当成pageNum页码使用 -->
<!-- 和startPage中的pageNum效果一样-->
<property name="offsetAsPageNum" value="true"/>
<!-- 该参数默认为false -->
<!-- 设置为true时,使用RowBounds分页会进行count查询 -->
<property name="rowBoundsWithCount" value="true"/>
<!-- 设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果 -->
<!-- (相当于没有执行分页查询,但是返回结果仍然是Page类型)-->
<property name="pageSizeZero" value="true"/>
<!-- 3.3.0版本可用 - 分页参数合理化,默认false禁用 -->
<!-- 启用合理化时,如果pageNum<1会查询第一页,如果pageNum>pages会查询最后一页 -->
<!-- 禁用合理化时,如果pageNum<1或pageNum>pages会返回空数据 -->
<property name="reasonable" value="true"/>
</plugin>
</plugins>
五个参数说明:
(1)增加dialect属性,使用时必须指定该属性,可选值为oracle,mysql,mariadb,sqlite,hsqldb,postgresql,没有默认值,必须指定该属性。
(2)增加offsetAsPageNum属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,使用RowBounds分页时,会将offset参数当成pageNum使用,可以用页码和页面大小两个参数进行分页。
(3)增加rowBoundsWithCount属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,使用RowBounds分页会进行count查询。
(4)增加pageSizeZero属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。当该参数设置为true时,如果pageSize=0或者RowBounds.limit = 0就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是Page类型)。
(5)增加reasonable属性,默认值为false,使用默认值时不需要增加该配置,需要设为true时,需要配置该参数。具体作用请看上面配置文件中的注释内容。
3.3 Java代码中的应用
分页插件支持以下两种调用方式:
//第一种,RowBounds方式的调用
List<Country> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(1, 10));
//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectIf(1);
在需要进行分页的Mybatis方法前,调用PageHelper.startPage静态方法即可,紧跟在这个方法后的第一个Mybatis查询方法会被进行分页。
1、分页应用一
SqlSession sqlSession = MybatisHelper.getSqlSession();
CountryMapper countryMapper = sqlSession.getMapper(CountryMapper.class);
try {
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
//紧跟着的第一个select方法会被分页
List<Country> list = countryMapper.selectIf(1);
assertEquals(2, list.get(0).getId());
assertEquals(10, list.size());
//分页时,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>,
//或者使用PageInfo类(下面的例子有介绍)
assertEquals(182, ((Page) list).getTotal());
} finally {
sqlSession.close();
}
2、分页应用二
SqlSession sqlSession = MybatisHelper.getSqlSession();
CountryMapper countryMapper = sqlSession.getMapper(CountryMapper.class);
try {
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
//紧跟着的第一个select方法会被分页
List<Country> list = countryMapper.selectIf(1);
//后面的不会被分页,除非再次调用PageHelper.startPage
List<Country> list2 = countryMapper.selectIf(null);
//list1
assertEquals(2, list.get(0).getId());
assertEquals(10, list.size());
//分页时,实际返回的结果list类型是Page<E>,如果想取出分页信息,需要强制转换为Page<E>,
//或者使用PageInfo类(下面的例子有介绍)
assertEquals(182, ((Page) list).getTotal());
//list2
assertEquals(1, list2.get(0).getId());
assertEquals(182, list2.size());
} finally {
sqlSession.close();
}
3、分页应用三
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List<Country> list = countryMapper.selectAll();
//用PageInfo对结果进行包装
PageInfo page = new PageInfo(list);
//测试PageInfo全部属性
//PageInfo包含了非常全面的分页属性
assertEquals(1, page.getPageNum());
assertEquals(10, page.getPageSize());
assertEquals(1, page.getStartRow());
assertEquals(10, page.getEndRow());
assertEquals(183, page.getTotal());
assertEquals(19, page.getPages());
assertEquals(1, page.getFirstPage());
assertEquals(8, page.getLastPage());
assertEquals(true, page.isFirstPage());
assertEquals(false, page.isLastPage());
assertEquals(false, page.isHasPreviousPage());
assertEquals(true, page.isHasNextPage());
提示:
(1)只有紧跟在PageHelper.startPage方法后的第一个Mybatis的查询方法会被分页
(2)分页插件不支持带有for update语句的分页
(3)分页插件不支持关联结果查询,可以用其它方式替代
(4)基于Spring boot框架的mybatis应用请关注其它分享
更多内容请关注本站!