什么是MyBatis?
- MyBatis是一个半ORM框架,内部封装了JDBC,开发时只需要关注SQL语句本身。不需要花费精力取加载驱动,创建连接,创建Statement的复杂的过程。
- MyBatis可以通过XML或注解的方式来配置和映射原生信息,将POJO映射成数据库中的记录,几乎避免了所有的JDBC代码和手动设置参数,以及获取结果集。
- MyBatis可以通过XML或注解的方式来配置和映射原生信息。通过Java对象和Statement中的SQL语句的动态参数进行映射,生成最终要执行的SQL语句。最后由MyBatis框架执行SQL语句,并将结果映射为Java对象返回。
MyBatis的优点和缺点
优点
- MyBatis基于SQL语句编程,相当灵活;不会对应用程序或数据库现有的设计造成任何影响;SQL写在XML文件中,解除程序于代码的耦合,方便统一管理;提供XML标签,支持编写动态SQL语句,并可以重用。
- MyBatis于JDBC相比,减少了50%以上的代码量,消除了大量重复代码。
- MyBatis能够很好的于各种数据库相兼容。
- MyBatis能够于Spring框架很好的集成。
- MyBatis提供映射标签,支持对象与数据库字段的ORM映射;提供对象关系映射标签,支持对象关系组件维护。
缺点
- SQL语句的编写工作量大
- SQL语句依赖于数据库,导致数据库移植性差,不能随便更换数据库
MyBatis整体架构和运行流程
MyBatis的整体构造由数据源配置文件、SQL映射文件、会话工厂、会话、执行器和底层封装对象组成。
1、数据源配置文件
通过配置的方式将数据库的配置信息从应用程序中独立出来,由独立的模块管理和配置。Mybatis的数据源配置文件包含数据库驱动、数据库连接地址、用户名密码、事务管理等,还可以配置连接池的连接数、空闲时间等。
mapper-config.xml配置文件基本配置信息如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value=""/>
<property name="url" value=""/>
<property name="username" value=""/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
mapper文件映射
mapper标签中的resource属性其参数是mapper文件的相对路径
使用相对路径引用mapper文件每次只能引用一个mapper文件;如果需要引用多个mapper文件,那么每个文件都要使用mapper标签中的resource属性引用mapper文件,不推荐使用此方式
<!--
方式一:使用相对类路径引用mapper配置文件
-->
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
mapper标签中的class属性为mapper文件的完整限定名
使用该方式时MyBatis会class属性用对象的mapper文件接口,然后还会去加载该接口同目录下的同名的mapper.xml文件
<!--
方式二:使用映射器接口,实现类的完全限定名
-->
<mappers>
<mapper class="org.mybatis.example.BlogMapper"/>
</mappers>
package标签批量注册mapper接口,根据name属性中的参数路径,将指定文件下的mapper.xml文件全部注册为映射器。
注意:
- 包名和接口所在包,名称要一致
- mapper.xml文件的名称要和接口名称一致
- 在”resource“下创建包使用”/“分割
<!--
方式三:将包内的映射器接口实现全部注册为映射器
-->
<mappers>
<package name="org.mybatis.example"/>
</mappers>
2、SQL映射文件
Mybatis中所有数据库的操作都会基于该映射文件和配置的sql语句,在这个配置文件中可以配置任何类型的sql语句。框架会根据配置文件中的参数配置,完成对sql语句以及输入输出参数的映射配置。
Mapper.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="命名空间">
<select id="方法名" resultMap="返回值类型" parameterType="参数类型">
-- sql语句
</select>
</mapper>
3.会话工厂与会话
Mybatis中会话工厂SqlSessionFactory类可以通过加载资源文件,读取数据源配置MapConfig.xml信息,从而产生一种可以与数据库交互的会话实例SqlSession,会话实例SqlSession根据Mapper.xml文件中配置的sql,对数据库进行操作。
4.运行流程
会话工厂SqlSessionFactory通过加载资源文件获取MapConfig.xml配置文件信息,然后生成可以与数据库交互的会话实例SqlSession。会话实例可以根据Mapper配置文件中的Sql配置去执行相应的增删改查操作。
MyBatis实现增删改查
增删改查前的准备
1、添加依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>cn.wzw.my</groupId>
<artifactId>MyBatisDemo03</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<maven.compiler.source>14</maven.compiler.source>
<maven.compiler.target>14</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- 代码测试依赖-->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<!-- 通过注解消除实际开发中的样板式代码-->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.26</version>
</dependency>
<!-- 日志依赖-->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- mybatis依赖-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.9</version>
</dependency>
<!-- 数据库依赖-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.49</version>
</dependency>
</dependencies>
</project>
2、配置mapper-config.xml文件
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入数据库配置文件-->
<properties resource="config/jdbc.properties"></properties>
<settings>
<!-- 开启驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启日志-->
<setting name="logImpl" value="log4j"/>
</settings>
<!-- 设置别名-->
<typeAliases>
<package name="cn.wzw.my.entity"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事务管理-->
<transactionManager type="JDBC"/>
<!-- 配置数据源-->
<dataSource type="POOLED">
<!-- 使用配置文件中的键,设置数据库驱动、链接地址、用户名、密码-->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- mapper接口映射-->
<mappers>
<package name="cn.wzw.my.mapper"/>
</mappers>
</configuration>
3、配置log4j.properties文件,放置在resources目录下
log4j.rootLogger=DEBUG,Console
#Console
log4j.appender.Console=org.apache.log4j.ConsoleAppender
log4j.appender.console.Target=System.out
log4j.appender.Console.layout=org.apache.log4j.PatternLayout
log4j.appender.Console.layout.ConversionPattern=%d [%t] %-5p [%c] - %m%n
log4j.logger.org.apache=ERROR
log4j.logger.org.mybatis=ERROR
log4j.logger.org.springframework=ERROR
#这个需要
log4j.logger.log4jdbc.debug=ERROR
log4j.logger.com.gk.mapper=ERROR
log4j.logger.jdbc.audit=ERROR
log4j.logger.jdbc.resultset=ERROR
#这个打印SQL语句非常重要
log4j.logger.jdbc.sqlonly=DEBUG
log4j.logger.jdbc.sqltiming=ERROR
log4j.logger.jdbc.connection=FATAL
实现增删改查
user表
CREATE TABLE `user` ( `uid` int(3) NOT NULL AUTO_INCREMENT COMMENT '编号', `user` varchar(20) NOT NULL COMMENT '用户名', `password` varchar(20) NOT NULL COMMENT '密码', `start` varchar(10) NOT NULL COMMENT '状态', PRIMARY KEY (`uid`) ) |
package cn.wzw.my.entity;
import lombok.Data;
@Data
public class User {
private long uid;
private String user;
private String password;
private String start;
}
1、UserMapper接口
package cn.wzw.my.mapper;
import cn.wzw.my.entity.User;
import java.util.List;
public interface UserMapper {
/**
* 第一部分:实现增删改查
*/
// 增加
Integer insertUser(User user);
// 修改
Integer updateUser(User user);
// 删除
Integer deleteUser(Integer id);
// 查询单条记录
User selectUserById(Integer id);
// 查询所有记录
List<User> selectUserAll();
}
2、UserMapper.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="cn.wzw.my.mapper.UserMapper">
<!--
第一部分:实现增删改查
-->
<!-- 增加-->
<insert id="insertUser">
insert into `user` (`user`,`password`,`start`) values (#{user},#{password},#{start})
</insert>
<!-- 修改-->
<update id="updateUser">
update `user` set `user`=#{user} ,`password`=#{password} ,`start`=#{start} where `uid`=#{uid}
</update>
<!-- 删除-->
<delete id="deleteUser">
delete from `user` where `uid`=#{uid}
</delete>
<!-- 查询单条记录-->
<select id="selectUserById" resultType="user">
select * from `user` where `uid`=#{uid}
</select>
<!-- 查询所有记录-->
<select id="selectUserAll" resultType="user">
select * from `user`
</select>
</mapper>
3、UserMapperTest测试类
package cn.wzw.my.mapper;
import cn.wzw.my.entity.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import static org.junit.Assert.*;
public class UserMapperTest {
SqlSessionFactory sqlSessionFactory = null;
@Before
public void init(){
try {
// Mybatis中会话工厂SqlSessionFactory类可以通过加载资源文件,读取数据源配置MapConfig.xml信息
InputStream resource = Resources.getResourceAsStream("config/mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 第一部分:实现增删改查
*/
// 增加
@Test
public void insertUser() {
// 会话实例SqlSession根据Mapper.xml文件中配置的sql,对数据库进行操作。
SqlSession sqlSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setUser("lisi");
user.setPassword("123456");
user.setStart("1");
// 通过SqlSession实例对象去操作数据库,方法中的参数需要指定接口中对应的方法路径
int result = sqlSession.insert("cn.wzw.my.mapper.UserMapper.insertUser", user);
System.out.println(result!=0?"数据添加成功":"数据添加失败");
}
// 修改
@Test
public void updateUser() {
// 获取会话实例SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setUid(1011);
user.setUser("李四");
user.setPassword("1008611");
user.setStart("0");
// 通过SqlSession实例对象去操作数据库,方法中的参数需要指定接口中对应的方法路径
int result = sqlSession.update("cn.wzw.my.mapper.UserMapper.updateUser", user);
System.out.println(result!=0?"修改成功":"修改失败");
}
// 删除
@Test
public void deleteUser() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过SqlSession实例对象去操作数据库,方法中的参数需要指定接口中对应的方法路径
int result = sqlSession.update("cn.wzw.my.mapper.UserMapper.deleteUser", 1011);
System.out.println(result!=0?"删除成功":"删除失败");
}
// 查询单条记录
@Test
public void selectUserById() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过SqlSession实例对象去操作数据库,方法中的参数需要指定接口中对应的方法路径
User user = sqlSession.selectOne("cn.wzw.my.mapper.UserMapper.selectUserById", 1010);
System.out.println("user = " + user);
}
// 查询所有记录
@Test
public void selectUserAll() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过SqlSession实例对象去操作数据库,方法中的参数需要指定接口中对应的方法路径
List<User> users = sqlSession.selectList("cn.wzw.my.mapper.UserMapper.selectUserAll");
for (User user:users){
System.out.println("user = " + user);
}
}
SQL语句中的#{}和${}的区别
#{}:#{}是编译预处理,MyBatis在执行SQL语句时,会将SQL语句中的#{}替换为?,然后再调用PreparedStatement中的set方法进行赋值。可以有效的方式SQL语句注入,提高安全性。
${}:${}是字符串替换,MyBatis在执行SQL语句时,会将SQL语句中的${}替换为变量的值
MyBatis获取参数的方式
- 接口中有单个参数
- 接口中有多个零散参数;MyBatis在处理多个参数是,会将多个参数保存到map集合中,会以arg0,arg1,或者param1,param2为键,以参数的位置进行存储。
- 将多个参数封装成实体类对象作为接口参数
- 将多个参数保存到Map集合中作为接口参数
1、UserMapper接口
/**
* 第二部分:MyBatis参数的获取方式
* 1、接口中有单个参数
* 2、接口中有多个零散参数
* 3、将多个参数封装成实体类对象作为接口参数
* 4、将多个参数保存到Map集合中作为接口参数
*/
// 1、接口中有单个参数
User selectOne(Integer id);
// 2、接口中有多个零散参数
// 方式一
User userAndStart1(@Param("user") String user, @Param("start") String start);
// 方式二
User userAndStart2(String user ,String start);
// 3、将多个参数封装成实体类对象最为接口参数
User selectUser(User user);
// 4、将多个参数保存到Map集合中作为接口参数
User selectMap(Map map);
2、UserMapper.xml文件
<!--
/**
* 第二部分:MyBatis参数的获取方式
* 1、接口中有单个参数
* 2、接口中有多个零散参数
* 3、将多个参数封装成实体类对象作为接口参数
* 4、将多个参数保存到Map集合中作为接口参数
*/
-->
<!-- 1、接口中有单个参数-->
<select id="selectOne" resultType="user">
select * from `user` where `uid`=#{uid}
</select>
<!-- 2、接口中有多个零散参数 方式一-->
<select id="userAndStart1" resultType="user">
select * from `user` where `user`=#{user} and `start`=#{start}
</select>
<!-- 2、接口中有多个零散参数 方式二-->
<select id="userAndStart2" resultType="user">
select * from `user` where `user`=#{param1} and `start`=#{param2}
</select>
<!-- 3、将多个参数封装成实体类对象最为接口参数-->
<select id="selectUser" resultType="user">
select * from `user` where `user`=#{user} and `start`=#{start}
</select>
<!-- 4、将多个参数保存到Map集合中作为接口参数-->
<select id="selectMap" resultType="user">
select * from `user` where `user`=#{user} and `start`=#{start}
</select>
3、UserMapperTest测试类
/**
* 第二部分:MyBatis参数的获取方式
* 1、接口中有单个参数
* 2、接口中有多个零散参数
* 3、将多个参数封装成实体类对象作为接口参数
* 4、将多个参数保存到Map集合中作为接口参数
*/
// 1、接口中有单个参数
@Test
public void selectOne() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过SqlSession实例指定Mapper接口,获取相对应的Mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// mapper对象调用指定的方法来进行数据库操作
User user = mapper.selectOne(1010);
System.out.println("user = " + user);
}
// 2、接口中有多个零散参数 方式一
@Test
public void userAndStart1() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过SqlSession实例指定Mapper接口,获取相对应的Mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// mapper对象调用指定的方法来进行数据库操作
User user = mapper.userAndStart1("jerry", "1");
System.out.println("user = " + user);
}
// 2、接口中有多个零散参数 方式二
@Test
public void userAndStart2() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过SqlSession实例指定Mapper接口,获取相对应的Mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// mapper对象调用指定的方法来进行数据库操作
User user = mapper.userAndStart2("jerry", "1");
System.out.println("user = " + user);
}
// 3、将多个参数封装成实体类对象最为接口参数
@Test
public void selectUser() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过SqlSession实例指定Mapper接口,获取相对应的Mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUser("jerry");
user.setStart("1");
// mapper对象调用指定的方法来进行数据库操作
User user1 = mapper.selectUser(user);
System.out.println("user1 = " + user1);
}
// 4、将多个参数保存到Map集合中作为接口参数
@Test
public void selectMap() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
// 通过SqlSession实例指定Mapper接口,获取相对应的Mapper对象
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Map<String, String> map = new HashMap<>();
map.put("user","jerry");
map.put("start","1");
// mapper对象调用指定的方法来进行数据库操作
User user = mapper.selectMap(map);
System.out.println("user = " + user);
}
Mpper自定义映射
MyBatis优点体现:
MyBatis提供映射标签,支持对象与数据库字段的ORM映射;提供对象关系映射标签,支持对象关系组件维护。
自定义映射用于数据库字段和实体类属性名不一致的情况,那么遇到该情况如何解决?
1、使用SQL语句的别名功能,在查询的SQL语句中定义字段的别名,将数据库字段的别名定义为实体类的属性名。
2、通过MyBatis的映射标签,将数据库的字段名和实体类的属性名 一 一对应
1、创建表
emp员工表
Create Table |
CREATE TABLE `emp` ( `eid` int(11) NOT NULL AUTO_INCREMENT COMMENT '员工编号', `ename` varchar(20) NOT NULL COMMENT '员工姓名', `age` varchar(10) NOT NULL COMMENT '员工年龄', `deptno` varchar(10) NOT NULL COMMENT '部门编号', PRIMARY KEY (`eid`) ) ; |
package cn.wzw.my.entity;
import lombok.Data;
@Data
public class Emp {
private long eid;
private String ename;
private String age;
private String deptno;
// 额外添加的部门属性,用于存储员工对应的部门信息
private Dept dept;
}
dept部门表
Create Table |
CREATE TABLE `dept` ( `did` int(11) NOT NULL AUTO_INCREMENT COMMENT '部门编号', `deptName` varchar(20) NOT NULL COMMENT '部门名称', `local` varchar(50) NOT NULL COMMENT '部门地区', PRIMARY KEY (`did`) ); |
package cn.wzw.my.entity;
import lombok.Data;
@Data
public class Dept {
private long did;
private String deptName;
private String local;
// 额外添加的员工属性,用于存储对应部门中的所有员工信息
private List<Emp> emps;
}
2、MyBatis对象之间的关联关系
一对一的关联关系
emp员工表:一个员工只有一个部门;查询出所有员工对应的部门信息
1、EmpMapper接口
package cn.wzw.my.mapper;
import cn.wzw.my.entity.Emp;
import java.util.List;
public interface EmpMapper {
// 查询出所有员工对应的部门信息
List<Emp> selectAll01();
List<Emp> selectAll02();
List<Emp> selectAll03();
}
2、EmpMapper.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="cn.wzw.my.mapper.EmpMapper">
<!-- emp员工表:一个员工只有一个部门;关系为一对一查询-->
<!-- 数据库字段和实体类对象属性的ORM关系映射-->
<resultMap id="empMap1" type="emp">
<id property="eid" column="eid"></id>
<result property="ename" column="ename"></result>
<result property="age" column="age"></result>
<result property="deptno" column="deptno"></result>
<association property="dept" javaType="dept">
<id property="did" column="did"></id>
<result property="deptName" column="deptName"></result>
<result property="local" column="local"></result>
</association>
</resultMap>
<select id="selectAll01" resultMap="empMap1">
select a.*,b.* from `emp` a left outer join `dept` b on(a.`deptno`=b.`did`)
</select>
<!-- autoMapping:设置数据库字段与实体类属性的自动映射-->
<resultMap id="empMap2" type="emp" autoMapping="true">
<association property="dept" javaType="dept">
<id property="did" column="did"></id>
<result property="deptName" column="deptName"></result>
<result property="local" column="local"></result>
</association>
</resultMap>
<select id="selectAll02" resultMap="empMap2">
select a.*,b.* from `emp` a left outer join `dept` b on(a.`deptno`=b.`did`)
</select>
<!-- 分步查询:先查询emp员工表中的数据,然后根据emp表中结果的deptno部门编号去dept部门表中查询数据-->
<resultMap id="empMap3" type="emp" autoMapping="true">
<!-- -->
<association property="dept" javaType="dept" column="deptno" select="deptAll" fetchType="lazy">
<id property="did" column="did"></id>
<result property="deptName" column="deptName"></result>
<result property="local" column="local"></result>
</association>
</resultMap>
<select id="selectAll03" resultMap="empMap3">
select * from `emp`
</select>
<select id="deptAll" resultType="dept">
select * from `dept` where `did`=#{deptno}
</select>
</mapper>
3、EmpMapperTest测试类
package cn.wzw.my.mapper;
import cn.wzw.my.entity.Emp;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import static org.junit.Assert.*;
public class EmpMapperTest {
SqlSessionFactory sqlSessionFactory = null;
@Before
public void init(){
try {
InputStream resource = Resources.getResourceAsStream("config/mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
public void selectAll01() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> emps = mapper.selectAll01();
for (Emp emp:emps){
System.out.println("emp = " + emp);
}
}
@Test
public void selectAll02() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> emps = mapper.selectAll02();
Iterator<Emp> iterator = emps.iterator();
while (iterator.hasNext()){
Emp emp = iterator.next();
System.out.println("emp = " + emp);
}
}
@Test
public void selectAll03() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> emps = mapper.selectAll03();
Iterator<Emp> iterator = emps.iterator();
while (iterator.hasNext()){
Emp emp = iterator.next();
System.out.println("emp = " + emp);
}
}
}
一对多的关联关系
dept部门表:一个部门有多个员工;查询部门中所有员工信息
1、DeptMapper接口
package cn.wzw.my.mapper;
import cn.wzw.my.entity.Dept;
import java.util.List;
public interface DeptMapper {
// 查询部门中的所有员工信息
List<Dept> selectAll01();
List<Dept> selectAll02();
List<Dept> selectAll03();
}
2、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="cn.wzw.my.mapper.DeptMapper">
<!-- 使用MyBatis的映射将数据库字段和实体类属性一一对应-->
<resultMap id="deptMap1" type="dept">
<id property="did" column="did"></id>
<result property="deptName" column="deptName"></result>
<result property="local" column="local"></result>
<collection property="emps" ofType="emp">
<id property="eid" column="eid"></id>
<result property="ename" column="ename"></result>
<result property="age" column="age"></result>
<result property="deptno" column="deptno"></result>
</collection>
</resultMap>
<select id="selectAll01" resultMap="deptMap1">
select a.*,b.* from `dept` a left join `emp` b on(a.`did`=b.`deptno`)
</select>
<!-- autoMapping:开启自动映射-->
<resultMap id="deptMap2" type="dept" autoMapping="true">
<collection property="emps" ofType="emp">
<id property="eid" column="eid"></id>
<result property="ename" column="ename"></result>
<result property="age" column="age"></result>
<result property="deptno" column="deptno"></result>
</collection>
</resultMap>
<select id="selectAll02" resultMap="deptMap2">
select a.*,b.* from `dept` a left join `emp` b on(a.`did`=b.`deptno`)
</select>
<!-- 分步查询:先查询dept部门表,根据部门表中结果的did部门编号去另外一张emp员工表中查询数据-->
<resultMap id="deptMap3" type="dept" autoMapping="true">
<collection property="emps" ofType="emp" column="did" select="selectDept" fetchType="lazy">
<id property="eid" column="eid"></id>
<result property="ename" column="ename"></result>
<result property="age" column="age"></result>
<result property="deptno" column="deptno"></result>
</collection>
</resultMap>
<select id="selectAll03" resultMap="deptMap3">
select * from `dept`
</select>
<select id="selectDept" resultType="dept">
select * from `emp` where `deptno`=#{did}
</select>
</mapper>
3、DeptMapperTest测试类
package cn.wzw.my.mapper;
import cn.wzw.my.entity.Dept;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Iterator;
import java.util.List;
import static org.junit.Assert.*;
public class DeptMapperTest {
SqlSessionFactory sqlSessionFactory = null;
@Before
public void init(){
try {
InputStream resource = Resources.getResourceAsStream("config/mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(resource);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Test
public void selectAll01() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> depts = mapper.selectAll01();
// 使用迭代器遍历集合
Iterator<Dept> iterator = depts.iterator();
while (iterator.hasNext()){
Dept dept = iterator.next();
System.out.println("dept = " + dept);
}
}
@Test
public void selectAll02() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> depts = mapper.selectAll02();
Iterator<Dept> iterator = depts.iterator();
while (iterator.hasNext()){
Dept dept = iterator.next();
System.out.println("dept = " + dept);
}
}
@Test
public void selectAll03() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
List<Dept> depts = mapper.selectAll03();
Iterator<Dept> iterator = depts.iterator();
while (iterator.hasNext()){
Dept dept = iterator.next();
System.out.println("dept = " + dept);
}
}
}
MyBatis动态SQL
MyBatis的优点体现:
MyBatis基于SQL语句编程,相当灵活;不会对应用程序或数据库现有的设计造成任何影响;SQL写在XML文件中,解除程序于代码的耦合,方便统一管理;提供XML标签,支持编写动态SQL语句,并可以重用。
动态查询SQL
1、UserMapper接口
/**
* 第四部分:动态SQL
* 动态查询
* 动态修改
* 动态删除
*/
/**
* 动态SQL:
* 1、<where> + <if>
* 2、<trim> + <if>
* 3、<where> + <choose> + <when> + <otherwise>
*/
// 1、<where> + <if>
List<User> userAndStart01(User user);
// 2、<trim> + <if>
List<User> userAndStart02(User user);
// 3、<where> + <choose> + <when> + <otherwise>
List<User> userAndStart03(User user);
2、UserMapper.xml文件
<!--
/**
* 第四部分:动态SQL
* 动态查询
* 动态修改
* 动态删除
*/
/**
* 动态SQL:
* 1、<where> + <if>
* 2、<trim> + <if>
* 3、<where> + <choose> + <when> + <otherwise>
*/
-->
<!--
1、<where> + <if>
<if>:用于判断传入的值是否符合条件。符合条件时执行<if>中的内容,否则不执行
<where>:where标签会知道如果它包含的标签中有返回值的话,它就插入一个where。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉
-->
<select id="userAndStart01" resultType="user">
select * from `user`
<where>
<if test="user!=null">
`user`=#{user}
</if>
<if test="start!=null">
and `start`=#{start}
</if>
</where>
</select>
<!--
2、<trim> + <if>
<trim>属性有如下:
prefix:添加前缀
prefixOverrides:去除前缀
suffix:添加后缀
suffixOverrides:去除后缀
<trim>:添加前缀where,当第一个if不执行时,在执行第二个<if>时去除前缀and,保证SQL正常查询
<if>:用于判断传入的值是否符合条件。符合条件时执行<if>中的内容,否则不执行
-->
<select id="userAndStart02" resultType="user">
select * from `user`
<trim prefix="where" prefixOverrides="and">
<if test="user!=null">
`user`=#{user}
</if>
<if test="start!=null">
and `start`=#{start}
</if>
</trim>
</select>
<!--
3、<where> + <choose> + <when> + <otherwise>
<where>:where标签会知道如果它包含的标签中有返回值的话,它就插入一个where。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉
<choose> + <when> + <otherwise>:<choose>中的内容从上到下执行,
如果第一个<when>满足条件,则只执行当前<when>中的内容,不在往下执行;
如果第一个<when>不满足条件,则执行下一个<when>中的内容,不在往下执行;
如果第一个<when>都不满足条件,则<otherwise>中的内容;
-->
<select id="userAndStart03" resultType="user">
select * from `user`
<where>
<choose>
<when test="user!=null">
`user`=#{user}
</when>
<when test="start!=null">
`start`=#{start}
</when>
<otherwise></otherwise>
</choose>
</where>
</select>
3、UserMapperTest测试类
/**
* 第四部分:动态SQL
* 动态查询
* 动态修改
* 动态删除
*/
/**
* 动态SQL:
* 1、<where> + <if>
* 2、<trim> + <if>
* 3、<where> + <choose> + <when> + <otherwise>
*/
// 1、<where> + <if>
@Test
public void userAndStart01() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUser("tom");
user.setStart("0");
List<User> users = mapper.userAndStart01(user);
Iterator<User> iterator = users.iterator();
while (iterator.hasNext()){
User user1 = iterator.next();
System.out.println("user1 = " + user1);
}
}
// 2、<trim> + <if>
@Test
public void userAndStart02() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUser("tom");
user.setStart("0");
List<User> users = mapper.userAndStart02(user);
Iterator<User> iterator = users.iterator();
while (iterator.hasNext()){
User next = iterator.next();
System.out.println("next = " + next);
}
}
// 3、<where> + <choose> + <when> + <otherwise>
@Test
public void userAndStart03() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUser("tom");
user.setStart("0");
List<User> users = mapper.userAndStart03(user);
Iterator<User> iterator = users.iterator();
while (iterator.hasNext()){
User next = iterator.next();
System.out.println("next = " + next);
}
}
动态修改SQL
1、UserMapper接口
/**
* 动态修改SQL:
* 1、<set> + <if>
* 2、<trim> + <if>
*/
// 1、<set> + <if>
Integer updateUser01(User user);
// 2、<trim> + <i
Integer updateUser02(User user);
2、UserMapper.xml文件
<!--
/**
* 动态修改SQL:
* 1、<set> + <if>
* 2、<trim> + <if>
*/
-->
<!--
1、<set> + <if>
<set>:<set>标签会知道如果它包含的标签中有返回值的话,它就插入一个<set>。此外,如果标签返回的内容是以','开头的,则它会剔除掉
<if>:用于判断传入的值是否符合条件。符合条件时执行<if>中的内容,否则不执行
-->
<update id="updateUser01">
update `user`
<set>
<if test="user!=null">
`user`=#{user}
</if>
<if test="password!=null">
,`password`=#{password}
</if>
<if test="start!=null">
, `start`=#{start}
</if>
</set>
where `uid`=#{uid}
</update>
<!--
2、<trim> + <if>
<trim>:在执行SQL语句时prefix属性添加前缀<set>,如果标签返回的内容是以','开头的,<trim>会通过prefixOverrides属性去除前缀","
<if>:用于判断传入的值是否符合条件。符合条件时执行<if>中的内容,否则不执行
-->
<update id="updateUser02">
update `user`
<trim prefix="set" prefixOverrides=",">
<if test="user!=null">
`user`=#{user}
</if>
<if test="password!=null">
,`password`=#{password}
</if>
<if test="start!=null">
, `start`=#{start}
</if>
</trim>
where `uid`=#{uid}
</update>
3、UserMapperTest测试类
/**
* 动态修改SQL:
* 1、<set> + <if>
* 2、<trim> + <if>
*/
@Test
public void updateUser01() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUid(1010);
// user.setUser("jerry");
user.setPassword("1008611");
// user.setStart("0");
Integer result = mapper.updateUser01(user);
System.out.println(result!=0?"修改成功":"修改失败");
}
@Test
public void updateUser02() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUid(1010);
// user.setUser("jerry");
user.setPassword("123456");
user.setStart("1");
Integer result = mapper.updateUser02(user);
System.out.println(result!=0?"修改成功":"修改失败");
}
动态删除SQL
1、UserMappe接口
/**
* 动态删除
* 1、where + foreach
* 2、trim + foreach
*/
// 1、where + foreach
Integer deleteUser01(List list);
// 2、trim + foreach
Integer deleteUser02(List list);
2、UserMapper.xml文件
<!--
/**
* 动态删除
* 1、where + foreach
* 2、trim + foreach
*/
-->
<!--
1、where + foreach
-->
<delete id="deleteUser01">
delete from `user`
<where>
<!--
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
删除形式:delete from `user` where `uid`=1 or `uid`=2 or `uid`=3
-->
<foreach collection="list" item="uid" separator="or">
`uid`=#{uid}
</foreach>
</where>
</delete>
<!--
2、trim + foreach
-->
<delete id="deleteUser02">
delete from `user`
<where>
<!--
collection:指定输入对象中的集合属性
item:每次遍历生成的对象
open:开始遍历时的拼接字符串
close:结束时拼接的字符串
separator:遍历对象之间需要拼接的字符串
删除形式:delete from `user` where `uid` in(id=1 or id=2 or id=3)
-->
<foreach collection="list" item="uid" open="`uid` in(" separator="," close=")">
#{uid}
</foreach>
</where>
</delete>
3、UserMapperTest测试类
/**
* 动态删除
* 1、where + foreach
* 2、trim + foreach
*/
// 1、where + foreach
// 删除形式:delete from `user` where `uid`=1 or `uid`=2 or `uid`=3
@Test
public void deleteUser01() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Integer result = mapper.deleteUser01(Arrays.asList(1009, 1010));
System.out.println(result!=0?"删除成功":"删除失败");
}
// 2、trim + foreach
// 删除形式:delete from `user` where `uid` in(id=1 or id=2 or id=3)
@Test
public void deleteUser02() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Integer result = mapper.deleteUser02(Arrays.asList(1009, 1010));
System.out.println(result!=0?"删除成功":"删除失败");
}
MyBatis注解开发
MyBatis可以通过XML或注解的方式来配置和映射原生信息,将POJO映射成数据库中的记录,几乎避免了所有的JDBC代码和手动设置参数,以及获取结果集。
MyBatis的注解开发可直接在接口中指定的接口方法上通过注解的方式书写SQL语句,避免在xml配置文件中书写SQL语句。
1、UserMapper接口
/**
* 第五部分:使用注解开发实现增删改查操作
*/
// 增加
@Insert("insert into `user` (`user`,`password`,`start`) values (#{user},#{password},#{start})")
Integer userInsert(User user);
// 修改
@Update("update `user` set `user`=#{user},`password`=#{password},`start`=#{start} where `uid`=#{uid}")
Integer userUpdate(User user);
// 删除
@Delete("delete from `user` where `uid`=#{uid}")
Integer userDelete(Integer uid);
// 查询单条记录
@Select("select * from `user` where `uid`=#{uid}")
User userSelectById(Integer uid);
// 查询所有记录
@Select("select * from `user`")
List<User> userSelectAll();
2、UserMapperTest测试类
/**
* 第五部分:使用注解开发实现增删改查操作
*/
// 增加
@Test
public void userInsert() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUser("lisi");
user.setPassword("123456");
user.setStart("1");
Integer result = mapper.userInsert(user);
System.out.println(result!=0?"添加成功":"添加失败");
}
// 修改
@Test
public void userUpdate() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = new User();
user.setUid(1011);
user.setUser("lucky");
user.setPassword("954321");
user.setStart("0");
Integer result = mapper.userUpdate(user);
System.out.println(result!=0?"修改成功":"修改失败");
}
// 删除
@Test
public void userDelete() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
Integer result = mapper.userDelete(1011);
System.out.println(result!=0?"删除成功":"删除失败");
}
// 查询单条记录
@Test
public void userSelectById() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.userSelectById(1010);
System.out.println("user = " + user);
}
// 查询所有记录
@Test
public void userSelectAll() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List<User> users = mapper.userSelectAll();
Iterator<User> iterator = users.iterator();
while (iterator.hasNext()){
User user = iterator.next();
System.out.println("user = " + user);
}
}
MyBatis缓存机制
MyBatis的缓存分为一级缓存和二级缓存,一级缓存是SqlSession级别的缓存,二级缓存是Mapper级别的缓存,二级缓存是多个SqlSession共享的。MyBatis通过缓存机制减轻数据压力,提高数据库性能。
一级缓存:
MyBatis的一级缓存是SqlSession级别的缓存,在操作数据库时需要构造SqlSession对象,在对象中有一个HashMap用于存储缓存数据,不同的SqlSession之间缓存数据区域是相互不影响的。
一级缓存的作用域是SqlSession范围的,当在同一个SqlSession中执行两次相同的sql语句时,第一次执行完毕会将数据库中查询的数据写到缓存中,第二次查询时会从缓存中获取数据,不再去底层进行数据库查询,从而提高了查询效率。需要注意的是:如果SqlSession执行了增加、修改、删除操作,MyBatis则会清空SqlSession中的一级缓存,这样做的目的是为了保证缓存数据中存储的最新信息,避免出现脏读现象。
当一个SqlSession结束后该SqlSession中的一级缓存也就不存在了,MyBatis默认开启一级缓存,不需要进行任何配置。
注意:MyBatis的缓存机制是基于id进行缓存,也就是说MyBatis在使用HashMap缓存机制,是使用对象id作为key,而对象作为value保存。
二级缓存:
二级缓存是Mapper级别的缓存机制,使用二级缓存时,多个SqlSession使用同一个Mapper的sql语句去操作数据库,得到的数据会存在二级缓存区域,它同样是使用HashMapper进行数据存储,相比一级缓存SqlSession,二级缓存的范围更大,多个SqlSession可以公用二级缓存,二级缓存是跨SqlSession的。
二级缓存是多个SqlSession共享的,其作用域是Mapper的同一个namespace,不同的SqlSession两次执行相同的Mapper下的sql语句,且向sql中传递的参数也相同,即最终执行相同的sql语句,则第一次执行完毕会将数据库中查询的数据写到缓存,第二次查询时会从缓存中获取数据,不再去底层数据库查询,从而提高查询效率。
MyBatid默认没有开启二级缓存,需要再手动开启二级缓存。
MyBatis二级缓存
一级缓存:MyBatis默认开启一级缓存。
一级缓存失效情况:
1.不同的SqlSession对应不同的缓存
2.同一个SqlSession但是查询条件不同
3.同一个SqlSession执行两次相同查询之间做了增删改的操作
4.同一个SqlSession执行两次相同查询之间手动清空缓存
二级缓存:MyBatis默认没有开启二级缓存,需要手动开启二级缓存。
二级缓存失效的条件:
在两次查询之间进行了任意的增删改操作,一级二级缓存同时失效
开启二级缓存:
- 第一步:在配置文件中开启二级缓存
- 第二步:在对应的xml映射文件中开启二级缓存
- 第三步:查询数据封装的实体类要实现序列化接口
- 第四步:二级缓存需要在一级缓存失效或提交后生效
第一步:mybatis-config.xml配置文件
<!-- 第一步:在配置文件中开启二级缓存--> <setting name="cacheEnabled" value="true"/>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入数据库配置文件-->
<properties resource="config/jdbc.properties"></properties>
<settings>
<!-- 开启驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启日志-->
<setting name="logImpl" value="log4j"/>
<!-- 第一步:在配置文件中开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 设置别名-->
<typeAliases>
<package name="cn.wzw.my.entity"/>
</typeAliases>
<environments default="development">
<environment id="development">
<!-- 事务管理-->
<transactionManager type="JDBC"/>
<!-- 配置数据源-->
<dataSource type="POOLED">
<!-- 使用配置文件中的键,设置数据库驱动、链接地址、用户名、密码-->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- mapper接口映射-->
<mappers>
<package name="cn.wzw.my.mapper"/>
</mappers>
</configuration>
第二步:在UserMapper.xml映射文件中开启二级缓存
<!--
/**
* 第六部分:MyBatis二级缓存
*/
-->
<!-- 第二步:在对应的xml映射文件中开启二级缓存 -->
<cache></cache>
<!-- 验证MyBatis缓存机制的查询语句-->
<select id="selectOneUser" resultType="user">
select * from `user` where `uid`=#{uid}
</select>
第三步:User实体类要实现序列化接口
package cn.wzw.my.entity;
import lombok.Data;
import java.io.Serializable;
import java.util.List;
// 第三步:查询数据封装的实体类要实现序列化接口
@Data
public class User implements Serializable {
private long uid;
private String user;
private String password;
private String start;
// 额外添加的员工属性,用于存储对应部门中的所有员工信息
private List<Emp> emps;
}
第四步:二级缓存需要在一级缓存失效或提交后生效
UserMapper.xml文件
/**
* 第六部分:MyBatis二级缓存
*/
User selectOneUser(Integer uid);
UserMapperTest测试类
/**
* 第六部分:MyBatis二级缓存
*/
@Test
public void selectOneUser() {
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
User user = mapper.selectOneUser(1010);
System.out.println("user = " + user);
// 第四步:二级缓存需要在一级缓存失效或提交后生效
// 清空一级缓存
sqlSession.commit();
UserMapper mapper1 = sqlSession.getMapper(UserMapper.class);
User user1 = mapper1.selectOneUser(1010);
System.out.println("user1 = " + user1);
}
MyBatis分页插件
第一步:pom.xml 中添加分页插件依赖
<!-- 分页依赖-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>5.3.0</version>
</dependency>
第二步:mybatis-config.xml配置文件中配置分页插件
复制pagehelper分页插件中的PageInterceptor文件路径
<plugins> <!-- pagehelper分页插件中的PageHelper文件路径:"com.github.pagehelper.PageInterceptor"--> <plugin interceptor="com.github.pagehelper.PageInterceptor"></plugin> </plugins>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 引入数据库配置文件-->
<properties resource="config/jdbc.properties"></properties>
<settings>
<!-- 开启驼峰命名-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
<!-- 开启日志-->
<setting name="logImpl" value="log4j"/>
<!-- 第一步:在配置文件中开启二级缓存-->
<setting name="cacheEnabled" value="true"/>
</settings>
<!-- 设置别名-->
<typeAliases>
<package name="cn.wzw.my.entity"/>
</typeAliases>
<!-- 配置分页插件-->
<plugins>
<!-- pagehelper分页插件中的PageHelper文件路径:"com.github.pagehelper.PageHelper"-->
<plugin interceptor="com.github.pagehelper.PageHelper"></plugin>
</plugins>
<environments default="development">
<environment id="development">
<!-- 事务管理-->
<transactionManager type="JDBC"/>
<!-- 配置数据源-->
<dataSource type="POOLED">
<!-- 使用配置文件中的键,设置数据库驱动、链接地址、用户名、密码-->
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!-- mapper接口映射-->
<mappers>
<package name="cn.wzw.my.mapper"/>
</mappers>
</configuration>
第三步:UserMapperTest测试类中查询数据测试分页插件PageHelper
/**
* 第七部分:MuBatis分页插件PageHelper
*/
@Test
public void pageHelper(){
SqlSession sqlSession = sqlSessionFactory.openSession(true);
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 使用分页插件进行分页显示;pageNum:表现页数;pageSize:表示每页显示多少条记录
PageHelper.startPage(1,3);
// 查询所有数据
List<User> users = mapper.selectUserAll();
// iterator迭代器遍历集合
Iterator<User> iterator = users.iterator();
while (iterator.hasNext()){
User user = iterator.next();
System.out.println("user = " + user);
}
PageInfo<User> pageInfo = new PageInfo<>(users);
//获取分页的相关数据
System.out.println(pageInfo);
//获取数据记录总条数
long total = pageInfo.getTotal();
System.out.println(total);
//获取当前页的显示数据记录
List<User> list = pageInfo.getList();
for (User user:list){
System.out.println("user = " + user);
}
}