跳到主要内容

Mybatis 学习

MyBatis 基础​

主流的 ORM 框架,之前叫 iBatis, 后来改名 MyBatis

如果你使用的是 Spring MyBatis 而不是 Spring Boot,并希望自动将实体类生成数据库表(类似于 JPA 的自动表生成),MyBatis 本身并不支持这种功能。MyBatis 是一个 ORM 框架,用于映射 SQL 语句和 Java 对象,但它不会像 JPA 那样自动创建数据库表。

不能自动创建数据库表,不支持!

是的,MyBatis 本身只能使用已经存在的数据库和表结构,它不会像 JPA 或 Hibernate 那样自动生成数据库表结构。

可以 CRUD

MyBatis 入门​

1,配置 pom.xml

<dependencies>

<!-- MyBatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.16</version>
</dependency>

<!-- MySQL -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>

<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.34</version>
</dependency>

<!-- ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>

<!-- ehcache -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.0.0</version>
</dependency>

</dependencies>

<build>
<resources>
<resource>
<directory>src/main/resources</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
</resources>
</build>

2,创建实体类

package com.xs.entity;

import lombok.Data;

@Data
public class People {
private Integer id;
private String name;
private Double money;
}

3,配置 config.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置 MyBatis 运行 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatistest?useUnicode=true&amp;charset=UTF-8"/> <!-- 修改你自己的database 名称 -->
<property name="username" value="root"/>
<property name="password" value=""/>
</dataSource>
</environment>
</environments>

<mappers>
<!-- 修改为 resources 根目录的映射文件 -->
<mapper resource="mapper/PeopleMapper.xml"/> <!-- 这里的路径要与实际文件位置一致 -->
</mappers>

</configuration>

4,配置 resource/mapper/PeopleMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="PeopleMapper">
<select id="findById" parameterType="java.lang.Integer" resultType="com.xs.entity.People">
select * from people where id = #{id}
</select>
</mapper>

5,Mysql 里创建一个数据

6,main

package com.xs.test;

import com.xs.entity.People;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test {

public static void main(String[] args) {

// 加载 MyBatis 配置文件
InputStream inp = Test.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSFB = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlF = sqlSFB.build(inp);

// 获取 SqlSession
SqlSession sqlS = sqlF.openSession();
String statement = "PeopleMapper.findById"; // 匹配的 namespace 和 id
People people = sqlS.selectOne(statement,1);
System.out.println(people);
sqlS.close();

}

}

Mapper 代理实现自定义接口​

使用这个方式 , 比较熟悉

1,自定义 接口

package com.xs.repository;

import com.xs.entity.People;
import java.util.List;

public interface PeopleRepository {
public int save(People people);
public int deleteById(Integer id);
public int update(People people);
public People findById(Integer id);
public List<People> findAll();
// public People findById2(int id);
// public People findByIdAndName(int id, String name);
}

