MyBatis 是一款优秀的半自动的ORM持久层框架,它支持自定义 SQL、存储过程以及高级映射。
MyBatis 免除了几乎所有的 JDBC 代码以及设置参数和获取结果集的工作。
MyBatis 可以通过简单的 XML 或注解来配置和映射原始类型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 对象)为数据库中的记录。
持久层:可以立即保存在磁盘上,在这里可以理解为与数据库相关操作。
什么是ORM
OBject Relation Mapping 对象关系映射
对象指的是面向面向对象,关系指的是数据库中的表,
例如Java语言中的POJO类与数据库模型之间的对应关系。
为什么MyBatis是半自动ORM框架
public class User(){
private long id;
private String realname;
}
User user = user .getById(3);
SELECT `id`,`realname` FROM `user` WHERE `id` = 3;
以上用例为ORM框架部分执行代码,发现在ORM框架中不需要使用SQL语句,
大大减少了程序员学习成本和SQL语句维护成本,
另外当数据库产品更换的之后无需重新编写项目中的SQL语句
-- MySQL
SELECT * FROM `user` LIMIT 10;
-- SqlServer
SELECT * FROM `user` TOP 10;
用MyBatis进行开发的,需要手写SQL语句,而ORM框架例如Hibernate则不需要编写SQL语句。
为什么MyBais是半自动ORM框架我们还要去学习呢
因为MyBatis使用自定义SQL所以更加灵活尤其在多表操作
SqlSession对象,该对象包含了执行SQL语句的所有方法,例如JDBC里面Connection
对象 | 说明 |
---|---|
Executor接口 | 执行器.统一调度其他三个对象执行对应的SQL |
StatementHandler | 使用的数据库中的Statement执行操作 相当于字符串拼接 |
PrepareStatement | 使用SQL传参的方式处理 |
ResultHandler | 对最后的结果进行封装 |
Executor接口,将传递过来的参数动态生成SQL语句,负责查询缓存。
MappedStatement对象,该对象负责对SQL封装,用于存储需要映射的SQL语句及参数等信息
ResultHandler对象,用户返回结果集合,封装成最红想要的数据类型,可以自定义返回类型
mvn archetype:generate
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.lihaozhegroupId>
<artifactId>mybatisartifactId>
<version>1.0-SNAPSHOTversion>
<name>mybatisname>
<packaging>jarpackaging>
<properties>
<jdk.version>17jdk.version>
<maven.compiler.source>17maven.compiler.source>
<maven.compiler.target>17maven.compiler.target>
<maven.compiler.compilerVersion>17maven.compiler.compilerVersion>
<maven.compiler.encoding>utf-8maven.compiler.encoding>
<project.build.sourceEncoding>utf-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<maven.test.failure.ignore>truemaven.test.failure.ignore>
<maven.test.skip>truemaven.test.skip>
<junit.version>5.8.2junit.version>
<fastjson.version>2.0.6fastjson.version>
<gson.version>2.9.0gson.version>
<hutool.version>5.8.0.M3hutool.version>
<jackson.version>2.13.3jackson.version>
<lombok.version>1.18.24lombok.version>
<java-testdata.version>1.1.2java-testdata.version>
properties>
<dependencies>
<dependency>
<groupId>org.junit.jupitergroupId>
<artifactId>junit-jupiter-apiartifactId>
<version>${junit.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>com.github.binarywanggroupId>
<artifactId>java-testdata-generatorartifactId>
<version>${java-testdata.version}version>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>3.8.1version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.11.0version>
dependency>
<dependency>
<groupId>org.junit.jupitergroupId>
<artifactId>junit-jupiter-engineartifactId>
<version>${junit.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>${hutool.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
<scope>providedscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>${fastjson.version}version>
dependency>
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>${gson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatypegroupId>
<artifactId>jackson-datatype-jsr310artifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.29version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.10version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.8version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.3.20version>
dependency>
<dependency>
<groupId>org.slf4jgroupId>
<artifactId>slf4j-simpleartifactId>
<version>1.7.36version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-war-pluginartifactId>
<version>3.3.2version>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<encoding>UTF-8encoding>
<source>${jdk.version}source>
<target>${jdk.version}target>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-clean-pluginartifactId>
<version>3.2.0version>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-resources-pluginartifactId>
<version>3.2.0version>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-surefire-pluginartifactId>
<version>2.22.2version>
<configuration>
<skip>trueskip>
configuration>
plugin>
plugins>
build>
project>
src/main/resources/config.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql:///mybatis?useUnicode=true&characterEncoding=UTF8&useSSL=false&useServerPrepStmts=false&rewriteBatchedStatements=true&cachePrepStmts=true&allowMultiQueries=true&serverTimeZone=Aisa/Shanghai
username=root
password=123456
src/main/resources/mybatis/mybatis-config.xml
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="config.properties" />
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
configuration>
@Test
public void testConetion() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
System.out.println(sqlSession.getConnection());
// 归还连接给数据源
sqlSession.close();
}
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public interface PersonMapper {
/**
* 查询用户列表 resultType
*
* @return
*/
List<Person> selectAll4t();
}
src/main/java/com/lihaozhe/mapper/PersonMapper.xml
或者
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<select id="selectAll4t" resultType="com.lihaozhe.pojo.Person">
SELECT *
FROM `person`
select>
mapper>
<mappers>
<package name="com.lihaozhe.mapper"/>
mappers>
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="config.properties" />
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<package name="com.lihaozhe.mapper"/>
mappers>
configuration>
src/test/java/com/lihaozhe/mapper/PersonMapperTest.java
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void selectAll4t() {
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行接口中的方法
List<Person> people = mapper.selectAll4t();
// 释放SqlSession资源
sqlSession.close();
// 遍历集合
people.forEach(System.out::println);
}
}
测试结果发现 idCard属性获取到的结果为null,
这是由于查询字段中没有idCard字段,
换言之 idCard属性 没有与 id_card字段形成映射关系
解决方法有两种:
- 使用ResultMap做结果集映射
- 在核心配置文件中设置 mapUnderscoreToCamelCase 值为 true
映射配置文件中编写 resultMap
<resultMap id="PersonMap" type="com.lihaozhe.pojo.Person">
<id property="id" column="id"/>
<result property="id" column="id"/>
<result property="uuid" column="uuid"/>
<result property="mobile" column="mobile"/>
<result property="nickname" column="nickname"/>
<result property="idCard" column="id_card"/>
resultMap>
修改select id=“selectAll4m” 的属性 resultType=“com.lihaozhe.pojo.Person” 为 resultMap=“PersonMap”
<select id="selectAll4m" resultMap="PersonMap">
SELECT *
FROM `person`
select>
在接口中增加对应的方法
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 查询用户列表 resultType
*
* @return
*/
List<Person> selectAll4t();
/**
* 查询用户列表 resultMap
*
* @return
*/
List<Person> selectAll4m();
}
测试 selectAll4m 方法
@Test
public void selectAll4m(){
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行接口中的方法
List<Person> people = mapper.selectAll4m();
// 释放SqlSession资源
sqlSession.close();
// 遍历集合
people.forEach(System.out::println);
}
在核心配置文件中配置此参数如下
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
settings>
测试 selectAll4t 方法
@Test
public void selectAll4t(){
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行接口中的方法
List<Person> people = mapper.selectAll4t();
// 释放SqlSession资源
sqlSession.close();
// 遍历集合
people.forEach(System.out::println);
}
在核心配置文件中 设置logImpl 的值为 STDOUT_LOGGING
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
src/main/resources/mybatis/myatis-confog.xml
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="config.properties" />
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<package name="com.lihaozhe.mapper"/>
mappers>
configuration>
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public interface PersonMapper {
/**
* 根据手机号查询用户信息
* @param mobile
* @return
*/
Person selectByMobile(@Param("mobile") String mobile);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
默认情况下,使用 #{} 参数语法时,MyBatis 会创建 PreparedStatement 参数占位符,并通过占位符安全地设置参数(就像使用 ? 一样)。
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<select id="selectByMobile" parameterType="java.lang.String" resultType="com.lihaozhe.pojo.Person">
SELECT *
FROM `person`
WHERE `mobile` = #{mobile}>
select>
mapper>
com.lihaozhe.mapper.PersonMapperTest
注意:测试方法中获取SqlSession对象
@Test
public void selectByMobile(){
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行接口中的方法
Person person = mapper.selectByMobile("13925135946");
// 释放SqlSession资源
sqlSession.close();
// 输出查询结果
System.out.println(person);
}
默认情况下,使用 #{} 参数语法时,MyBatis 会创建 PreparedStatement 参数占位符,并通过占位符安全地设置参数(就像使用 ? 一样)。
这样做更安全,更迅速,通常也是首选做法,不过有时你就是想直接在 SQL 语句中直接插入一个不转义的字符串。
比如 ORDER BY 子句,MyBatis 就不会修改或转义该字符串了。
需求:查询的条件字段和该字段的值不确定
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public interface PersonMapper {
/**
* 根据不确定的字段查询
* @param column
* @param value
* @return
*/
Person selectByFiled(@Param("column") String column,@Param("value")String value);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<select id="selectByFiled" resultType="com.lihaozhe.pojo.Person">
SELECT *
FROM `person`
WHERE ${column} = #{value}
select>
mapper>
com.lihaozhe.mapper.PersonMapperTest
注意:测试方法中获取SqlSession对象
@Test
public void selectByFiled() {
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行接口中的方法
Person person = mapper.selectByFiled("mobile", "18400880850");
// 释放SqlSession资源
sqlSession.close();
// 输出查询结果
System.out.println(person);
}
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE mobile = ?
==> Parameters: 18400880850(String)
起因:parameterType 和 resultType 的值 需要使用类的完全限定名 太麻烦 希望使用 简短的名字来替代 类的完全限定名
在核心配置文件中 配置如下内容:
<typeAliases>
<typeAlias alias="login" type="com.lihaozhe.pojo.Login"/>
typeAliases>
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Login;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 上午8:52
*/
public interface PersonMapper {
/**
* 根据唯一身份标识符用户信息
*
* @param uuid
* @return
*/
Person selectByUuid(@Param("uuid") String uuid);;
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<select id="selectByUuid" resultType="person">
SELECT *
FROM `person`
WHERE uuid = #{uuid}
select>
mapper>
com.lihaozhe.mapper.PersonMapperTest
注意:测试方法中获取SqlSession对象
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Login;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public class LoginMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void selectByPid(){
LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
Login login = mapper.selectByPid(3);
sqlSession.close();
System.out.println(login);
}
}
起因:在核心配置文件中单独为某个类做别名映射 如果需要映射的类太多 则过于麻烦 可以指定某个包面所有的类指定别名映射
<typeAliases>
<package name="com.lihaozhe.pojo"/>
typeAliases>
src/main/resources/mybatis/myatis-confog.xml
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="config.properties" />
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
<typeAliases>
<package name="com.lihaozhe.pojo"/>
typeAliases>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<package name="com.lihaozhe.mapper"/>
mappers>
configuration>
com.lihaozhe.mapper.DeptMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Dept;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public interface DeptMapper {
/**
* 新增部门
*
* @param dept
* @return
*/
int insert(@Param("dept") Dept dept);
}
src/main/resources/com/lihaozhe/mapper/DeptMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.DeptMapper">
<insert id="insert">
INSERT INTO `dept` (`dname`)
VALUES (#{dept.dname})
insert>
mapper>
com.lihaozhe.mapper.DeptMapperTest
注意:测试方法中获取SqlSession对象
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public class DeptMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void insert(){
// 获取代理对象
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
// 准备数据
Dept dept = new Dept("人事部");
// 插入之前 输出准备数据
System.out.println("插入之前 dept >>> " + dept);
// 调用方法执行 insert 操作
mapper.insert(dept);
// 手动提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
// 插入之后 输出准备数据
System.out.println("插入之后 dept >>> " + dept);
}
}
插入之前 dept >>> Dept(did=0, dname=人事部)
Opening JDBC Connection
Created connection 671596011.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2807bdeb]
==> Preparing: INSERT INTO `dept` (`dname`) VALUES (?)
==> Parameters: 人事部(String)
<== Updates: 1
Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2807bdeb]
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2807bdeb]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@2807bdeb]
Returned connection 671596011 to pool.
插入之后 dept >>> Dept(did=0, dname=人事部)
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.DeptMapper">
<insert id="insert" parameterType="dept" useGeneratedKeys="true" keyProperty="did" keyColumn="did">
INSERT INTO `dept` (`dname`)
VALUES (#{dept.dname})
insert>
mapper>
插入之前 dept >>> Dept(did=0, dname=摸鱼部)
Opening JDBC Connection
Created connection 1643141512.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@61f05988]
==> Preparing: INSERT INTO `dept` (`dname`) VALUES (?)
==> Parameters: 摸鱼部(String)
<== Updates: 1
Committing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@61f05988]
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@61f05988]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@61f05988]
Returned connection 1643141512 to pool.
插入之后 dept >>> Dept(did=8, dname=摸鱼部)
com.lihaozhe.mapper.DeptMappe
package com.lihaozhe.mapper;
import cn.hutool.core.collection.LineIter;
import com.lihaozhe.pojo.Dept;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public interface DeptMapper {
/**
* 修改部门信息
*
* @param dept
* @return
*/
int update(@Param("dept") Dept dept);
}
src/main/resources/com/lihaozhe/mapper/DeptMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.DeptMapper">
<update id="update">
UPDATE `dept`
SET `dname` = #{dept.dname}
WHERE `did` = #{dept.did}
update>
mapper>
com.lihaozhe.mapper.DeptMappeTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午8:52
*/
public class DeptMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void getSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void update() {
// 获取代理对象
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
// 准备数据
Dept dept = new Dept(8, "企宣部");
// 调用方法执行 update 操作
mapper.update(dept);
// 手动提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
}
com.lihaozhe.mapper.DeptMappe
package com.lihaozhe.mapper;
import cn.hutool.core.collection.LineIter;
import com.lihaozhe.pojo.Dept;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/6 上午11:13
*/
public interface DeptMapper {
/**
* 根据部门id删除部门
*
* @param did
* @return
*/
int deleteByDid(@Param("did") long did);
}
src/main/resources/com/lihaozhe/mapper/DeptMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.DeptMapper">
<delete id="deleteByDid">
DELETE
FROM `dept`
WHERE `did` = #{did}
delete>
mapper>
com.lihaozhe.mapper.DeptMappeTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:56
*/
public class DeptMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void getSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void deleteByDid(){
// 获取代理对象
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
// 调用方法执行 delete 操作
mapper.deleteByDid(8);
// 手动提交事务
sqlSession.commit();
// 释放资源
sqlSession.close();
}
}
com.lihaozhe.util.mybatis.MyBatisUtil
package com.lihaozhe.util.mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/13 上午11:39
*/
public abstract class MyBatisUtil {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();
private static SqlSessionFactory sqlSessionFactory;
private static SqlSession sqlSession;
static {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 获取 SqlSession 对象
*
* @return SqlSession 对象
*/
public static SqlSession openSqlSession() {
if (threadLocal.get() == null) {
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
// 与线程绑定
threadLocal.set(sqlSession);
// 返回 SqlSession 对象
return sqlSession;
} else {
return threadLocal.get();
}
}
/**
* 获取 SqlSession 对象
*
* @param executorType SIMPLE,REUSE,BATCH
* @return SqlSession 对象
*/
public static SqlSession openSqlSession(ExecutorType executorType) {
if (threadLocal.get() == null) {
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession(executorType);
// 与线程绑定
threadLocal.set(sqlSession);
// 返回 SqlSession 对象
return sqlSession;
} else {
return threadLocal.get();
}
}
/**
* 释放资源
*/
public static void close() {
if (threadLocal.get() != null) {
sqlSession = threadLocal.get();
threadLocal.remove();
sqlSession.close();
}
}
/**
* 事务提交 释放资源
*/
public static void commitAndClose() {
if (threadLocal.get() != null) {
sqlSession = threadLocal.get();
threadLocal.remove();
sqlSession.commit();
sqlSession.close();
}
}
/**
* 事务回滚 释放资源
*/
public static void rollbackAndClose() {
if (threadLocal.get() != null) {
sqlSession = threadLocal.get();
threadLocal.remove();
sqlSession.rollback();
sqlSession.close();
}
}
}
@Test
public void test() {
// 需求:查询某部门的(did) 名字有某个字的(ename) 员工列表
// 分析:
// 如果不给部门编号则在所有部门中查找 did 不能为 0
// 如果有部门编号则在某部门内查找
long did = 3;
StringBuilder sql = new StringBuilder("select * from person where ");
if (did != 0) {
sql.append(" did = ?");
sql.append(" and ename like ");
sql.append(" '%");
sql.append(" ? ");
sql.append("%' ");
}else {
sql.append(" ename like ");
sql.append(" '%");
sql.append(" ? ");
sql.append("%' ");
}
System.out.println(sql.toString());
// select * from person where ename like % ? %
// select * from person where did = ? and ename like % ? %
}
起因:根据不同的查询条件生成不同的SQL语句
将经常使用的SQL语句定义成SQL片段当使用的时候引导该片段即可 有点像 变量的赋值与引用
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 根据用户ID查询该用户信息 使用SQL片段
*
* @return
*/
Person selectById(@Param("id") long id);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<sql id="select_person">
SELECT *
FROM `person`
sql>
<select id="selectById" resultType="person">
<include refid="select_person">include>
WHERE `id` = #{id}
select>
mapper>
com.lihaozhe.mapper.PersonMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void selectById() {
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行接口中的方法
Person person = mapper.selectByid(3);
// 释放SqlSession资源
sqlSession.close();
// 输出查询结果
System.out.println(person);
}
}
SQL解析结果:
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5bc69d3c6aba4a61a81115ba916237f3, 13925135946, 邹庶, 313227198110042264
<== Total: 1
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 模糊查找某姓名中包含某个字的用户
*
* @param nickname
* @return
*/
List<Person> selectByNickname(@Param("nickname") String nickname);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
<sql id="select_person">
SELECT *
FROM `person`
sql>
<select id="selectByNickname" resultType="person">
<select id="selectByNickname" resultType="person">
<bind name="like_nickname" value="'%' + nickname + '%'"/>
<include refid="select_person">include>
WHERE `nickname` like #{like_nickname}
select>
select>
注意:在bind标签中value属性获取值的时候不需要使用#
com.lihaozhe.mapper.PersonMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void getSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void selectByNickname() {
// 获取接口代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 准备数据集
String nickname = "孙";
// %孙%
StringBuilder param = new StringBuilder();
param.append("%");
if (!StringUtils.isEmpty(nickname)) {
param.append(nickname);
}
param.append("%");
// 执行代理对象中的方法
List<Person> personList = mapper.selectByNickname(param.toString());
// 释放资源
sqlSession.close();
// 输出结果
personList.forEach(System.out::println);
}
}
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void getSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void selectByNickname() {
// 获取接口代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行代理对象中的方法
List<Person> personList = mapper.selectByNickname("孙");
// 释放资源
sqlSession.close();
// 输出结果
personList.forEach(System.out::println);
}
}
结果解析:
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `nickname` LIKE ?
==> Parameters: %孙%(String)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 2, 82bbfb207b38447e93fffe3c53ba3e5b, 15051340785, 孙陈, 919948197901282822
<== Row: 31, 3db353f3b81b44c6bc6095487d8a5b05, 13628389232, 孙鹃祈, 314211197412052754
<== Row: 72, 2032a25e5245454894e192d8d5b17147, 13352587230, 孙茎, 453355198107241539
<== Total: 3
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 模糊查找某姓名中包含某个字的男性或女性用户
*
* @param nickname
* @return
*/
List<Person> selectByGenderAndNickname(@Param("gender") Integer gender, @Param("nickname") String nickname);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<sql id="select_person">
SELECT *
FROM `person`
sql>
<select id="selectByGenderAndNickname" resultType="person">
<include refid="select_person">include>
WHERE
<if test="gender != null">
if(mod(substr(id_card, 17, 1), 2), 1, 0) = #{gender}
if>
<if test="nickname != null and nickname.length > 0">
<bind name="like_nickname" value="'%' + nickname + '%'"/>
AND `nickname` like #{like_nickname}
if>
select>
mapper>
结果解析:
-- 当方法中参数nickname的值为null或者字符串长度为零
SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `gender` = ?
-- 当方法中参数nickname的值不为null且字符串长度大于零
SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `gender` = ? AND `nickname` LIKE ?
com.lihaozhe.mapper.PersonMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void oepnSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void selectByGenderAndNickname() {
// 获取接口代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行代理对象中的方法
// List personList = mapper.selectByGenderAndNickname(0,null);
List<Person> personList = mapper.selectByGenderAndNickname(1,"孙");
// 释放资源
sqlSession.close();
// 输出结果
personList.forEach(System.out::println);
}
}
使用上面if相同的方法selectByGenderAndNickname和配置文件
当两个参数同时为null的时候sql语句为 :
SELECT * FROM `perason` WHERE
这条sql语句存在语法错误 当没有查询条件的时候做出如下配置
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<sql id="select_person">
SELECT *
FROM `person`
sql>
<select id="selectByGenderAndNickname" resultType="person">
<include refid="select_person">include>
WHERE
<if test="gender != null">
if(mod(substr(id_card, 17, 1), 2), 1, 0) = #{gender}
if>
<if test="nickname != null and nickname.length > 0">
<bind name="like_nickname" value="'%' + nickname + '%'"/>
AND `nickname` like #{like_nickname}
if>
select>
mapper>
有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。
需求:
id
,uuid
,mobile
多个查询条件选择其中一个
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* `id`, `uuid`, `mobile` 多个查询条件选择其中一个
* @param person
* @return
*/
Person selectByIdOrUuidOrMobile(@Param("person") Person person);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
<sql id="select_person">
SELECT *
FROM `person`
sql>
<select id="selectByIdOrUuidOrMobile" resultType="person">
<include refid="select_person">include>
<where>
<choose>
<when test="person.id != null and person.id > 0">
`id` = #{person.id}
when>
<when test="person.uuid != null and person.uuid.length > 0">
`uuid` = #{person.uuid}
when>
<otherwise>
`mobile` = #{person.mobile}
otherwise>
choose>
where>
select>
解析结果:
-- 只传入mobile
SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `mobile` = ?
-- 传入uuid
SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `uuid` = ?
-- 传入id
SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
com.lihaozhe.mapper.PersonMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void selectByIdOrUuidOrMobile() {
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 准备数据
Person person = new Person();
// SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `mobile` = ?
person.setMobile("13352587230");
// SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `uuid` = ?
person.setUuid("2032a25e5245454894e192d8d5b17147");
// SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
person.setId(33);
// 执行接口中的方法
person = mapper.selectByIdOrUuidOrMobile(person);
// SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `nickname` LIKE ?
// 释放SqlSession资源
sqlSession.close();
// 输出查询结果
System.out.println(person);
}
}
com.lihaozhe.mapper.EmpMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Emp;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/8 上午10:32
*/
public interface EmpMapper {
/**
* 动态SQL if 按照部门ID和姓名中部分关键字查找
* 如果没有传递部门ID则在所有部门中查找
* 如果传递部门ID但没有传递姓名中的关键字则查找该部门下所有员工列表
* 如果部门ID和姓名中的关键字都没有传递则查找所有员工列表
*
* @param emp
* @return
*/
List<Emp> selcetByDidAndEname(@Param("emp") Emp emp);
}
src/main/resources/com/lihaozhe/mapper/EmpMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.EmpMapper">
<select id="selectByDidAndEname" resultType="emp">
SELECT * FROM `emp`
<trim prefix="where" prefixOverrides="AND|OR">
<if test="emp.did != null and emp.did > 0">
`did` = #{emp.did}
if>
<if test="emp.ename != null and emp.ename.length > 0">
<bind name="like_ename" value="'%' + emp.ename + '%'"/>
AND `ename` like #{like_ename}
if>
trim>
select>
mapper>
解析 结果:
-- ename 孙
SELECT `eid`, `ename`, `did` FROM `emp` WHERE `ename` Like ?
-- ename ""
SELECT `eid`, `ename`, `did` FROM `emp`
-- did 3
SELECT `eid`, `ename`, `did` FROM `emp` WHERE `did` = ?
-- did 3 并且 ename 孙
SELECT `eid`, `ename`, `did` FROM `emp` WHERE `did` = ? AND `ename` Like ?
com.lihaozhe.mapper.EmpMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Emp;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/8 下午12:02
*/
public class EmpMapperTest {
@Test
public void selcetByDidAndEname(){
// 使用工具类获取 SqlSession 对象
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取接口代理对象
EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
// 准备数据
Emp emp = new Emp();
// SELECT `eid`, `ename`, `did` FROM `emp` WHERE `ename` Like ?
emp.setEname("孙");
// SELECT `eid`, `ename`, `did` FROM `emp`
// emp.setEname("");
// SELECT `eid`, `ename`, `did` FROM `emp` WHERE `did` = ?
emp.setDid(3);
// SELECT `eid`, `ename`, `did` FROM `emp` WHERE `did` = ? AND `ename` Like ?
// 执行 接口 中的方法
List<Emp> emps = mapper.selcetByDidAndEname(emp);
// 使用工具类 释放资源
MyBatisUtil.close();
// 输出结果
emps.forEach(System.out::println);
}
}
用于动态更新语句的类似解决方案叫做 set, set 元素可以用于动态包含需要更新的列,忽略其它不更新的列。
需求:更新 person表 中的个别字段
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 修改员工表数据
*
* @param person
* @return
*/
int updateById(@Param("person") Person person);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<update id="updateById" parameterType="person">
UPDATE `person`
<set>
<if test="person.nickname != null and person.nickname.length > 0">
`nickname` = #{person.nickname},
if>
<if test="person.mobile != null and person.mobile.length == 11">
`mobile` = #{person.mobile},
if>
<if test="person.idCard != null and (person.idCard.length == 18 or person.idCard.length == 15)">
`id_card` = #{person.idCard}
if>
set>
WHERE `id` = #{person.id}
update>
mapper>
或者:
<update id="updateById">
UPDATE `person`
<trim prefix="set" suffixOverrides=",">
<if test="person.nickname != null and person.nickname.length > 0">
`nickname` = #{person.nickname},
if>
<if test="person.mobile != null and person.mobile.length == 11">
`mobile` = #{person.mobile},
if>
<if test="person.idCard != null and (person.idCard.length == 18 or person.idCard.length == 15)">
`id_card` = #{person.idCard}
if>
trim>
WHERE `id` = #{person.id}
update>
com.lihaozhe.mapper.PersonMapperTest
package com.lihaozhe.mapper;
import cn.binarywang.tools.generator.ChineseIDCardNumberGenerator;
import cn.binarywang.tools.generator.ChineseMobileNumberGenerator;
import cn.binarywang.tools.generator.ChineseNameGenerator;
import cn.hutool.core.util.IdUtil;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void updateById() {
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 准备数据
Person person = new Person();
String mobile = ChineseMobileNumberGenerator.getInstance().generate();
System.out.println(mobile);
// UPDATE `person` SET `mobile` = ? WHERE `id` = ?
person.setMobile(mobile);
person.setId(3);
// 执行接口中的方法
mapper.updateById(person);
// 事务提交
sqlSession.commit();
// 释放SqlSession资源
sqlSession.close();
// 输出结果
if (status > 0) {
System.out.println("☺");
} else {
System.out.println("o(╯□╰)o");
}
}
}
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 查找多个id的用户列表
*
* @param ids
* @return
*/
List<Person> selectByIds(@Param("ids") Long... ids);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<sql id="select_person">
SELECT *
FROM `person`
sql>
<select id="selectByIds" resultType="person">
<include refid="select_person">include>
<where>
`id` IN
<foreach collection="ids" index="index" item="id" open="(" separator="," close=")">
#{id}
foreach>
where>
select>
mapper>
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import cn.binarywang.tools.generator.ChineseIDCardNumberGenerator;
import cn.binarywang.tools.generator.ChineseMobileNumberGenerator;
import cn.binarywang.tools.generator.ChineseNameGenerator;
import cn.hutool.core.util.IdUtil;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void selectByIds() {
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行接口中的方法
List<Person> personList = mapper.selectByIds(1L, 3L, 5L);
// 释放SqlSession资源
sqlSession.close();
// 输出查询结果
personList.forEach(System.out::println);
}
}
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 根据传入的id删除用户
*
* @param ids
* @return
*/
int delByIds(@Param("ids") Long... ids);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<delete id="delByIds">
DELETE FROM `person`
<where>
`id` IN
<foreach collection="ids" index="index" item="id" open="(" separator="," close=")">
#{id}
foreach>
where>
delete>
mapper>
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import cn.binarywang.tools.generator.ChineseIDCardNumberGenerator;
import cn.binarywang.tools.generator.ChineseMobileNumberGenerator;
import cn.binarywang.tools.generator.ChineseNameGenerator;
import cn.hutool.core.util.IdUtil;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void delByIds() {
// 获取该接口的代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行接口中的方法
mapper.delByIds(1L, 3L, 5L);
// 事务提交
sqlSession.commit();
// 释放SqlSession资源
sqlSession.close();
// 输出结果
if (status > 0) {
System.out.println("☺");
System.out.println(status + " 条记录被删除");
} else {
System.out.println("o(╯□╰)o");
}
}
}
清空person表
truncate person;
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 新增用户列列表
*
* @param personList
* @return
*/
int insertAll(@Param("personList") List<Person> personList);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<insert id="insertAll">
INSERT INTO `person` (`uuid`,`mobile`,`nickname`,`id_card`) VALUES
<foreach collection="personList" index="index" item="person" separator=",">
(#{person.uuid},#{person.mobile},#{person.nickname},#{person.idCard})
foreach>
insert>
mapper>
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import cn.binarywang.tools.generator.ChineseIDCardNumberGenerator;
import cn.binarywang.tools.generator.ChineseMobileNumberGenerator;
import cn.binarywang.tools.generator.ChineseNameGenerator;
import cn.hutool.core.util.IdUtil;
import com.lihaozhe.pojo.Person;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void insertAll() {
// 准备数据
ArrayList<Person> personList = new ArrayList<>();
for (int i = 0; i < 200; i++) {
Person person = new Person();
person.setUuid(IdUtil.fastSimpleUUID());
person.setMobile(ChineseMobileNumberGenerator.getInstance().generate());
person.setNickname(ChineseNameGenerator.getInstance().generate());
person.setIdCard(ChineseIDCardNumberGenerator.getInstance().generate());
System.out.println(person);
personList.add(person);
}
// 获取接口代理对象
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 执行代理对象中的方法
int status = mapper.insertAll(personList);
// 事务提交
sqlSession.commit();
// 释放资源
sqlSession.close();
// 输出结果
if (status > 0) {
System.out.println("☺");
System.out.println("新增了 " + status + " 条记录");
} else {
System.out.println("o(╯□╰)o");
}
}
}
@Test
public void testConetion() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession 同时设置批处理
SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
System.out.println(sqlSession.getConnection());
// 归还连接给数据源
sqlSession.close();
}
package com.lihaozhe.util.mybatis;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/13 上午11:39
*/
public abstract class MyBatisUtil {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<>();
private static SqlSessionFactory sqlSessionFactory;
private static SqlSession sqlSession;
static {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = null;
try {
reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 获取 SqlSession 对象
*
* @return SqlSession 对象
*/
public static SqlSession openSqlSession() {
if (threadLocal.get() == null) {
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
// 与线程绑定
threadLocal.set(sqlSession);
// 返回 SqlSession 对象
return sqlSession;
} else {
return threadLocal.get();
}
}
/**
* 获取 SqlSession 对象
*
* @param executorType SIMPLE,REUSE,BATCH
* @return SqlSession 对象
*/
public static SqlSession openSqlSession(ExecutorType executorType) {
if (threadLocal.get() == null) {
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession(executorType);
// 与线程绑定
threadLocal.set(sqlSession);
// 返回 SqlSession 对象
return sqlSession;
} else {
return threadLocal.get();
}
}
/**
* 释放资源
*/
public static void close() {
if (threadLocal.get() != null) {
sqlSession = threadLocal.get();
threadLocal.remove();
sqlSession.close();
}
}
/**
* 事务提交 释放资源
*/
public static void commitAndClose() {
if (threadLocal.get() != null) {
sqlSession = threadLocal.get();
threadLocal.remove();
sqlSession.commit();
sqlSession.close();
}
}
/**
* 事务回滚 释放资源
*/
public static void rollbackAndClose() {
if (threadLocal.get() != null) {
sqlSession = threadLocal.get();
threadLocal.remove();
sqlSession.rollback();
sqlSession.close();
}
}
}
com.lihaozhe.mapper.LoginMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Login;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:27
*/
public interface LoginMapper {
/**
* 使用账号和密码登录 获取用户信息
*
* @param login 登录参数 account password
* @return
*/
Person selectPersonByAccountAndPassword01(@Param("login") Login login);
}
src/main/resources/com/lihaozhe/mapper/LoginMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.LoginMapper">
<select id="selectPersonByAccountAndPassword01" resultType="person">
SELECT p.id, nickname
FROM login l
INNER JOIN person p
WHERE pid = p.id
AND account = #{login.account}
AND auth_text = #{login.authText}
select>
mapper>
com.lihaozhe.mapper.LoginMapper.Test
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Login;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:29
*/
public class LoginMapperTest {
@Test
public void selectPersonByAccountAndPassword01(){
Login login = new Login("13925135946", "123456");
SqlSession sqlSession = MyBatisUtil.openSqlSession();
LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
Person person = mapper.selectPersonByAccountAndPassword01(login);
MyBatisUtil.close();
System.out.println(person);
}
}
com.lihaozhe.mapper.LoginMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Login;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:27
*/
public interface LoginMapper {
/**
* 用户登录
*
* @param login 登录参数 account password
* @return
*/
Person selectByAccountAndPassword02(@Param("login") Login login);
}
src/main/resources/com/lihaozhe/mapper/LoginMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.LoginMapper">
<resultMap id="PersonMap" type="person">
<id property="id" column="id"/>
<result property="uuid" column="uuid"/>
<result property="mobile" column="mobile"/>
<result property="nickname" column="nickname"/>
<result property="idCard" column="id_card"/>
resultMap>
<select id="selectPersonByAccountAndPassword02" resultMap="PersonMap">
SELECT p.id, nickname
FROM login l
INNER JOIN person p
WHERE pid = p.id
AND account = #{login.account}
AND auth_text = #{login.authText}
select>
mapper>
com.lihaozhe.mapper.LoginMapper.Test
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Login;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:29
*/
public class LoginMapperTest {
@Test
public void selectPersonByAccountAndPassword02(){
Login login = new Login("13925135946", "123456");
SqlSession sqlSession = MyBatisUtil.openSqlSession();
LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
Person person = mapper.selectPersonByAccountAndPassword02(login);
MyBatisUtil.close();
System.out.println(person);
}
}
com.lihaozhe.mapper.LoginMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Login;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:27
*/
public interface LoginMapper {
/**
* 用户登录
*
* @param login 登录参数 account password
* @return
*/
Person selectByAccountAndPassword03(@Param("login") Login login);
}
src/main/resources/com/lihaozhe/mapper/LoginMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.LoginMapper">
<select id="selectPersonByAccountAndPassword03" resultMap="com.lihaozhe.mapper.PersonMapper.PersonMap">
SELECT p.id, nickname
FROM login l
INNER JOIN person p
WHERE pid = p.id
AND account = #{login.account}
AND auth_text = #{login.authText}
select>
mapper>
com.lihaozhe.mapper.LoginMapper.Test
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Login;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:29
*/
public class LoginMapperTest {
@Test
public void selectPersonByAccountAndPassword03(){
Login login = new Login("13925135946", "123456");
SqlSession sqlSession = MyBatisUtil.openSqlSession();
LoginMapper mapper = sqlSession.getMapper(LoginMapper.class);
Person person = mapper.selectPersonByAccountAndPassword03(login);
MyBatisUtil.close();
System.out.println(person);
}
}
com.lihaozhe.vo.PersonVo
package com.lihaozhe.vo;
import com.lihaozhe.pojo.Login;
import com.lihaozhe.pojo.Person;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 下午2:19
*/
public class PersonVo implements Serializable {
private static final long serialVersionUID = -2348274078216811958L;
/**
* 登录信息
*/
private Login login;
/**
* 员工信息
*/
private Person person;
}
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.vo.PersonVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:27
*/
public interface PersonMapper {
/**
* 根据id获取用户详细信息包括登录信息
*
* @param id 用户ID
* @return
*/
PersonVo selectPersonVoById(@Param("id") long id);
}
<typeAliases>
<package name="com.lihaozhe.pojo"/>
<package name="com.lihaozhe.vo"/>
typeAliases>
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<resultMap id="PersonVoMap" type="personVo">
<association property="login">
<id property="id" column="lid"/>
<result property="account" column="account"/>
<result property="authText" column="auth_text"/>
<result property="pid" column="pid"/>
association>
<association property="person">
<id property="id" column="pid"/>
<result property="uuid" column="uuid"/>
<result property="mobile" column="mobile"/>
<result property="nickname" column="nickname"/>
<result property="idCard" column="id_card"/>
association>
resultMap>
<select id="selectPersonVoById" resultMap="PersonVoMap">
SELECT l.id AS lid,
account,
auth_text,
pid,
uuid,
mobile,
nickname,
id_card
FROM login l
inner join person p
WHERE pid = p.id
and pid = #{id}
select>
mapper>
com.lihaozhe.mapper.PersonMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.vo.PersonVo;
import com.lihaozhe.util.mybatis.MyBatisUtil;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午3:29
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void openSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sessionFactory.openSession();
}
@Test
public void selectPersonVoById(){
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
PersonVo personVo = mapper.selectPersonVoById(3L);
sqlSession.close();
System.out.println(personVo);
}
}
写法与一对一完全一致
下面的案例使用关联查询和子查询分别实现
com.lihaozhe.vo.SonVo
package com.lihaozhe.vo;
import com.lihaozhe.pojo.Father;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 上午9:46
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class SonVo implements Serializable {
private static final long serialVersionUID = -203988976020008362L;
/**
* 儿子ID
*/
private long sId;
/**
* 儿子姓名
*/
private String sName;
/**
* 该儿子父亲ID
*/
private long fId;
/**
* 该儿子父亲信息
*/
private Father father;
}
com.lihaozhe.mapper.SonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.vo.SonVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 下午3:01
*/
public interface SonMapper {
/**
* 根据儿子ID查询儿子和该儿子父亲的信息
*
* @param sid
* @return
*/
SonVo selectSonVoBySid(@Param("sid") long sid);
}
src/main/resources/com/lihaozhe/mapper/SonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.SonMapper">
<resultMap id="SonVoMap" type="sonVo">
<id property="sId" column="s_id"/>
<result property="sName" column="s_name"/>
<result property="fId" column="fid"/>
<association property="father">
<id property="fId" column="fid"/>
<result property="fName" column="f_name"/>
association>
resultMap>
<select id="selectSonVoBySid" resultMap="SonVoMap">
SELECT s_id, s_name, s.f_id AS fid, f_name
FROM son s
INNER JOIN father f ON s.f_id = f.f_id AND s_id = #{sid}
select>
mapper>
com.lihaozhe.mapper.SonMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.SonVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 下午3:13
*/
public class SonMapperTest {
@Test
public void selectSonVoBySid() {
SqlSession sqlSession = MyBatisUtil.openSqlSession();
SonMapper mapper = sqlSession.getMapper(SonMapper.class);
SonVo sonVo = mapper.selectSonVoBySid(3L);
MyBatisUtil.close();
System.out.println(sonVo);
}
}
com.lihaozhe.mapper.FatherMapper
package com.lihaozhe.mapper;
import com.lihaozhe.vo.FatherVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 上午11:15
*/
public interface FatherMapper {
/**
* 根据父亲ID获取父亲信息
*
* @param fid
* @return
*/
Father selectFatherById(@Param("fid") long fid);
}
com.lihaozhe.mapper.SonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.vo.SonVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 上午11:08
*/
public interface SonMapper {
/**
* 根据儿子ID查询儿子和该儿子父亲的信息
*
* @param sid
* @return
*/
SonVo selectSonVoById(@Param("sid") long sid);
}
src/main/resources/com/lihaozhe/mapper/FatherMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.FatherMapper">
<select id="selectFatherById" resultType="father">
SELECT *
FROM `father`
WHERE `f_id` = #{fid}
select>
mapper>
src/main/resources/com/lihaozhe/mapper/SonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.SonMapper">
<resultMap id="SonVoMapper" type="sonVo">
<id property="sId" column="s_id"/>
<result property="sName" column="s_name"/>
<result property="fId" column="f_id"/>
<association property="father" column="f_id" select="com.lihaozhe.mapper.FatherMapper.selectFatherById"/>
resultMap>
<select id="selectSonVoById" resultMap="SonVoMapper">
SELECT *
FROM `son`
WHERE `s_id` = #{sid}
select>
mapper>
com.lihaozhe.mapper.FatherMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.FatherVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 上午11:22
*/
public class FatherMapperTest {
@Test
public void selectFatherById(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
FatherMapper mapper = sqlSession.getMapper(FatherMapper.class);
Father father = mapper.selectFatherById(1L);
MyBatisUtil.close();
System.out.println(father);
}
}
com.lihaozhe.mapper.SonMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.SonVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 上午11:33
*/
public class SonMapperTest {
@Test
public void selectSonVoById() {
SqlSession sqlSession = MyBatisUtil.openSqlSession();
SonMapper mapper = sqlSession.getMapper(SonMapper.class);
SonVo sonVo = mapper.selectSonVoById(3L);
MyBatisUtil.close();
System.out.println(sonVo);
}
}
解析SQL
==> Preparing: SELECT s_id, s_name,f_id FROM son WHERE s_id = ?
==> Parameters: 1(Long)
<== Columns: s_id, s_name, f_id
<== Row: 1, 李金吒, 1
====> Preparing: SELECT f_id, f_name FROM father WHERE f_id = ?
====> Parameters: 1(Integer)
<==== Columns: f_id, f_name
<==== Row: 1, 李靖
<==== Total: 1
<== Total: 1
下面的案例使用子查询和联合查询分别实现
com.lihaozhe.vo.FatherVo
package com.lihaozhe.vo;
import com.lihaozhe.pojo.Son;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 上午10:27
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class FatherVo implements Serializable {
private static final long serialVersionUID = -1335512987974717220L;
/**
* 父亲ID
*/
private long fId;
/**
* 父亲姓名
*/
private String fName;
/**
* 该父亲的儿子们
*/
private List<Son> sons;
}
com.lihaozhe.mapper.SonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Son;
import com.lihaozhe.vo.SonVo;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 上午11:08
*/
public interface SonMapper {
/**
* 根据父亲ID获取该父亲的儿子列表
* @param fid
* @return
*/
List<Son> selectAllByFId(@Param("fid") long fid);
}
com.lihaozhe.mapper.FatherMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Father;
import com.lihaozhe.vo.FatherVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 上午11:15
*/
public interface FatherMapper {
/**
* 根据父亲ID获取父亲及其儿子们的信息
*
* @param fid
* @return
*/
FatherVo selectFatherVoById(@Param("fid") long fid);
}
src/main/resources/com/lihaozhe/mapper/SonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.SonMapper">
<select id="selectAllByFId" resultType="son">
select *
from son
where f_id = #{fid};
select>
mapper>
src/main/resources/com/lihaozhe/mapper/FatherMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.FatherMapper">
<resultMap id="FatherVoMap" type="fatherVo">
<id property="fId" column="f_id"/>
<result property="fName" column="f_name"/>
<collection property="sons" ofType="son" column="f_id" select="com.lihaozhe.mapper.SonMapper.selectAllByFId"/>
resultMap>
<select id="selectFatherVoById" resultMap="FatherVoMap">
select *
from father
where f_id = #{fid};
select>
mapper>
com.lihaozhe.mapper.SonMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Son;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.SonVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 上午11:33
*/
public class SonMapperTest {
@Test
public void selectAllByFId(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
SonMapper mapper = sqlSession.getMapper(SonMapper.class);
List<Son> sons = mapper.selectAllByFId(1L);
MyBatisUtil.close();
sons.forEach(System.out::println);
}
}
com.lihaozhe.mapper.FatherMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Father;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.FatherVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 上午11:22
*/
public class FatherMapperTest {
@Test
public void selectFatherVoById(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
FatherMapper mapper = sqlSession.getMapper(FatherMapper.class);
FatherVo fatherVo = mapper.selectFatherVoById(1L);
MyBatisUtil.close();
System.out.println(fatherVo);
}
}
解析SQL
==> Preparing: SELECT f_id, f_name FROM father WHERE f_id = ?
==> Parameters: 1(Long)
<== Columns: f_id, f_name
<== Row: 1, 李靖
====> Preparing: SELECT s_id, s_name,f_id FROM son WHERE f_id = ?
====> Parameters: 1(Integer)
<==== Columns: s_id, s_name, f_id
<==== Row: 1, 李金吒, 1
<==== Row: 2, 李木吒, 1
<==== Row: 3, 李哪吒, 1
<==== Total: 3
<== Total: 1
com.lihaozhe.mapper.FatherMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Father;
import com.lihaozhe.vo.FatherVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 下午3:49
*/
public interface FatherMapper {
/**
* 根据父亲ID获取父亲及其儿子们的信息
*
* @param fid
* @return
*/
FatherVo selectFatherVoBySid(@Param("fid") long fid);
}
src/main/resources/com/lihaozhe/mapper/FatherMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.FatherMapper">
<resultMap id="FatherVoMapper" type="fatherVo">
<id property="fId" column="fid"/>
<result property="fName" column="f_name"/>
<collection property="sons" ofType="son">
<id property="sId" column="s_id"/>
<result property="sName" column="s_name"/>
<result property="fId" column="fid"/>
collection>
resultMap>
<select id="selectFatherVoBySid" resultMap="FatherVoMapper">
select f.f_id as fid, f_name, s_id, s_name
from father f
inner join son s on f.f_id = s.f_id and f.f_id = #{fid}
select>
mapper>
com.lihaozhe.mapper.FatherMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Father;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.FatherVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/10 下午3:52
*/
public class FatherMapperTest {
@Test
public void selectFatherVoBySid(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
FatherMapper mapper = sqlSession.getMapper(FatherMapper.class);
FatherVo fatherVo = mapper.selectFatherVoBySid(1L);
MyBatisUtil.close();
System.out.println(fatherVo);
}
}
- 直接多对多
- 间接多对多 将多对多拆成两个一对多 或 两个多对一
需求:查找某图书类目下的所有图书信息
com.lihaozhe.vo.CategoryVo
package com.lihaozhe.vo;
import com.lihaozhe.pojo.Book;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 上午11:27
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CategoryVo implements Serializable {
private static final long serialVersionUID = 5565769402064534797L;
/**
* 分类ID
*/
private long cid;
/**
* 分类名称
*/
private String cname;
/**
* 某分类的图书列表
*/
private List<Book> books;
}
com.lihaozhe.mapper.CategoryMapper
package com.lihaozhe.mapper;
import com.lihaozhe.vo.CategoryVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 上午11:28
*/
public interface CategoryMapper {
/**
* 根据分类ID获取分类及其分类下的图书列表
*
* @param cid
* @return
*/
CategoryVo selectCategoryVoByCid(@Param("cid") long cid);
}
src/main/resources/com/lihaozhe/mapper/CategoryMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.CategoryMapper">
<resultMap id="CategoryVoMap" type="categoryVo">
<id property="cid" column="cid"/>
<id property="cname" column="cname"/>
<collection property="books" ofType="book">
<id property="bid" column="bid"/>
<result property="bname" column="bname"/>
collection>
resultMap>
<select id="selectCategoryVoByCid" resultMap="CategoryVoMap">
select cid, cname, bid, bname
from category
inner join book_category
inner join book
on cid = m_cid and bid = m_bid and cid = #{cid}
select>
mapper>
com.lihaozhe.mapper.CategoryMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.CategoryVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 上午11:34
*/
public class CategoryMapperTest {
@Test
public void selectCategoryVoByCid(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
CategoryMapper mapper = sqlSession.getMapper(CategoryMapper.class);
CategoryVo categoryVo = mapper.selectCategoryVoByCid(3L);
MyBatisUtil.close();
System.out.println(categoryVo);
}
}
需求:查找某图书的分类信息
com.lihaozhe.vo.BookVo
package com.lihaozhe.vo;
import com.lihaozhe.pojo.Category;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 上午11:36
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class BookVo implements Serializable {
private static final long serialVersionUID = 6785352134653400094L;
/**
* 书的ID
*/
private long bid;
/**
* 书名
*/
private String bname;
/**
* 某图书的分类信息列表
*/
private List<Category> categories;
}
com.lihaozhe.mapper.BookMapper
package com.lihaozhe.mapper;
import com.lihaozhe.vo.BookVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 上午11:38
*/
public interface BookMapper {
/**
* 根据图书ID查询图书信息包括该图书的分类信息
*
* @param bid
* @return
*/
BookVo selectBookVoByBid(@Param("bid") long bid);
}
src/main/resources/com/lihaozhe/mapper/BookMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.BookMapper">
<resultMap id="BookVoMap" type="bookVo">
<id property="bid" column="bid"/>
<result property="bname" column="bname"/>
<collection property="categories" ofType="category">
<id property="cid" column="cid"/>
<id property="cname" column="cname"/>
collection>
resultMap>
<select id="selectBookVoByBid" resultMap="BookVoMap">
select bid, bname, cid, cname
from book
inner join book_category
inner join category
on bid = m_bid and cid = m_cid and bid = #{bid}
select>
mapper>
package com.lihaozhe.mapper;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.BookVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 上午11:34
*/
public class BookMapperTest {
@Test
public void test(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
BookMapper mapper = sqlSession.getMapper(BookMapper.class);
BookVo bookVo = mapper.selectBookVoByBid(3L);
MyBatisUtil.close();
System.out.println(bookVo);
}
}
com.lihaozhe.pojo.StudentCourse
package com.lihaozhe.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class StudentCourse implements Serializable {
private static final long serialVersionUID = 7294808647412902387L;
/**
* 学生ID
*/
private long sId;
/**
* 课程ID
*/
private long cId;
/**
* 学生信息
*/
private Student student;
/**
* 课程信息
*/
private Course course;
}
com.lihaozhe.mapper.CourseMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Course;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/11 下午3:04
*/
public interface CourseMapper {
/**
* 根据课程ID查找课程
*
* @param cid
* @return
*/
Course selectCourseByCid(@Param("cid") long cid);
}
src/main/resources/com/lihaozhe/mapper/CourseMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.CourseMapper">
<select id="selectCourseByCid" resultType="course">
SELECT *
FROM `course`
WHERE `c_id` = #{cid}
select>
mapper>
com.lihaozhe.mapper.CourseMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Course;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/11 下午3:06
*/
public class CourseMapperTest {
@Test
public void selectCourseByCid(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);
Course course = mapper.selectCourseByCid(3L);
MyBatisUtil.close();
System.out.println(course);
}
}
com.lihaozhe.mapper.StudentMapper
package com.lihaozhe.mapper;
import com.lihaozhe.vo.StudentVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/11 下午3:08
*/
public interface StudentMapper {
/**
* 根据学生ID 查询学生信息 包含所需课程的ID列表
*
* @param sid
* @return
*/
StudentVo selectStudentVoBySid(@Param("sid") long sid);
}
src/main/resources/com/lihaozhe/mapper/StudentMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.StudentMapper">
<resultMap id="StudentVoMap" type="studentVo">
<id property="sId" column="sid"/>
<result property="sName" column="s_name"/>
<collection property="studentCourses" ofType="studentCourse">
<result property="sId" column="sid"/>
<result property="cId" column="c_id"/>
<association property="course" column="c_id" select="com.lihaozhe.mapper.CourseMapper.selectCourseByCid"/>
collection>
resultMap>
<select id="selectStudentVoBySid" resultMap="StudentVoMap">
select stu.s_id as sid, s_name, c_id
from student as stu
inner join student_course sc on stu.s_id = sc.s_id and stu.s_id = #{sid}
select>
mapper>
com.lihaozhe.mapper.StudentMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.StudentVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/11 下午3:23
*/
public class StudentMapperTest {
@Test
public void selectStudentVoBySid() {
SqlSession sqlSession = MyBatisUtil.openSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
StudentVo studentVo = mapper.selectStudentVoBySid(3L);
System.out.println(studentVo);
System.out.println(studentVo.getSName());
studentVo.getStudentCourses().forEach(studentCourse -> System.out.println(studentCourse.getCourse()));
}
}
==> Preparing: SELECT s.s_id, s_name, c_id FROM `student` s INNER JOIN `student_course` sc ON s.s_id = sc.s_id AND s.s_id = ?
==> Parameters: 1(Long)
<== Columns: s_id, s_name, c_id
<== Row: 1, stu01, 1
====> Preparing: SELECT * FROM `course` WHERE `c_id` = ?
====> Parameters: 1(Integer)
<==== Columns: c_id, c_name
<==== Row: 1, java
<==== Total: 1
<== Row: 1, stu01, 2
====> Preparing: SELECT * FROM `course` WHERE `c_id` = ?
====> Parameters: 2(Integer)
<==== Columns: c_id, c_name
<==== Row: 2, scala
<==== Total: 1
<== Total: 2
com.lihaozhe.mapper.StudentMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Student;
import com.lihaozhe.vo.StudentVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/11 下午3:08
*/
public interface StudentMapper {
/**
* 根据学生ID 查询学生信息 包含所需课程的ID列表
*
* @param sid
* @return
*/
StudentVo selectStudentVoBySid(@Param("sid") long sid);
/**
* 根据学生ID 查询学生信息
*
* @param sid
* @return
*/
Student selectStudentBySid(@Param("sid") long sid);
}
src/main/resources/com/lihaozhe/mapper/StudentMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.StudentMapper">
<resultMap id="StudentVoMap" type="studentVo">
<id property="sId" column="sid"/>
<result property="sName" column="s_name"/>
<collection property="studentCourses" ofType="studentCourse">
<result property="sId" column="sid"/>
<result property="cId" column="c_id"/>
<association property="course" column="c_id" select="com.lihaozhe.mapper.CourseMapper.selectCourseByCid"/>
collection>
resultMap>
<select id="selectStudentVoBySid" resultMap="StudentVoMap">
select stu.s_id as sid, s_name, c_id
from student as stu
inner join student_course sc on stu.s_id = sc.s_id and stu.s_id = #{sid}
select>
<select id="selectStudentBySid" resultType="student">
SELECT * FROM `student` WHERE `s_id` = #{sid}
select>
mapper>
com.lihaozhe.mapper.StudentMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Student;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.StudentVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/11 下午3:23
*/
public class StudentMapperTest {
@Test
public void selectStudentVoBySid() {
SqlSession sqlSession = MyBatisUtil.openSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
StudentVo studentVo = mapper.selectStudentVoBySid(3L);
System.out.println(studentVo);
System.out.println(studentVo.getSName());
studentVo.getStudentCourses().forEach(studentCourse -> System.out.println(studentCourse.getCourse()));
}
@Test
public void selectStudentBySid() {
SqlSession sqlSession = MyBatisUtil.openSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
Student student = mapper.selectStudentBySid(3L);
System.out.println(student);
}
}
com.lihaozhe.vo.CourseVo
package com.lihaozhe.vo;
import com.lihaozhe.pojo.StudentCourse;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/14 下午12:22
*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CourseVo implements Serializable {
private static final long serialVersionUID = -2649136027724661116L;
/**
* 课程ID
*/
private long cId;
/**
* 课程名称
*/
private String cName;
/**
* 课程关联信息
*/
private List<StudentCourse> studentCourses;
}
com.lihaozhe.mapper.CourseMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Course;
import com.lihaozhe.vo.CourseVo;
import org.apache.ibatis.annotations.Param;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/11 下午3:04
*/
public interface CourseMapper {
/**
* 根据课程ID查找课程
*
* @param cid
* @return
*/
Course selectCourseByCid(@Param("cid") long cid);
/**
* 根据课程ID查找课程 包含所需课程的ID列表
*
* @param cid
* @return
*/
CourseVo selectCourseVoByCid(@Param("cid") long cid);
}
src/main/resources/com/lihaozhe/mapper/CourseMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.CourseMapper">
<select id="selectCourseByCid" resultType="course">
SELECT *
FROM `course`
WHERE `c_id` = #{cid}
select>
<resultMap id="CourseVoMap" type="courseVo">
<id property="cId" column="cid"/>
<result property="cName" column="c_name"/>
<collection property="studentCourses" ofType="studentCourse">
<result property="sId" column="sid"/>
<result property="cId" column="c_id"/>
<association property="student" column="s_id" select="com.lihaozhe.mapper.StudentMapper.selectStudentBySid"/>
collection>
resultMap>
<select id="selectCourseVoByCid" resultMap="CourseVoMap">
select c.c_id as cid, c_name, s_id
from course as c
inner join student_course sc on c.c_id = sc.c_id and c.c_id = #{cid}
select>
mapper>
com.lihaozhe.mapper.CourseMapperTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Course;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import com.lihaozhe.vo.CourseVo;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/11 下午3:06
*/
public class CourseMapperTest {
@Test
public void selectCourseByCid(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);
Course course = mapper.selectCourseByCid(3L);
MyBatisUtil.close();
System.out.println(course);
}
@Test
public void selectCourseVoByCid(){
SqlSession sqlSession = MyBatisUtil.openSqlSession();
CourseMapper mapper = sqlSession.getMapper(CourseMapper.class);
CourseVo courseVo = mapper.selectCourseVoByCid(3L);
System.out.println(courseVo);
System.out.println(courseVo.getCName());
courseVo.getStudentCourses().forEach(studentCourse -> System.out.println(studentCourse.getStudent()));
}
}
@Test
public void selectStudentVoBySid01() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
StudentVo studentVo = mapper.selectStudentVoBySid(1L);
MyBatisUtil.close();
System.out.println(studentVo.getSName());
}
Opening JDBC Connection
Created connection 379121284.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
==> Preparing: SELECT s.s_id, s_name, c_id FROM `student` s INNER JOIN `student_course` sc ON s.s_id = sc.s_id AND s.s_id = ?
==> Parameters: 1(Long)
<== Columns: s_id, s_name, c_id
<== Row: 1, stu01, 1
====> Preparing: SELECT * FROM `course` WHERE `c_id` = ?
====> Parameters: 1(Integer)
<==== Columns: c_id, c_name
<==== Row: 1, java
<==== Total: 1
<== Row: 1, stu01, 2
====> Preparing: SELECT * FROM `course` WHERE `c_id` = ?
====> Parameters: 2(Integer)
<==== Columns: c_id, c_name
<==== Row: 2, scala
<==== Total: 1
<== Total: 2
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
Returned connection 379121284 to pool.
@Test
public void selectStudentVoBySid02() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
StudentVo studentVo = mapper.selectStudentVoBySid(1L);
MyBatisUtil.close();
studentVo.getStudentCourses().forEach(studentCourse -> System.out.println(studentCourse.getCourse()));
}
Opening JDBC Connection
Created connection 379121284.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
==> Preparing: SELECT s.s_id, s_name, c_id FROM `student` s INNER JOIN `student_course` sc ON s.s_id = sc.s_id AND s.s_id = ?
==> Parameters: 1(Long)
<== Columns: s_id, s_name, c_id
<== Row: 1, stu01, 1
====> Preparing: SELECT * FROM `course` WHERE `c_id` = ?
====> Parameters: 1(Integer)
<==== Columns: c_id, c_name
<==== Row: 1, java
<==== Total: 1
<== Row: 1, stu01, 2
====> Preparing: SELECT * FROM `course` WHERE `c_id` = ?
====> Parameters: 2(Integer)
<==== Columns: c_id, c_name
<==== Row: 2, scala
<==== Total: 1
<== Total: 2
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
Returned connection 379121284 to pool.
Course(cId=1, cName=java)
Course(cId=2, cName=scala)
Process finished with exit code 0
从上面第一个案例可以看出客户只想查看学生休息并不想看学生所学专业信息 但是 仍然执行了子查询,
我们希望 当想看该学生和该学生所学专业详细信息的之后才走子查询而只看学生信息的时候不走子查询
于是我们开启了延迟加载
<setting name="lazyLoadingEnabled" value="true"/>
@Test
public void selectStudentVoBySid01() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
StudentVo studentVo = mapper.selectStudentVoBySid(1L);
MyBatisUtil.close();
System.out.println(studentVo.getSName());
}
Opening JDBC Connection
Created connection 379121284.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
==> Preparing: SELECT s.s_id, s_name, c_id FROM `student` s INNER JOIN `student_course` sc ON s.s_id = sc.s_id AND s.s_id = ?
==> Parameters: 1(Long)
<== Columns: s_id, s_name, c_id
<== Row: 1, stu01, 1
<== Row: 1, stu01, 2
<== Total: 2
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1698ee84]
Returned connection 379121284 to pool.
@Test
public void selectStudentVoBySid02() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
StudentVo studentVo = mapper.selectStudentVoBySid(1L);
MyBatisUtil.close();
studentVo.getStudentCourses().forEach(studentCourse -> System.out.println(studentCourse.getCourse()));
}
Opening JDBC Connection
Created connection 544966217.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
==> Preparing: SELECT s.s_id, s_name, c_id FROM `student` s INNER JOIN `student_course` sc ON s.s_id = sc.s_id AND s.s_id = ?
==> Parameters: 1(Long)
<== Columns: s_id, s_name, c_id
<== Row: 1, stu01, 1
<== Row: 1, stu01, 2
<== Total: 2
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
Returned connection 544966217 to pool.
Opening JDBC Connection
Checked out connection 544966217 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
==> Preparing: SELECT * FROM `course` WHERE `c_id` = ?
==> Parameters: 1(Integer)
<== Columns: c_id, c_name
<== Row: 1, java
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
Returned connection 544966217 to pool.
Course(cId=1, cName=java)
Opening JDBC Connection
Checked out connection 544966217 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
==> Preparing: SELECT * FROM `course` WHERE `c_id` = ?
==> Parameters: 2(Integer)
<== Columns: c_id, c_name
<== Row: 2, scala
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@207b8649]
Returned connection 544966217 to pool.
Course(cId=2, cName=scala)
Process finished with exit code 0
侵入式延迟 访问主对象及主对象里面的属性时,不光会加载主对象(即从数据库中查询主对象的信息),还会一同加载关联对象。 积极加载
深度延迟 访问主对象属性时,只加载主,只有当访问关联对象的属性时,才会去加载关联对象。 按需加载
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="lazyLoadingEnabled" value="true"/>
settings>
映射配置文件中子查询设置fetchType
fetchType=“eager” 不支持懒加载
fetchType=“lzsy” 支持懒加载
@Test
public void selectDeptVoById01() {
// 获取接口代理对象
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
// 执行代理对象中方法
mapper.selectDeptVoById(3L);
// 释放资源
sqlSession.close();
}
@Test
public void selectDeptVoById02() {
// 获取接口代理对象
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
// 执行代理对象中方法
DeptVo deptVo = mapper.selectDeptVoById(3L);
// 释放资源
sqlSession.close();
System.out.println(deptVo.getDname());
}
@Test
public void selectDeptVoById03() {
// 获取接口代理对象
DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
// 执行代理对象中方法
DeptVo deptVo = mapper.selectDeptVoById(3L);
// 释放资源
sqlSession.close();
deptVo.getEmps();
}
com.lihaozhe.mapper.CacheTest
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/12 上午10:05
*/
public class CacheTest {
@Test
public void testCache01(){
SqlSession sqlSession = MyBatisUtil.getSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person01 = mapper.selectById(3L);
Person person02 = mapper.selectById(3L);
MyBatisUtil.close();
}
}
Opening JDBC Connection
Created connection 1552870927.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5ee0074d47064285b8c5925534d70d84, 17674856547, 令狐荡, 649152199504171242
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Returned connection 1552870927 to pool.
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/12 上午10:05
*/
public class CacheTest {
@Test
public void testCache02() {
SqlSession sqlSession = MyBatisUtil.openSqlSession();
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
Person person01 = mapper.selectById(6L);
Person person02 = mapper.selectById(3L);
MyBatisUtil.close();
}0
}
Opening JDBC Connection
Created connection 1552870927.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 6(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 6, aebe1bd701b24fb89347c78bb3aaf938, 13651227685, 欧阳脓, 644102199803081660
<== Total: 1
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5ee0074d47064285b8c5925534d70d84, 17674856547, 令狐荡, 649152199504171242
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Returned connection 1552870927 to pool.
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/12 上午10:05
*/
public class CacheTest {
@Test
public void testCache03() {
SqlSession sqlSession = MyBatisUtil.openSqlSession();
PersonMapper mapper01 = sqlSession.getMapper(PersonMapper.class);
PersonMapper mapper02 = sqlSession.getMapper(PersonMapper.class);
Person person01 = mapper01.selectById(3L);
Person person02 = mapper02.selectById(3L);
MyBatisUtil.close();
}
}
Opening JDBC Connection
Created connection 1552870927.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5ee0074d47064285b8c5925534d70d84, 17674856547, 令狐荡, 649152199504171242
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Returned connection 1552870927 to pool.
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/12 上午10:05
*/
public class CacheTest {
@Test
public void testCache04() {
SqlSession sqlSession01 = MyBatisUtil.getSqlSession();
PersonMapper mapper01 = sqlSession01.getMapper(PersonMapper.class);
Person person01 = mapper01.selectById(3L);
SqlSession sqlSession02 = MyBatisUtil.getSqlSession();
PersonMapper mapper02 = sqlSession02.getMapper(PersonMapper.class);
Person person02 = mapper02.selectById(3L);
MyBatisUtil.close();
}
}
Opening JDBC Connection
Created connection 1552870927.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5ee0074d47064285b8c5925534d70d84, 17674856547, 令狐荡, 649152199504171242
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Returned connection 1552870927 to pool.
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/12 上午10:05
*/
public class CacheTest {
@Test
public void testCache05() {
SqlSession sqlSession01 = MyBatisUtil.getSqlSession();
PersonMapper mapper01 = sqlSession01.getMapper(PersonMapper.class);
Person person01 = mapper01.selectById(3L);
MyBatisUtil.close();
SqlSession sqlSession02 = MyBatisUtil.getSqlSession();
PersonMapper mapper02 = sqlSession02.getMapper(PersonMapper.class);
Person person02 = mapper02.selectById(3L);
MyBatisUtil.close();
}
}
Opening JDBC Connection
Created connection 1552870927.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5ee0074d47064285b8c5925534d70d84, 17674856547, 令狐荡, 649152199504171242
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Returned connection 1552870927 to pool.
Opening JDBC Connection
Checked out connection 1552870927 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5ee0074d47064285b8c5925534d70d84, 17674856547, 令狐荡, 649152199504171242
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@5c8eee0f]
Returned connection 1552870927 to pool.
MyBatis如果想跨SqlSession缓存则可以采用将查询结果缓存至第三方,例如:
- ehcache
- memcached
- redis
maven项目提前在pom.xml文件中增加相关依赖
<settings>
<setting name="cacheEnabled" value="true" />
settings>
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
缓存遇到commit失效
ehcache二级缓存在映射配置文件中加入
<cache type="org.mybatis.caches.ehcache.LoggingEhcache" />
<cache type="org.mybatis.caches.ehcache.EhcacheCache"/>
<dependency>
<groupId>org.ehcachegroupId>
<artifactId>ehcacheartifactId>
<version>3.9.9version>
dependency>
<dependency>
<groupId>org.mybatis.cachesgroupId>
<artifactId>mybatis-ehcacheartifactId>
<version>1.2.2version>
dependency>
<settings>
<setting name="cacheEnabled" value="true" />
settings>
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
添加以下内容
<cache eviction="FIFO" flushInterval="60000" size="512" readOnly="true" />
在需要缓存的查找标签增加设置useCache=true
<select id="selectById" resultType="person" useCache="true">
<include refid="select_person">include>
<where>
`id` = #{id}
where>
select>
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/12 上午10:05
*/
public class CacheTest {
@Test
public void testCache05() {
SqlSession sqlSession01 = MyBatisUtil.openSqlSession();
PersonMapper mapper01 = sqlSession01.getMapper(PersonMapper.class);
Person person01 = mapper01.selectById(3L);
MyBatisUtil.close();
SqlSession sqlSession02 = MyBatisUtil.openSqlSession();
PersonMapper mapper02 = sqlSession02.getMapper(PersonMapper.class);
Person person02 = mapper02.selectById(3L);
MyBatisUtil.close();
}
}
Cache Hit Ratio [com.lihaozhe.mapper.PersonMapper]: 0.0
Opening JDBC Connection
Created connection 1045731788.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5ee0074d47064285b8c5925534d70d84, 17674856547, 令狐荡, 649152199504171242
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
Returned connection 1045731788 to pool.
Cache Hit Ratio [com.lihaozhe.mapper.PersonMapper]: 0.5
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
import org.apache.ibatis.session.SqlSession;
import org.junit.jupiter.api.Test;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/12 上午10:05
*/
public class CacheTest {
@Test
public void testCache05() {
SqlSession sqlSession01 = MyBatisUtil.openSqlSession();
PersonMapper mapper01 = sqlSession01.getMapper(PersonMapper.class);
Person person01 = mapper01.selectById(3L);
MyBatisUtil.close();
SqlSession sqlSession02 = MyBatisUtil.openSqlSession();
PersonMapper mapper02 = sqlSession02.getMapper(PersonMapper.class);
Person person02 = mapper02.selectById(3L);
MyBatisUtil.close();
}
}
Cache Hit Ratio [com.lihaozhe.mapper.PersonMapper]: 0.0
Opening JDBC Connection
Created connection 1045731788.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 6(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 6, aebe1bd701b24fb89347c78bb3aaf938, 13651227685, 欧阳脓, 644102199803081660
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
Returned connection 1045731788 to pool.
Cache Hit Ratio [com.lihaozhe.mapper.PersonMapper]: 0.0
Opening JDBC Connection
Checked out connection 1045731788 from pool.
Setting autocommit to false on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
==> Preparing: SELECT `id`, `uuid`, `mobile`, `nickname`, `id_card` FROM `person` WHERE `id` = ?
==> Parameters: 3(Long)
<== Columns: id, uuid, mobile, nickname, id_card
<== Row: 3, 5ee0074d47064285b8c5925534d70d84, 17674856547, 令狐荡, 649152199504171242
<== Total: 1
Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
Closing JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@3e5499cc]
Returned connection 1045731788 to pool.
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.3.1version>
dependency>
<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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0modelVersion>
<groupId>com.lihaozhegroupId>
<artifactId>mybatisartifactId>
<version>1.0-SNAPSHOTversion>
<name>mybatisname>
<packaging>jarpackaging>
<properties>
<jdk.version>17jdk.version>
<maven.compiler.source>17maven.compiler.source>
<maven.compiler.target>17maven.compiler.target>
<maven.compiler.compilerVersion>17maven.compiler.compilerVersion>
<maven.compiler.encoding>utf-8maven.compiler.encoding>
<project.build.sourceEncoding>utf-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<maven.test.failure.ignore>truemaven.test.failure.ignore>
<maven.test.skip>truemaven.test.skip>
<junit.version>5.8.2junit.version>
<fastjson.version>2.0.6fastjson.version>
<gson.version>2.9.0gson.version>
<hutool.version>5.8.0.M3hutool.version>
<jackson.version>2.13.3jackson.version>
<lombok.version>1.18.24lombok.version>
<java-testdata.version>1.1.2java-testdata.version>
properties>
<dependencies>
<dependency>
<groupId>org.junit.jupitergroupId>
<artifactId>junit-jupiter-apiartifactId>
<version>${junit.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>com.github.binarywanggroupId>
<artifactId>java-testdata-generatorartifactId>
<version>${java-testdata.version}version>
dependency>
<dependency>
<groupId>org.apache.commonsgroupId>
<artifactId>commons-lang3artifactId>
<version>3.8.1version>
dependency>
<dependency>
<groupId>commons-iogroupId>
<artifactId>commons-ioartifactId>
<version>2.11.0version>
dependency>
<dependency>
<groupId>org.junit.jupitergroupId>
<artifactId>junit-jupiter-engineartifactId>
<version>${junit.version}version>
<scope>testscope>
dependency>
<dependency>
<groupId>cn.hutoolgroupId>
<artifactId>hutool-allartifactId>
<version>${hutool.version}version>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>${lombok.version}version>
<scope>providedscope>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>fastjsonartifactId>
<version>${fastjson.version}version>
dependency>
<dependency>
<groupId>com.google.code.gsongroupId>
<artifactId>gsonartifactId>
<version>${gson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-coreartifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-annotationsartifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.coregroupId>
<artifactId>jackson-databindartifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatypegroupId>
<artifactId>jackson-datatype-jsr310artifactId>
<version>${jackson.version}version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.29version>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.10version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>1.2.8version>
dependency>
<dependency>
<groupId>org.ehcachegroupId>
<artifactId>ehcacheartifactId>
<version>3.9.9version>
dependency>
<dependency>
<groupId>org.mybatis.cachesgroupId>
<artifactId>mybatis-ehcacheartifactId>
<version>1.2.2version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.3.1version>
dependency>
<dependency>
<groupId>org.springframeworkgroupId>
<artifactId>spring-contextartifactId>
<version>5.3.20version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-war-pluginartifactId>
<version>3.3.2version>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<version>3.8.1version>
<configuration>
<encoding>UTF-8encoding>
<source>${jdk.version}source>
<target>${jdk.version}target>
configuration>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-clean-pluginartifactId>
<version>3.2.0version>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-resources-pluginartifactId>
<version>3.2.0version>
plugin>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-surefire-pluginartifactId>
<version>2.22.2version>
<configuration>
<skip>trueskip>
configuration>
plugin>
plugins>
build>
project>
追加以下内容
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"/>
<property name="pageSizeZero" value="true"/>
<property name="reasonable" value="true" />
plugin>
plugins>
1. helperDialect :分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置 helperDialect 属性来指定分页插件使用哪种方言。配置时,可以使用下面的缩写值:oracle , mysql , mariadb , sqlite , hsqldb , postgresql , db2 , sqlserver , informix , h2 , sqlserver2012 , derby 特别注意:使用 SqlServer2012 数据库时,需要手动指定为 sqlserver2012 ,否则会使用 SqlServer2005 的方式进行分页。 你也可以实现 AbstractHelperDialect ,然后配置该属性为实现类的全限定名称即可使用自定义的实现方法。 2. offsetAsPageNum :默认值为 false ,该参数对使用 RowBounds 作为分页参数时有效。 当该参数设置为 true 时,会将 RowBounds 中的 offset 参数当成 pageNum 使用,可以用页码和页面大小两个参数进行分页。 3. rowBoundsWithCount :默认值为 false ,该参数对使用 RowBounds 作为分页参数时有效。当该参数设置为 true 时,使用 RowBounds 分页会进行 count 查询。 4. pageSizeZero :默认值为 false ,当该参数设置为 true 时,如果 pageSize=0 或者 RowBounds.limit = 0 就会查询出全部的结果(相当于没有执行分页查询,但是返回结果仍然是 Page 类型)。 5. reasonable :分页合理化参数,默认值为 false 。当该参数设置为 true 时, pageNum<=0 时会查询第一页, pageNum>pages (超过总数时),会查询最后一页。默认 false 时,直接根据参数进行查询。 6. params :为了支持 startPage(Object params) 方法,增加了该参数来配置参数映射,用于从对象中根据属性名取值, 可以配置 pageNum,pageSize,count,pageSizeZero,reasonable ,不配置映射的用默认值, 默认值为 pageNum=pageNum;pageSize=pageSize;count=countSql;reasonable=reasonable;pageSizeZero= pageSizeZero 。 7. supportMethodsArguments :支持通过 Mapper 接口参数来传递分页参数,默认值 false ,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest 。 8. autoRuntimeDialect :默认值为 false 。设置为 true 时,允许在运行时根据多数据源自动识别对应方言的分页 (不支持自动选择 sqlserver2012 ,只能使用 sqlserver ),用法和注意事项参考下面的场景五。 9. closeConn :默认值为 true 。当使用运行时动态数据源或没有设置 helperDialect 属性自动获取数据库类型时,会自动获取一个数据库连接, 通过该属性来设置是否关闭获取的这个连接,默认 true 关闭,设置为 false 后,不会关闭获取的连接,这个参数的设置要根据自己选择的数据源来决定。
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="config.properties"/>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
<setting name="cacheEnabled" value="true"/>
settings>
<typeAliases>
<package name="com.lihaozhe.pojo"/>
<package name="com.lihaozhe.vo"/>
typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"/>
<property name="pageSizeZero" value="true"/>
<property name="reasonable" value="true"/>
plugin>
plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<package name="com.lihaozhe.mapper"/>
mappers>
configuration>
com.lihaozhe.mapper.PersonMapper
package com.lihaozhe.mapper;
import com.lihaozhe.pojo.Person;
import org.apache.ibatis.annotations.Param;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:47
*/
public interface PersonMapper {
/**
* 分页查询
* @param person
* @return
*/
List<Person> select4page(@Param("person") Person person);
}
src/main/resources/com/lihaozhe/mapper/PersonMapper.xml
DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.lihaozhe.mapper.PersonMapper">
<select id="select4page" resultType="person">
SELECT *
FROM `person`
<trim prefix="where" prefixOverrides="AND|OR">
<if test="person.mobile != null and person.mobile.length > 0 and person.mobile.length < 12">
<bind name="like_mobile" value="'%'+ person.mobile +'%'"/>
AND `mobile` LIKE #{like_mobile}
if>
<if test="person.mobile != null and person.mobile.length > 0 and person.mobile.length < 12">
<bind name="like_nickname" value="'%'+ person.nickname +'%'"/>
AND `nickname` LIKE #{like_nickname}
if>
trim>
select>
mapper>
com.lihaozhe.mapper.PersonMapperTest
package com.lihaozhe.mapper;
import cn.binarywang.tools.generator.ChineseIDCardNumberGenerator;
import cn.binarywang.tools.generator.ChineseMobileNumberGenerator;
import cn.binarywang.tools.generator.ChineseNameGenerator;
import cn.hutool.core.util.IdUtil;
import com.alibaba.fastjson.JSONObject;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.lihaozhe.pojo.Person;
import com.lihaozhe.util.mybatis.MyBatisUtil;
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.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import java.io.IOException;
import java.io.Reader;
import java.util.ArrayList;
import java.util.List;
/**
* @author 李昊哲
* @version 1.0.0 2022/7/7 下午1:51
*/
public class PersonMapperTest {
private SqlSession sqlSession;
// JUnit5 @BeforeAll和@BeforeEach注解替换了 JUnit4 中的@Before注解。
// 它⽤于表⽰应在当前类中的每个@Test⽅法之前执⾏注解⽅法。
// 注意:@BeforeAll注解的⽅法必须为静态⽅法,否则它将引发运⾏时错误。
// 注意:@BeforeEach注解的⽅法不得为静态⽅法,否则它将引发运⾏时错误。
@BeforeEach
public void getSqlSession() throws IOException {
// 核心配置文件classpath路径
String resource = "mybatis/mybatis-config.xml";
// 加载配置文件
Reader reader = Resources.getResourceAsReader(resource);
// 构建会话工厂
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
// 从SqlSessionFactory对象中获取SqlSession
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void select4page(){
PersonMapper mapper = sqlSession.getMapper(PersonMapper.class);
// 在执行代理对象中查询方法之前 开启分页
PageHelper.startPage(10,5);
// 准备查询条件
Person person = new Person();
// 开启分页后 执行代理对象中的查询方法
List<Person> personList = mapper.select4page(person);
sqlSession.close();
PageInfo<Person> pageInfo = new PageInfo<>(personList);
System.out.println(pageInfo);
System.out.println(JSONObject.toJSONString(pageInfo));
System.out.println(JSONObject.toJSONString(pageInfo.getList()));
}
}
PageInfo类属性介绍
属性名 | 属性说明 |
---|---|
pageNum | 当前页 |
pageSize | 每页的数量 |
size | 当前页的数量 |
startRow | 由于startRow和endRow不常用,这里说个具体的用法 可以在页面中"显示startRow到endRow 共size条数据" 当前页面第一个元素在数据库中的行号 |
endRow | |
pages | 总页数 |
prePage | 前一页 |
nextPage | 下一页 |
isFirstPage | 是否为第一页 |
isLastPage | 是否为最后一页 |
hasPreviousPage | 是否有前一页 |
hasNextPage | 是否有下一页 |
navigatePages | 导航页码数 |
navigatepageNums | 所有导航页号 |
nnavigateFirstPage | 导航条上的第一页 |
navigateLastPage | 导航条上的最后一页 |
list | 数据集合 |
total | 总数量 |
DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<properties resource="config.properties"/>
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="lazyLoadingEnabled" value="true"/>
<setting name="aggressiveLazyLoading" value="false"/>
settings>
<typeAliases>
<package name="com.lihaozhe.pojo"/>
<package name="com.lihaozhe.vo"/>
typeAliases>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">
<property name="helperDialect" value="mysql"/>
<property name="pageSizeZero" value="true"/>
<property name="reasonable" value="true" />
plugin>
plugins>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
dataSource>
environment>
environments>
<mappers>
<package name="com.lihaozhe.mapper"/>
mappers>
configuration>