框架是一个半成品,解决了软件开发过程中的普遍性问题,简化了开发步骤,提高了开发效率。
ORM全称为Object Relational Mapping,意为对象关系映射,主要实现了将程序中的一个对象与表中的一行数据对应。ORM框架提供了持久化类与表的映射关系,在运行时把对象持久化到数据库中。
存在大量的冗余代码。
手工创建 Connection、Statement 等,效率低下。
手工将结果集封装成实体对象。
查询效率低,没有对数据访问进行优化。
MyBatis 本是 apache 的一个开源项目 iBatis, 2010年这个项目由 apache software foundation 迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。
iBatis 一词来源于 “internet” 和 “abatis” 的组合,是一个基于Java的持久层框架。iBatis 提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAOs)
MyBatis 是一款优秀的持久层框架,它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 POJO(Plain Ordinary Java Objects,普通 Java 对象)为数据库中的记录。
官方网站: https://mybatis.org/mybatis-3/
Maven配置:
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.7version>
dependency>
创建maven工程mybatis01,并引入依赖库
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.7version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.17version>
dependency>
在resources目录下创建 config.xml
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/lesson?serverTimezone=Asia/Shanghai&tinyInt1isBit=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
dataSource>
environment>
environments>
<mappers>
mappers>
configuration>
在使用的数据库中创建数据表 user
DROP TABLE IF EXISTS user;
CREATE TABLE user(
username varchar(50) NOT NULL PRIMARY KEY COMMENT '账号',
password varchar(50) NOT NULL COMMENT '密码',
salt varchar(50) NOT NULL COMMENT '随机盐',
name varchar(20) NOT NULL COMMENT '姓名',
sex tinyint(1) UNSIGNED NOT NULL COMMENT '性别',
address varchar(50) NOT NULL COMMENT '地址'
) ENGINE=InnoDB CHARSET=utf8;
public class User{
private String username;
private String password;
private String salt;
private String name;
private int sex;
private String address;
//省略getter和setter
//构造方法:要么无参,要么全参
}
public interface UserMapper {
User getUserByUsername(String username);
}
在 resources 目录下创建 mapper 目录来存放 Mapper 接口映射文件,方便管理。在 mapper 目录下创建userMapper.xml
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ch.mybatis.mapper.UserMapper">
<select id="getUserByUsername" resultType="com.ch.mybatis.model.User">
SELECT username,password,salt,name,sex,address FROM user WHERE username=#{arg0}
select>
mapper>
<mappers>
<mapper resource="mapper/userMapper.xml"/>
mappers>
public class UserMapperTest{
@Test
public void getUserByUsernameTest() throws IOException{
//创建SqlSessionFactory构建者
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
//读取配置文件信息
InputStream is = Resources.getResourceAsStream("config.xml");
//SqlSessionFactory构建者根据配置文件信息构建SqlSessionFactory
SqlSessionFactory factory = builder.build(is);
//SqlSession工厂开启SqlSession => Sql会话 => Connection上进行信息传输就是会话
SqlSession session = factory.openSession();
//从Sql会话中获取UserMapper接口的代理对象
UserMapper userMapper = session.getMapper(UserMapper.class);
//调用接口方法进行查询
User user = userMapper.getUserByUsername("admin");
System.out.println(user);
}
}
Mybatis支持properties文件的引入,这样做的目的就是为了区分配置:不同的文件中描述不同的配置,这样方便管理。 在 resources 目录下新建 jdbc.properties 文件,然后在 config.xml 中引入
#jdbc.properties
jdbc.driverClassName=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/lesson?characterEncoding=utf8&tinyInt1isBit=false
jdbc.username=root
jdbc.password=root
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties" />
<environments default="dev">
<environment id="dev">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driverClassName}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/userMapper.xml"/>
mappers>
configuration>
在Mapper接口映射文件中,存在如下配置片段:
<select id="getUserByUsername" resultType="com.ch.mybatis.model.User">
...
select>
resultType
属性的配置比较繁琐,当大量使用该属性时,开发效率将变得非常低下。为了提高开发效率,Mybatis提供了为类型定义别名的功能。该功能需要在 config.xml
中进行配置
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="jdbc.properties" />
<typeAliases>
<typeAlias方式和 type="com.ch.mybatis.model.User" alias="user" />
<package name="com.ch.mybatis.model" />
typeAliases>
...
configuration>
配置类型别名后,在接口的映射文件中就可以使用别名了。
<select id="getUserByUsername" resultType="user">
...
select>
Mybatis本身有提供日志功能,开启日志需要在 config.xml
进行配置
...
在Mybatis中,参数取值有两种方式:一种是#{表达式}, 另一种是 **${表达式} ** ;
#{表达式} 采用的是JDBC中的预编译来实现,因此可以防止SQL注入。
**${表达式} ** 采用的是字符串拼接,因此常用在排序字段变化、分组字段变化、查询表名变化等场景。
在Mapper接口中,如果接口方法带有多个参数,如何对这些参数取值呢? Mybatis提供了两种表达式的写法来进行参数取值,一种是通过arg参数下标取该参数的值;一种是通过param参数位置,后面采用JDBC设置参数值的方法,需要注意的是,参数位置是从1开始
当接口方法的参数列表中只有1个参数时,表达式的写法将没有限制,任意内容均可获取到该参数的值
//在UserMapper接口中添加接口方法
List<User> getUsers(String name, int sex);//根据姓名,性别查询用户信息
<select id="getUsers" resultType="user">
SELECT
username,
password,
salt,
name,
sex,
address
FROM
user
WHERE
name LIKE CONCAT('%', #{arg0},'%')
AND
sex = #{arg1}
select>
//编写查询条件类
public class UserCondition{
private String name;
private int sex;
//省略 getter 和 setter 方法
}
//在UserMapper接口中添加接口方法
public List<User> searchUsers(UserCondition condition);//根据姓名,性别查询用户信息
<select id="getUsers" resultType="user">
SELECT
username,
password,
salt,
name,
sex,
address
FROM
user
WHERE
name LIKE CONCAT('%', #{name},'%')
AND
sex = #{sex}
select>
//在UserMapper接口中添加接口方法
List<User> findUsers(String address, UserCondition userCondition);
<select id="findUsers" resultType="user">
SELECT
username,
password,
salt,
name,
sex,
address
FROM
USER
WHERE
address LIKE CONCAT('%', #{arg0}, '%')
AND name LIKE CONCAT('%', #{arg1.name}, '%')
AND sex = #{arg1.sex}
select>
由于Map中存放的数据是通过键值对实现的,因此可以将Map当做一个实体类对象来看待。Map中的键就相当于实体类中的属性名,Map中的值就相当于实体类中的属性值。因此,其取值方式与实体类对象作为参数一样。
//在UserMapper接口中添加接口方法
List<User> queryUsers(Map<String, Object> params);
<select id="findUsers" resultType="user">
SELECT
username,
password,
salt,
name,
sex,
address
FROM
USER
WHERE
address LIKE CONCAT('%', #{address}, '%')
AND name LIKE CONCAT('%', #{name}, '%')
AND sex = #{sex}
select>
为了方便开发,Mybatis对参数提供了注解,从而可以给参数指定名称,方便在对应的Mapper映射文件中使用
//在UserMapper接口中添加接口方法
List<User> retrieveUsers(@Param("condition") Map<String,Object> params);
<select id="findUsers" resultType="user">
SELECT
username,
password,
salt,
name,
sex,
address
FROM
USER
WHERE
address LIKE CONCAT('%', #{condition.address}, '%')
AND name LIKE CONCAT('%', #{condition.name}, '%')
AND sex = #{condition.sex}
select>
<insert id="addUser">
insert>
<update id="updateUser">
update>
<delete id="deleteUser">
delete>
当保存一条数据时,有时我们需要该数据的ID,ID 生成有两种方式:一种是数据库自动生成,另一种是程序通过编码生成。Mybatis 也提供了这两种方式来生成ID,ID生成后可以设置到给定的属性上,这个过程称之为主键回填。
-- 创建表
DROP TABLE IF EXISTS score;
CREATE TABLE score (
-- 主键自增
id bigint(20) NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '主键',
name varchar(20) NOT NULL COMMENT '姓名',
score double(5,2) DEFAULT NULL COMMENT '成绩'
) ENGINE=InnoDB CHARSET=UTF8;
DROP TABLE IF EXISTS article;
CREATE TABLE `article` (
-- 主键需要传值
`id` varchar(50) NOT NULL PRIMARY KEY COMMENT '主键',
`title` varchar(50) NOT NULL COMMENT '标题',
`content` varchar(255) NOT NULL COMMENT '内容',
`author` varchar(20) NOT NULL COMMENT '作者'
) ENGINE=InnoDB CHARSET=UTF8
// 创建实体类 成绩
public class Score {
private long id;
private String name;
private Double score;
//省略getter和setter
//构造方法:要么无参,要么全参
}
// 创建实体类 文章
public class Article {
private String id;
private String title;
private String content;
private String author;
//省略getter和setter
//构造方法:要么无参,要么全参
}
// 创建Mapper接口
public interface ScoreMapper {
int addScore(@Param("score") Score score);
}
// 创建Mapper接口
public interface ArticleMapper {
int addArticle(@Param("article") Article article);
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ch.mybatis.mapper.ScoreMapper">
<insert id="addScore">
<selectKey keyProperty="score.id" resultType="long" order="AFTER">
SELECT LAST_INSERT_ID()
selectKey>
INSERT INTO score(name, score)VALUES(#{score.name}, #{score.score})
insert>
mapper>
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ch.mybatis.mapper.ArticleMapper">
<insert id="addArticle">
<selectKey keyProperty="article.id" resultType="string" order="BEFORE">
SELECT REPLACE(UUID(),'-','')
selectKey>
INSERT INTO article(id, title, content, author)
VALUES (#{article.id}, #{article.title}, #{article.content}, #{article.author})
insert>
mapper>
主键回填的应用场景: 如果一个业务,需要增加一条记录,然后还需要增加的相关的记录,这个相关的记录就需要使用到前一条记录的主键。
在SQL查询时,我们经常会遇到数据库表中设计的字段名与对应的实体类中的属性名不匹配的情况,针对这种情况,Mybatis 提供了结果集映射,供用户自己实现数据库表中字段与实体类中属性进行匹配。
DROP TABLE IF EXISTS employee;
CREATE TABLE employee(
id int NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '员工编号',
name varchar(30) NOT NULL COMMENT '姓名',
entry_time datetime NOT NULL COMMENT '入职时间',
leave_time datetime DEFAULT NULL COMMENT '离职时间'
) ENGINE=InnoDB CHARSET=UTF8;
// 创建实体类 员工
public class Employee {
private long id;
private String name;
private Date entryTime;
private Date leaveTime;
//省略getter和setter
//构造方法:要么无参,要么全参
}
// 创建Mapper接口
public interface EmployeeMapper {
List<Employee> getAllEmployees();
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ch.mybatis.mapper.EmployeeMapper">
<resultMap id="empMap" type="com.ch.mybatis.model.Employee">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="entryTime" column="entry_time" />
<result property="leaveTime" column="leave_time" />
resultMap>
<select id="getAllEmployees" resultMap="empMap">
SELECT id,name,entry_time,leave_time FROM employee
select>
mapper>
DROP TABLE IF EXISTS passenger;
CREATE TABLE passenger (
id bigint NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '乘客编号',
name varchar(50) NOT NULL COMMENT '姓名',
sex tinyint(1) NOT NULL DEFAULT '0' COMMENT '性别',
birthday date NOT NULL COMMENT '生日'
) ENGINE=InnoDB CHARSET=UTF8;
DROP TABLE IF EXISTS passport;
CREATE TABLE passport (
id bigint NOT NULL AUTO_INCREMENT COMMENT '护照编号',
office varchar(50) NOT NULL COMMENT '签证机关',
valid_time tinyint NOT NULL COMMENT '有效期限',
nationality varchar(50) NOT NULL COMMENT '国籍',
passenger_id bigint NOT NULL COMMENT '乘客编号',
PRIMARY KEY (id),
FOREIGN KEY (passenger_id) REFERENCES passenger (id)
) ENGINE=InnoDB CHARSET=UTF8;
public class Passport {
private long id;
private String nationality;
private int validTime;
private String office;
//省略getter和setter
//构造方法:要么无参,要么全参
}
public class Passenger {
private long id;
private String name;
private int sex;
private Date birthday;
private Passport passport; //对象作为属性
//省略getter和setter
//构造方法:要么无参,要么全参
}
public interface PassengerMapper {
List<Passenger> getAllPassengers();
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ch.mybatis.mapper.PassengerMapper">
<resultMap id="passengerMap" type="com.ch.mybatis.model.Passenger">
<id property="id" column="id" />
<result property="name" column="name" />
<result property="sex" column="sex" />
<result property="birthday" column="birthday" />
<association property="passport" javaType="com.ch.mybatis.model.Passport">
<id property="id" column="passportId" />
<result property="nationality" column="nationality" />
<result property="office" column="office" />
<result property="validTime" column="validTime" />
association>
resultMap>
<select id="getAllPassengers" resultMap="passengerMap">
SELECT
a.id,
a.name,
a.sex,
a.birthday,
b.id passportId,
b.nationality,
b.office,
b.valid_time validTime
FROM
passenger a,
passport b
WHERE
a.id = b.passenger_id
select>
mapper>
DROP TABLE IF EXISTS class;
CREATE TABLE class (
id int NOT NULL AUTO_INCREMENT PRIMARY KEY COMMENT '班级编号',
name varchar(50) NOT NULL COMMENT '名称'
) ENGINE=InnoDB CHARSET=UTF8;
DROP TABLE IF EXISTS student;
CREATE TABLE student (
id bigint NOT NULL AUTO_INCREMENT COMMENT '学号',
name varchar(50) NOT NULL COMMENT '姓名',
class_id int NOT NULL COMMENT '班级编号',
PRIMARY KEY (id),
FOREIGN KEY (class_id) REFERENCES class (id)
) ENGINE=InnoDB CHARSET=UTF8;
public class Student {
private long id;
private String name;
}
public class Clazz {
private int id;
private String name;
private List<Student> students; //集合作为属性
}
public interface PassengerMapper {
List<Passenger> getAllPassengers();
}
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.ch.mybatis.mapper.ClassMapper">
<resultMap id="clazzMap" type="com.ch.mybatis.model.Clazz">
<id property="id" column="id" />
<result property="name" column="name" />
<collection property="students" ofType="com.ch.mybatis.model.Student" column="id">
<id property="id" column="sid" />
<result property="name" column="name" />
collection>
resultMap>
<select id="getClazzList" resultMap="clazzMap">
SELECT
a.id,
a.name,
b.id sid,
b.name sname
FROM
class a,
student b
WHERE
a.id = b.class_id
select>
mapper>
为了方便SQL代码的重复利用,Mybatis 提供了 sql 标签为特定的SQL代码进行重用
<sql id="fields">
username, password,salt,sex,address
sql>
<select id="getUserByUsername" resultType="user">
SELECT
<include refid="fields" />
FROM
`user`
WHERE
username = #{abcde}
select>
<select id="searchUsers" resultType="user">
SELECT
<include refid="fields" />
FROM
`user`
WHERE
name LIKE CONCAT('%', #{name}, '%')
AND address LIKE CONCAT('%', #{address}, '%')
select>
<select id="queryUsers" resultType="user">
SELECT
<include refid="fields" />
FROM
`user`
WHERE
name LIKE CONCAT('%', #{c.name}, '%')
AND address LIKE CONCAT('%', #{c.address}, '%')
select>
<select id="findUsers" resultType="user">
SELECT
<include refid="fields" />
FROM
`user`
WHERE
sex = #{arg0}
AND name LIKE CONCAT('%', #{arg1.name}, '%')
AND address LIKE CONCAT('%', #{arg1.address}, '%')
select>
<select id="retrieveUsers" resultType="user">
SELECT
<include refid="fields" />
FROM
`user`
WHERE
sex = #{sex}
AND name LIKE CONCAT('%', #{name}, '%')
AND address LIKE CONCAT('%', #{address}, '%')
select>
在日常开发过程中,我们经常会遇到带条件查询,但用户通常不会将所有的查询条件都填写,只是填写其中部分,每个用户填写的查询条件也不完全相同,那么在编写SQL语句时就难以确定查询条件。为了解决这个问题,Mybatis 提供了 if 标签来进行验证,如果满足,才将标签内的内容拼接至SQL语句中。
//ScoreMapper中新增接口
List<Score> getScores(@Param("params") Map<String,Object> params);
<select id="getScores" resultType="score">
SELECT id,name,score FROM score WHERE 1=1
<if test="params.name != null and params.name != ''">
AND name LIKE CONCAT('%', #{params.name}, '%')
if>
<if test="params.scoreFrom != null and params.scoreFrom != ''">
AND score >= #{params.scoreFrom}
if>
<if test="params.scoreTo != null and params.scoreTo != ''">
if>
select>
在条件查询中,有时存在有效查询条件,有时不存在有效查询条件,那么 SQL 代码中 WHERE 的使用就显得比较繁琐了,为了解决这个问题,Mybatis 提供了 where 标签来解决这个问题。当 where 标签内存在查询条件时, where 标签会在SQL代码中添加 WHERE 关键字; 当 where 标签内不不存在查询条件时, where 标签将忽略 WHERE 关键字的添加。除此之外,where 标签还将自动忽略其后的 AND 或者 OR 关键字。
<select id="getScores" resultType="score">
SELECT id,name,score FROM score
<where>
<if test="params.name != null and params.name != ''">
AND name LIKE CONCAT('%', #{params.name}, '%')
if>
<if test="params.scoreFrom != null and params.scoreFrom != ''">
AND score >= #{params.scoreFrom}
if>
<if test="params.scoreTo != null and params.scoreTo != ''">
if>
where>
select>
在日常开发过程中经常会遇到动态更新的情况,面对这个场景,Mybatis 提供了 set 标签来解决此类问题。
set 标签还具有忽略最后一个SQL子句的后缀,比如逗号。
//ScoreMapper中新增接口
int updateScore(@Param("s") Score score);
<update id="updateScore">
UPDATE score
<set>
<if test="s.name != null and s.name != ''">
name = #{s.name},
if>
<if test="s.score != null and s.score != ''">
score = #{s.score},
if>
set>
<where>
<if test="s.id != null and s.id != ''">
AND id = #{s.id}
if>
where>
update>
Mybatis 提供了 trim 标签来代替 where 标签和 set 标签。其语法如下:
<trim prefix="" prefixOverrides="" suffix="" suffixOverrides="">trim>
<select id="getScores" resultType="score">
SELECT id,name,score FROM score
<trim prefix="WHERE" prefixOverrides="AND">
<if test="params.name != null and params.name != ''">
AND name LIKE CONCAT('%', #{params.name}, '%')
if>
<if test="params.scoreFrom != null and params.scoreFrom != ''">
AND score >= #{params.scoreFrom}
if>
<if test="params.scoreTo != null and params.scoreTo != ''">
if>
trim>
select>
<update id="updateScore">
UPDATE score
<trim suffixOverrides="," suffix="">
<if test="s.name != null and s.name != ''">
name = #{s.name},
if>
<if test="s.score != null and s.score != ''">
score = #{s.score},
if>
trim>
<where>
<if test="s.id != null and s.id != ''">
AND id = #{s.id}
if>
where>
update>
在查询条件中,有时我们会传递一个数组或者一个集合作为查询的条件,此时,需要遍历这个集合才能完成 SQL 语句的组装,为了解决这个问题,Mybatis 提供了 foreach 标签来进行遍历。其语法规则如下:
<foreach collection="" item="" open="" seperator="" close="" index="">
foreach>
//ScoreMapper中新增接口
int deleteScore(@Param("ids")int[] scoreIds);
<delete id="deleteScore">
DELETE FROM score WHERE id IN
<foreach collection="ids" item="id" open="(" separator="," close=")">
#{id}
foreach>
delete>
缓存就是存储在内存中的临时数据,将用户经常查询的数据放在缓存(内存)中,用户再次查询数据的时候就不用从磁盘上(关系型数据库数据文件)查询,从缓存中查询,能够提高查询效率,解决了高并发系统的性能问题
减少和数据库的交互次数,减少系统开销,提高系统效率
经常查询并且不经常改变的数据
mybatis包含一个非常强大的查询缓存特性,可以非常方便地定制和配置缓存,缓存可以极大地提高查询效率
mybatis系统默认定义了两级缓存:一级缓存和二级缓存
一级缓存:
默认情况下只有一级缓存开启(SqlSession级别的缓存,也称为本地缓存),同一个 SqlSession 执行多次同构查询时,结果将放入一级缓存。
二级缓存:
需要手动开启和配置,它是基于SqlSessionFactory级别的缓存,同一个 SqlSessionFactory 构建的 SqlSession 发起的多次同构查询,如果SqlSession关闭,则会将数据保存在二级缓存中
<settings>
<setting name="cacheEnabled" value="true"/>
settings>
<cache flushInterval="300000" readOnly="true" size="10000" eviction="LRU"/>
二级缓存缓存数据的前提是查询的 SqlSession 关闭,如果 SqlSession 没有关闭,那么数据将不会进入二级缓存,再次进行同构查询时,二级缓存由于没有数据,查询将进入数据库,造成二级缓存失效的现象。另一种情况是,当前查询的 SqlSession 已经关闭,数据也进入了二级缓存,但在下一次查询之前,如果中间发生了更新操作,该操作更新的数据在的二级缓存中存在,那么二级缓存也将失效。
官方网站: https://pagehelper.github.io/
最新版本Maven配置:
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.3.0version>
dependency>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">plugin>
plugins>
@Test
public void paginationTest(){
SqlSession sqlSession = MybatisUtil.openSession();
//从Sql会话中获取Mapper接口的代理实例
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
Map<String,Object> params = new HashMap<>();
params.put("sex", 1);
params.put("name", "理");
params.put("address", "千");
//设置分页
PageHelper.startPage(1, 5);
List<User> users = userMapper.retrieveUsers(params);
PageInfo<User> pageInfo = new PageInfo<>(users);//将分页查询的结果集保存在PageInfo对象中
System.out.println("总条数:" + pageInfo.getTotal());
System.out.println("总页数:" + pageInfo.getPages());
//当前页数据展示
pageInfo.getList().forEach(System.out::println);
}
Druid 是阿里巴巴开源平台上的一个项目,是性能最好的数据库连接池,如何在Mybatis中配置该数据源呢?
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.8version>
dependency>
创建 DruidDataSourceFactory, 并继承 PooledDataSourceFactory,并替换数据源
public class DruidDataSourceFactory extends PooledDataSourceFactory {
public DruidDataSourceFactory() {
this.dataSource = new DruidDataSource();//替换数据源
}
}
<dataSource type="com.ch.mybatis.datasource.DruidDataSourceFactory">
...
dataSource>