2,配置 resource/repository/PeopleRepository

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口的路径 -->
<mapper namespace="com.xs.repository.PeopleRepository">
<insert id="save" parameterType="com.xs.entity.People">
insert into people(name, money) values(#{name},#{money})
</insert>

<delete id="deleteById" parameterType="java.lang.Integer">
delete from people where id = #{id}
</delete>

<update id="update" parameterType="com.xs.entity.People">
update people set name = #{name}, money = #{money} where id = #{id}
</update>

<select id="findById" parameterType="java.lang.Integer" resultType="com.xs.entity.People">
select * from people where id = #{id}
</select>

<select id="findAll" resultType="com.xs.entity.People">
select * from people
</select>

<!-- <select id="findById2" parameterType="int" resultType="com.xs.entity.People">-->
<!-- select * from people where id = #{num}-->
<!-- </select>-->

</mapper>

3,配置 config.xml

<mappers>
<!-- 修改为 resources 根目录的映射文件 -->
<mapper resource="repository/PeopleRepository.xml"/> <!-- xml的路径 -->
</mappers>

4,main

package com.xs.test;

import com.xs.entity.People;
import com.xs.repository.PeopleRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test2 {

public static void main(String[] args) {

// 加载 MyBatis 配置文件
InputStream inp = Test2.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSFB = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlF = sqlSFB.build(inp);

// 获取 SqlSession
SqlSession sqlS = sqlF.openSession();
PeopleRepository peopleRepository = sqlS.getMapper(PeopleRepository.class);

// add & save
// People p = new People();
// p.setName("July");
// p.setMoney(Double.parseDouble("657"));
// peopleRepository.save(p);

// update
// People p = peopleRepository.findById(2);
// p.setName("哈哈");
// p.setMoney(Double.parseDouble("111"));
// peopleRepository.update(p);

// findAll
// List<People> list = peopleRepository.findAll();
// for(People people:list){
// System.out.println(people);
// }

sqlS.commit(); // 不要忘记提交事务
sqlS.close();

}

}

实现 一 对 多 关系​

两个数据库 连接 自定义

1,Classes 和 Student

package com.xs.entity;

import lombok.Data;

import java.util.List;

@Data
public class Classes {
private Integer id;
private String name;
private List<Student> students; //不需要放在phpMyadmin
}
package com.xs.entity;

import lombok.Data;

@Data
public class Student {
private Integer id;
private String name;
private Classes cid;
}

2,创建 Student 接口

package com.xs.repository;

import com.xs.entity.Student;

public interface StudentRepository {
public Student findById(Integer id);
}

3,创建 Student xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口的路径 -->
<mapper namespace="com.xs.repository.StudentRepository">

<!-- 输出结果: Student(id=1, name=Hoo, cid=Classes(id=1, name=一班)) -->
<resultMap id="studentMap" type="com.xs.entity.Student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
<association property="cid" javaType="com.xs.entity.Classes">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
</association>
</resultMap>

<select id="findById" parameterType="java.lang.Integer" resultMap="studentMap">
select s.id sid,s.name sname,c.id cid,c.name cname from student s, classes c where s.id = #{id} and s.cid = c.id
</select>

</mapper>

4, 配置 config.xml

<mapper resource="repository/StudentRepository.xml"/> <!-- xml的路径 -->

5,main

package com.xs.test;

import com.xs.entity.Classes;
import com.xs.entity.People;
import com.xs.entity.Student;
import com.xs.repository.ClassesRepository;
import com.xs.repository.StudentRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test4 {

public static void main(String[] args) {
// 加载 MyBatis 配置文件
InputStream inp = Test.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSFB = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlF = sqlSFB.build(inp);

// 获取 SqlSession
SqlSession sqlS = sqlF.openSession();

// Student
// StudentRepository studentRepository = sqlS.getMapper(StudentRepository.class);
// Student student = studentRepository.findById(1);
// System.out.println(student);

// Classes
ClassesRepository classesRepository = sqlS.getMapper(ClassesRepository.class);
Classes classes = classesRepository.findById(1);
System.out.println(classes);

}

}

Classes

1,接口

package com.xs.repository;

import com.xs.entity.Classes;

public interface ClassesRepository {
public Classes findById(Integer id);
}

2,ClassesRepository.xml 配置 和 代码

<mapper resource="repository/ClassesRepository.xml"/> <!-- xml的路径 -->
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口的路径 -->
<mapper namespace="com.xs.repository.ClassesRepository">

<resultMap id="classesMap" type="com.xs.entity.Classes">
<id column="cid" property="id"/>
<result column="cname" property="name"/>
<collection property="students" ofType="com.xs.entity.Student">
<id column="sid" property="id"/>
<result column="sname" property="name"/>
</collection>
</resultMap>

<select id="findById" parameterType="java.lang.Integer" resultMap="classesMap">
select c.id cid,c.name cname,s.id sid,s.name sname from classes c, student s where c.id = #{id} and c.id = s.cid
</select>

</mapper>

MyBatis 逆向工程​

禁!自动生成已存在的表单在项目里​

1,配置 pom

<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.16</version>
</dependency>

<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.33</version>
</dependency>

<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.4.0</version>
</dependency>

2,创建 generatorConfig.xml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
<context id="MySqlContext" targetRuntime="MyBatis3">
<jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/testmybatis"
userId="root"
password=""/>
<javaModelGenerator targetPackage="com.xs.entity" targetProject="src/main/java"/>
<sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources"/>
<javaClientGenerator type="XMLMAPPER" targetPackage="com.xs.mapper" targetProject="src/main/java"/>

<table tableName="student" domainObjectName="Student"/>
<table tableName="people" domainObjectName="People"/>
<table tableName="classes" domainObjectName="Classes"/>
</context>
</generatorConfiguration>

配置 DTD​

3,下载 mybatis-generator-config_1_0.dtd 文件,在Setting -> Languages & Frameworks -> Schemas and DTDs 引入

URI 名称: http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd

URI 名称: http://mybatis.org/dtd/mybatis-3-config.dtd

mybatis-3-config.dtd  也一样要引入

4,创建 generator -> MyBatisGeneratorRunner.java 启动

package com.xs.generator;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.File;
import java.util.ArrayList;
import java.util.List;

public class MyBatisGeneratorRunner {
public static void main(String[] args) throws Exception {
List<String> warnings = new ArrayList<>();
boolean overwrite = true;
File configFile = new File("src/main/resources/generatorConfig.xml"); // 修改为您的配置文件路径
ConfigurationParser cp = new ConfigurationParser(warnings);
Configuration config = cp.parseConfiguration(configFile);
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
myBatisGenerator.generate(null);

// 输出生成的警告
for (String warning : warnings) {
System.out.println(warning);
}
}
}

MyBatis 延迟加载​

使用延迟加载(lazyLoadingEnabled=true)的好处在于,MyBatis 只会在需要时加载相关的数据,减少不必要的数据加载,优化性能。具体的好处包括:

  1. 提高性能:
    • 延迟加载意味着 MyBatis 只会在你真正使用关联对象时,才会去查询数据库。例如,一个 Student 对象有一个关联的 Classes 对象,只有在你调用 student.getClasses() 时,才会去加载 Classes 对象。这样可以减少不必要的查询,提升应用的性能。
  2. 减少内存占用:
    • 如果你有大量关联对象,但是并不需要立即访问它们,延迟加载可以避免一次性加载大量数据到内存中,节省内存消耗。
  3. 更高的灵活性:
    • 延迟加载让你可以按需加载关联的数据。如果某个场景下你不需要关联数据,MyBatis 不会去查询关联表。这给开发者更多控制,避免了数据库的过度查询。
  4. 提高响应速度:
    • 对于一些只需要部分数据的场景,延迟加载可以让你更快地获取初始数据,而不是一次性加载所有相关联的数据,从而减少初始查询时间,提高接口响应速度。

1,config.xml 配置

<configuration>

<!-- 延迟加载 -->
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
<setting name="lazyLoadingEnabled" value="true"/>
</settings>

2,创建 order 和 customer

package com.xs.entity;

import lombok.Data;

@Data
public class Order {
private Integer id;
private String name;
private Customer customer;
}
package com.xs.entity;

import lombok.Data;

import java.util.List;

@Data
public class Customer {
private Integer id;
private String name;
private List<Order> orders;
}

3,创建 repository

package com.xs.repository;

import com.xs.entity.Order;

public interface OrderRepository {
public Order findById(Integer id);
}
package com.xs.repository;

import com.xs.entity.Customer;

public interface CustomerRepository {
public Customer findById(Integer id);
}

4,repository.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口的路径 -->
<mapper namespace="com.xs.repository.OrderRepository">

<resultMap id="orderMap" type="com.xs.entity.Order">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="customer" javaType="com.xs.entity.Customer" select="com.xs.repository.CustomerRepository.findById" column="cid"/>
</resultMap>

<select id="findById" parameterType="java.lang.Integer" resultMap="orderMap">
SELECT * FROM `order` WHERE id = #{id}
</select>

</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口的路径 -->
<mapper namespace="com.xs.repository.CustomerRepository">

<resultMap id="orderMap" type="com.xs.entity.Order">
<id column="id" property="id"/>
<result column="name" property="name"/>
<association property="customer" javaType="com.xs.entity.Customer" select="com.xs.repository.CustomerRepository.findById" column="cid"/>
</resultMap>

<select id="findById" parameterType="java.lang.Integer" resultType="com.xs.entity.Customer">
select * from customer where id = #{id}
</select>

</mapper>

5,配置 config.xml

<mapper resource="repository/CustomerRepository.xml"/> <!-- xml的路径 -->
<mapper resource="repository/OrderRepository.xml"/> <!-- xml的路径 -->

6,main

package com.xs.test;

import com.xs.entity.Order;
import com.xs.repository.OrderRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test5 {

public static void main(String[] args) {
// 加载 MyBatis 配置文件
InputStream inp = Test.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSFB = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlF = sqlSFB.build(inp);

// 获取 SqlSession
SqlSession sqlS = sqlF.openSession();
OrderRepository orderRepository = sqlS.getMapper(OrderRepository.class);
Order order = orderRepository.findById(4);
System.out.println(order);
// 结果
// Order(id=4, name=订单4, customer=Customer(id=3, name=Vn, orders=null))

}

}

MyBatis 缓存​

使用 MyBatis 的 二级缓存 有以下几个好处:

1. 减少数据库查询次数​

二级缓存将查询结果存储在缓存中,当相同的查询再次发出时,直接从缓存中读取数据,而不是每次都从数据库中重新获取。这减少了对数据库的访问频率,提高了系统的响应速度。

2. 提升系统性能​

通过减少对数据库的访问,降低了数据库负载,尤其是在数据变化不频繁但查询频繁的场景中。缓存能够显著提升系统性能,尤其是对于高并发的应用场景。

3. 节约资源​

数据库是系统中耗费资源较多的部分,减少对其查询可以节省 CPU 和 I/O 资源。缓存可以缓解数据库的压力,减少响应时间,提升用户体验。

4. 跨 Session 的共享​

与一级缓存不同,二级缓存可以跨 SqlSession 共享。这意味着在同一个 MyBatis 应用中,不同的 SqlSession 可以共享缓存数据,进一步减少重复查询。

5. 持久化缓存数据​

如果配置了合适的缓存存储策略,二级缓存的数据可以持久化到磁盘或其他存储介质,这样即使应用重启也能从缓存中快速恢复数据,减少重新查询数据库的开销。

适用场景​

二级缓存适合以下场景:

  • 读多写少:数据更新较少,而查询频繁的系统,如用户信息、产品目录等。
  • 高并发读请求:高流量的读请求场景中,通过缓存可以显著提高查询效率。
注意事项​
  • 缓存数据的一致性问题:二级缓存会缓存查询结果,当数据库中的数据发生变更时,必须确保缓存中的数据也能够及时失效或更新,以避免数据不一致的问题。
  • 缓存的存储空间:缓存占用内存或磁盘空间,因此要合理配置缓存的大小,以避免占用过多资源。

在恰当的场景下,使用二级缓存能显著提高系统的效率。

1,配置 pom

<!-- ehcache -->
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.6.11</version>
</dependency>

<!-- ehcache -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>1.2.1</version> <!-- 请根据最新版本选择 -->
</dependency>

<!-- slf4j 缓存 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
<version>1.7.36</version> <!-- 选择适合的版本 -->
</dependency>

2,实体类

package com.xs.entity;

import lombok.Data;

import java.io.Serializable;

@Data
public class MyClass implements Serializable {
private Integer id;
private String name;
}

3,Repository JAVA

package com.xs.repository;

import com.xs.entity.MyClass;

public interface MyClassRepository {
public MyClass findById(Integer id);
}

4,Repository XML

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口的路径 -->
<mapper namespace="com.xs.repository.MyClassRepository">

<!-- 配置 二级缓存 -->
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
<property name="timeToIdleSeconds" value="3600"/>
<property name="timeToLiveSeconds" value="3600"/>
<property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>

<select id="findById" parameterType="java.lang.Integer" resultType="com.xs.entity.MyClass">
SELECT * FROM classes WHERE id = #{id}
</select>

</mapper>

5,配置 二级缓存

<settings>

<!-- 二级缓存 -->
<setting name="cacheEnabled" value="true"/>
</settings>

6,配置 config.xml

<mapper resource="repository/MyClassRepository.xml"/> <!-- xml的路径 -->

7,main

package com.xs.test;

import com.xs.entity.MyClass;
import com.xs.entity.Order;
import com.xs.repository.MyClassRepository;
import com.xs.repository.OrderRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test6 {

public static void main(String[] args) {
// 加载 MyBatis 配置文件
InputStream inp = Test.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSFB = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlF = sqlSFB.build(inp);

// 获取 SqlSession
SqlSession sqlS = sqlF.openSession();
MyClassRepository myClassRepository = sqlS.getMapper(MyClassRepository.class);

// 第一次查询
MyClass mc1 = myClassRepository.findById(1);
System.out.println(mc1);

sqlS.close();

// 第二次查询,同样的查询应该命中缓存
sqlS = sqlF.openSession();
myClassRepository = sqlS.getMapper(MyClassRepository.class);
MyClass mc2 = myClassRepository.findById(1);
System.out.println(mc2);

sqlS.close();

}

}

8,在 resource 创建 ehcache.xml

<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="http://www.ehcache.org/ehcache.xsd"
updateCheck="false"
monitoring="autodetect"
dynamicConfig="true">

<!-- 默认缓存配置 -->
<defaultCache
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
diskSpoolBufferSizeMB="30"
maxEntriesLocalDisk="10000000"
diskPersistent="false"
diskExpiryThreadIntervalSeconds="120"
memoryStoreEvictionPolicy="LRU"/>

<!-- 自定义缓存配置 -->
<cache name="exampleCache"
maxEntriesLocalHeap="1000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
diskSpoolBufferSizeMB="20"
maxEntriesLocalDisk="10000000"
diskPersistent="false"
memoryStoreEvictionPolicy="LRU">
</cache>

<!-- 另外一个自定义缓存 -->
<cache name="anotherCache"
maxEntriesLocalHeap="500"
eternal="true"
overflowToDisk="true"
diskSpoolBufferSizeMB="50"
maxEntriesLocalDisk="500000"
diskPersistent="true"
diskExpiryThreadIntervalSeconds="60"
memoryStoreEvictionPolicy="FIFO">
</cache>

</ehcache>

MyBatis 动态 SQL​

1,实体类

package com.xs.entity;

import lombok.Data;

@Data
public class User {
private Integer id;
private String username;
private String password;
private Integer age;
}

2,Repository JAVA

package com.xs.repository;

import com.xs.entity.User;

public interface UserRepository {
public User findByUser(User user);
}

3,配置 config.xml

<mapper resource="repository/UserRepository.xml"/> <!-- xml的路径 -->

4,Repository XML

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- 接口的路径 -->
<mapper namespace="com.xs.repository.UserRepository">

<select id="findByUser" parameterType="com.xs.entity.User" resultType="com.xs.entity.User">
SELECT * FROM user
<where>
<if test="id!=null">
id = #{id}
</if>
<if test="username!=null">
and username = #{username}
</if>
<if test="password!=null">
and password = #{password}
</if>
<if test="age!=null">
and age = #{age}
</if>
</where>
</select>

</mapper>

5,main

package com.xs.test;

import com.xs.entity.MyClass;
import com.xs.entity.Order;
import com.xs.entity.User;
import com.xs.repository.MyClassRepository;
import com.xs.repository.OrderRepository;
import com.xs.repository.UserRepository;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class Test7 {

public static void main(String[] args) {
// 加载 MyBatis 配置文件
InputStream inp = Test.class.getClassLoader().getResourceAsStream("config.xml");
SqlSessionFactoryBuilder sqlSFB = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlF = sqlSFB.build(inp);

// 获取 SqlSession
SqlSession sqlS = sqlF.openSession();
UserRepository userRepository = sqlS.getMapper(UserRepository.class);
User u = new User();
u.setId(2);
u.setUsername("BGG");
// u.setPassword("5566");
// u.setAge(9);
User user = userRepository.findByUser(u);
System.out.println(user);

}

}
Choose / When 动态 写法​
<select id="findByUser" parameterType="com.xs.entity.User" resultType="com.xs.entity.User">
SELECT * FROM user
<where>
<choose>
<when test="id!=null">
id = #{id}
</when>
<when test="username!=null">
and username = #{username}
</when>
<when test="password!=null">
and password = #{password}
</when>
<when test="age!=null">
and age = #{age}
</when>
</choose>
</where>
</select>
Trim 动态 写法​
<select id="findByUser" parameterType="com.xs.entity.User" resultType="com.xs.entity.User">
SELECT * FROM user
<trim prefix="where" prefixOverrides="and">
<if test="id!=null">
id = #{id}
</if>
<if test="username!=null">
and username = #{username}
</if>
<if test="password!=null">
and password = #{password}
</if>
<if test="age!=null">
and age = #{age}
</if>
</trim>
</select>
set 动态 写法​

用于 Update 操作

1,Repository JAVA

package com.xs.repository;

import com.xs.entity.User;

public interface UserRepository {
public User findByUser(User user);
public int update(User user);
}

2,Repository XML

<update id="update" parameterType="com.xs.entity.User">
update user
<set>
<if test="username != null">
username = #{username},
</if>
<if test="password != null">
password = #{password},
</if>
<if test="age != null">
age = #{age}
</if>
</set>
where id = #{id}
</update>