mybatis

MyBatis概述

MyBatis是一个实现了数据持久化的开源框架,简单理解就是对JDBC进行封装

MyBatis优点

  • 与JDBC相比,减少了50%以上的代码量。
  • MyBatis 是最简单的持久化框架,小巧并且简单易学。
  • MyBatis相当灵活,不会对应用程序或者数据库的现有设计强加任何影响,SQL写在XML里,从程序代码中彻底分离,降低耦合度,便于统一管理和优化,并可重用。
  • 提供XML标签,支持编写动态SQL语句。
  • 提供映射标签,支持对象与数据库的ORM字段关系映射。

MyBatis缺点

  • SQL语句的编写工作量较大,尤其是字段多、关联表多时,更是如此,对开发人员编写SQL语句的功底有一定要求。
  • SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库。

MyBatis核心接口和类

MyBatis的开发方式

  • 使用原生接口
  • Mapper代理实现自定义接口

MyBatis的使用

  • 新建Maven工程,pom.xml
<dependencies>
 <dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis</artifactId>
 <version>3.4.5</version>
 </dependency>
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>8.0.11</version>
 </dependency>
 <dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.6</version>
 <scope>provided</scope>
 </dependency>
</dependencies>
  • 创建数据表
use mybatis;
create table t_account(
   id int primary key auto_increment,
   username varchar(11),
   password varchar(11),
   age int
)
  • 创建实体类
package com.southwind.entity;
import lombok.Data;
@Data
public class Account {
   private long id;
   private String username;
   private String password;
   private int age;
}
  • 创建 MyBatis 的配置文件 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">
     <!-- 配置JDBC事务管理 -->
     <transactionManager type="JDBC"></transactionManager>
     <!-- POOLED配置JDBC数据源连接池 -->
     <dataSource type="POOLED">
       <property name="driver" value="com.mysql.cj.jdbc.Driver"></property>
       <property name="url"value="jdbc:mysql://localhost:3306/mybatis?
useUnicode=true&amp;characterEncoding=UTF-8"></property>
       <property name="username" value="root"></property>
       <property name="password" value="root"></property>
     </dataSource>
    </environment>
 </environments>
</configuration>

使用原生接口

  1. MyBatis 框架需要开发者自定义 SQL语句,写在 Mapper.xml 文件中,实际开发中,会为每个实体类创建对应的Mapper.xml,定义管理该对象数据的 SQL。

    目录结构
<?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.southwind.mapper.AccoutMapper">

     <insert id="save" parameterType="com.southwind.entity.Account">
       insert into t_account(username,password,age) values(#{username},#
{password},#{age})
     </insert>
</mapper>
  • namespace 通常设置为⽂件所在包+⽂件名的形式。
  • insert 标签表示执⾏添加操作。
  • select 标签表示执⾏查询操作。
  • update 标签表示执⾏更新操作。
  • delete 标签表示执⾏删除操作。
  • id 是实际调⽤ MyBatis ⽅法时需要⽤到的参数。
  • parameterType 是调⽤对应⽅法时参数的数据类型。
  1. 在全局配置⽂件 config.xml 中注册 AccountMapper.xml
 <!-- 注册AccountMapper.xml -->
 <mappers>
     <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
 </mappers>
  1. 调⽤ MyBatis 的原⽣接⼝执⾏添加操作。
public class Test {
     public static void main(String[] args) {
         //加载MyBatis配置⽂件
         
         InputStream inputStream =
Test.class.getClassLoader().getResourceAsStream("config.xml");//读取流
         SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new
SqlSessionFactoryBuilder();  //MyBatis核心类
         SqlSessionFactory sqlSessionFactory =
sqlSessionFactoryBuilder.build(inputStream);  //根据配置文件创建工厂对象
         SqlSession sqlSession = sqlSessionFactory.openSession();
         String statement = "com.southwind.mapper.AccoutMapper.save";
         Account account = new Account(1L,"张三","123123",22);
         sqlSession.insert(statement,account);
         sqlSession.commit();
     }
}

通过 Mapper 代理实现自定义接口

  • 自定义接口,定义相关业务方法。
  • 编写与方法相对应的 Mapper.xml。
  1. 自定义接口
package com.southwind.repository;
import com.southwind.entity.Account;
import java.util.List;
public interface AccountRepository {
     public int save(Account account);
     public int update(Account account);
     public int deleteById(long id);
     public List<Account> findAll();
     public Account findById(long id);
}
  1. 创建接⼝对应的 Mapper.xml,定义接⼝⽅法对应的 SQL 语句。
    statement 标签可根据 SQL 执⾏的业务选择 insert、delete、update、select。
    MyBatis 框架会根据规则⾃动创建接⼝实现类的代理对象。
    规则:
  • Mapper.xml 中 namespace 为接⼝的全类名。
  • Mapper.xml 中 statement 的 id 为接⼝中对应的⽅法名。
  • Mapper.xml 中 statement 的 parameterType 和接⼝中对应⽅法的参数类型⼀致。
  • Mapper.xml 中 statement 的 resultType 和接⼝中对应⽅法的返回值类型⼀致。
<?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.southwind.repository.AccountRepository">
     <insert id="save" parameterType="com.southwind.entity.Account">
         insert into t_account(username,password,age) values(#{username},#
{password},#{age})
     </insert>
     <update id="update" parameterType="com.southwind.entity.Account">
         update t_account set username = #{username},password = #{password},age
= #{age} where id = #{id}
     </update>
     <delete id="deleteById" parameterType="long">
         delete from t_account where id = #{id}
     </delete>
     <select id="findAll" resultType="com.southwind.entity.Account">
         select * from t_account
     </select>
     <select id="findById" parameterType="long"
resultType="com.southwind.entity.Account">
         select * from t_account where id = #{id}
     </select>
</mapper>

  1. 在 config.xml 中注册 AccountRepository.xml
<!-- 注册AccountMapper.xml -->
<mappers>
   <mapper resource="com/southwind/mapper/AccountMapper.xml"></mapper>
   <mapper resource="com/southwind/repository/AccountRepository.xml"></mapper>
</mappers>
  1. 调⽤接⼝的代理对象完成相关的业务操作
public class Test {
     public static void main(String[] args) {       
         InputStream inputStream =
Test.class.getClassLoader().getResourceAsStream("config.xml");
         SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new
SqlSessionFactoryBuilder();  
         SqlSessionFactory sqlSessionFactory =
sqlSessionFactoryBuilder.build(inputStream); 
         SqlSession sqlSession = sqlSessionFactory.openSession();
         //获取实现接⼝的代理对象
         AccountRepository accountRepository =
sqlSession.getMapper(AccountRepository.class);
         //添加对象
         Account account = new Account(3L,"王五","111111",24);
         int result = accountRepository.save(account);
         sqlSession.commit();
         //查询全部对象
         List<Account> list = accountRepository.findAll();
         for (Account account:list){
             System.out.println(account);
         }
         sqlSession.close();
         //通过id查询对象
         Account account = accountRepository.findById(3L);
         System.out.println(account);
         sqlSession.close();
         //修改对象
         Account account = accountRepository.findById(3L);
         account.setUsername("⼩明");
         account.setPassword("000");
         account.setAge(18);
         int result = accountRepository.update(account);
         sqlSession.commit();
         System.out.println(result);
         sqlSession.close();
         //通过id删除对象
         int result = accountRepository.deleteById(3L);
         System.out.println(result);
         sqlSession.commit();
         sqlSession.close();
     }
}

Mapper.xml

MyBatis主要有两个配置文件,一个是config.xml(1.配置MyBatis运行环境,数据源环境;2.把Mapper引进来)、一个是Mapper.xml

  • statement 标签:select、update、delete、insert 分别对应查询、修改、删除、添加操作。
  • parameterType:参数数据类型
  1. 基本数据类型,通过 id 查询 Account
<select id="findById" parameterType="long"
resultType="com.southwind.entity.Account">
 select * from t_account where id = #{id}
</select>
  1. String 类型,通过 name 查询 Account
<select id="findByName" parameterType="java.lang.String"
resultType="com.southwind.entity.Account">
 select * from t_account where username = #{username}
</select>
  1. 包装类,通过 id 查询 Account
<select id="findById2" parameterType="java.lang.Long"
resultType="com.southwind.entity.Account">
 select * from t_account where id = #{id}
</select>
  1. 多个参数,通过 name 和 age 查询 Account
<select id="findByNameAndAge" resultType="com.southwind.entity.Account">
 select * from t_account where username = #{arg0} and age = #{arg1}
</select>
  1. Java Bean
<update id="update" parameterType="com.southwind.entity.Account">
 update t_account set username = #{username},password = #{password},age =
#{age} where id = #{id}
</update>
  • resultType:结果类型
  1. 基本数据类型,统计 Account 总数
<select id="count" resultType="int">
 select count(id) from t_account
</select>
  1. 包装类,统计 Account 总数
<select id="count2" resultType="java.lang.Integer">
 select count(id) from t_account
</select>
  1. String 类型,通过 id 查询 Account 的 name
<select id="findNameById" resultType="java.lang.String">
 select username from t_account where id = #{id}
</select>
  1. Java Bean
<select id="findById" parameterType="long"
resultType="com.southwind.entity.Account">
 select * from t_account where id = #{id}
</select>

级联查询

  • ⼀对多
    Student
package com.southwind.entity;
import lombok.Data;
@Data
public class Student {
 private long id;
 private String name;
 private Classes classes;
}

Classes

package com.southwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Classes {
 private long id;
 private String name;
 private List<Student> students;
}

StudentRepository

package com.southwind.repository;
import com.southwind.entity.Student;
public interface StudentRepository {
 public Student findById(long id);
}

StudentRepository.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.southwind.repository.StudentRepository">

   <resultMap id="studentMap" type="com.southwind.entity.Student">
       <id column="id" property="id"></id>
       <result column="name" property="name"></result>
       <association property="classes" javaType="com.southwind.entity.Classes">
           <id column="cid" property="id"></id>
           <result column="cname" property="name"></result>
       </association>
   </resultMap>
   <select id="findById" parameterType="long" resultMap="studentMap">
       select s.id,s.name,c.id as cid,c.name as cname from student s,classes c
where s.id = #{id} and s.cid = c.id
   </select>
</mapper>
select s.id,s.name,c.id,c.name from student s,classes c where s.id = #{id} and s.cid = c.id

idea运行结果

数据库运行结果

明明在数据库里查到了c.name是6班,为啥idea里面是null呢。
因为没有映射起来,MyBatis和Java类怎么映射的?是把结果集和类变量名的映射。就看Student属性名和结果集的字段名做对比,哪个相等就赋值。如果结果集多个字段与属性名重合,就按顺序取。即把第一个id“1”和第一个“name”取出来赋给Student的id和name。但是结果集没有“classes”这个字段,也就是说它与变量名映射不上,所以classes=null。
验证一下

select s.id as sid,s.name as sname,c.id,c.name from student s,classes c where s.id = #{id} and s.cid = c.id

结果

显然,想要classes不为空,就得把cid和cname整合为一个classes对象赋给student。所以不能像sid和sname直接映射,而是通过间接映射

同样的,查询一个班级的所有学生,应该把查到的学生封装成List<>赋给classes。
id和cid映射、name和cname映射、students和查询到的学生对象集合映射

ClassesRepository

package com.southwind.repository;
import com.southwind.entity.Classes;
public interface ClassesRepository {
 public Classes findById(long id);
}

ClassesRepository.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.southwind.repository.ClassesRepository">

   <resultMap id="classesMap" type="com.southwind.entity.Classes">
       <id column="cid" property="id"></id>
       <result column="cname" property="name"></result>
       <collection property="students" ofType="com.southwind.entity.Student">
           <id column="id" property="id"/>
           <result column="name" property="name"/>
       </collection>
   </resultMap>
   <select id="findById" parameterType="long" resultMap="classesMap">
       select s.id,s.name,c.id as cid,c.name as cname from student s,classes c
where c.id = #{id} and s.cid = c.id
   </select>
</mapper>
  • 多对多
    Customer
package com.southwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Customer {
 private long id;
 private String name;
 private List<Goods> goods;
}

Goods

package com.southwind.entity;
import lombok.Data;
import java.util.List;
@Data
public class Goods {
 private long id;
 private String name;
 private List<Customer> customers;
}

CustomerRepository

package com.southwind.repository;
import com.southwind.entity.Customer;
public interface CustomerRepository {
 public Customer findById(long id);
}

CustomerRepository.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.southwind.repository.CustomerRepository">

     <resultMap id="customerMap" type="com.southwind.entity.Customer">
         <id column="cid" property="id"></id>
         <result column="cname" property="name"></result>
         <collection property="goods" ofType="com.southwind.entity.Goods">
             <id column="gid" property="id"/>
             <result column="gname" property="name"/>
         </collection>
     </resultMap>
     <select id="findById" parameterType="long" resultMap="customerMap">
         select c.id cid,c.name cname,g.id gid,g.name gname from customer c,goods
g,customer_goods cg where c.id = #{id} and cg.cid = c.id and cg.gid = g.id
     </select>
</mapper>

GoodsRepository

package com.southwind.repository;
import com.southwind.entity.Goods;
public interface GoodsRepository {
 public Goods findById(long id);
}

GoodsRepository.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.southwind.repository.GoodsRepository">

     <resultMap id="goodsMap" type="com.southwind.entity.Goods">
         <id column="gid" property="id"></id>
         <result column="gname" property="name"></result>
         <collection property="customers" ofType="com.southwind.entity.Customer">
             <id column="cid" property="id"/>
             <result column="cname" property="name"/>
         </collection>
     </resultMap>
     <select id="findById" parameterType="long" resultMap="goodsMap">
           select c.id cid,c.name cname,g.id gid,g.name gname from customer c,goods
g,customer_goods cg where g.id = #{id} and cg.cid = c.id and cg.gid = g.id
     </select>
</mapper>

逆向工程

MyBatis 框架需要:实体类、⾃定义 Mapper 接⼝、Mapper.xml
传统的开发中上述的三个组件需要开发者⼿动创建,逆向⼯程可以帮助开发者来⾃动创建三个组件,减
轻开发者的⼯作量,提⾼⼯作效率。
如何使⽤
MyBatis Generator,简称 MBG,是⼀个专⻔为 MyBatis 框架开发者定制的代码⽣成器,可⾃动⽣成
MyBatis 框架所需的实体类、Mapper 接⼝、Mapper.xml,⽀持基本的 CRUD 操作,但是⼀些相对复
杂的 SQL 需要开发者⾃⼰来完成。

  • 新建 Maven ⼯程,pom.xml
<dependencies>
 <dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis</artifactId>
 <version>3.4.5</version>
 </dependency>
 <dependency>
 <groupId>mysql</groupId>
 <artifactId>mysql-connector-java</artifactId>
 <version>8.0.11</version>
 </dependency>
 <dependency>
 <groupId>org.mybatis.generator</groupId>
 <artifactId>mybatis-generator-core</artifactId>
 <version>1.3.2</version>
 </dependency>
</dependencies>
  • 创建 MBG 配置⽂件 generatorConfig.xml
  1. jdbcConnection 配置数据库连接信息。
  2. javaModelGenerator 配置 JavaBean 的⽣成策略。
  3. sqlMapGenerator 配置 SQL 映射⽂件⽣成策略。
  4. javaClientGenerator 配置 Mapper 接⼝的⽣成策略。
  5. table 配置⽬标数据表(tableName:表名,domainObjectName:JavaBean 类名)。
<?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="testTables" targetRuntime="MyBatis3">
         <jdbcConnection
             driverClass="com.mysql.cj.jdbc.Driver"
             connectionURL="jdbc:mysql://localhost:3306/mybatis?
useUnicode=true&amp;characterEncoding=UTF-8"
             userId="root"
             password="root"
         ></jdbcConnection>
         <javaModelGenerator targetPackage="com.southwind.entity"
targetProject="./src/main/java"></javaModelGenerator>
         <sqlMapGenerator targetPackage="com.southwind.repository"
targetProject="./src/main/java"></sqlMapGenerator>
         <javaClientGenerator type="XMLMAPPER"
targetPackage="com.southwind.repository" targetProject="./src/main/java">
         </javaClientGenerator>
         <table tableName="t_user" domainObjectName="User"></table>
     </context>
</generatorConfiguration>
  • 创建 Generator 执⾏类。
package com.southwind.test;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.exception.InvalidConfigurationException;
import org.mybatis.generator.exception.XMLParserException;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
public class Main {
   public static void main(String[] args) {
       List<String> warings = new ArrayList<String>();
       boolean overwrite = true;
       String genCig = "/generatorConfig.xml";
       File configFile = new File(Main.class.getResource(genCig).getFile());
       ConfigurationParser configurationParser = new
       ConfigurationParser(warings);
       Configuration configuration = null;
       try {
          configuration = configurationParser.parseConfiguration(configFile);
       } catch (IOException e) {
          e.printStackTrace();
       } catch (XMLParserException e) {
          e.printStackTrace();
       }
       DefaultShellCallback callback = new DefaultShellCallback(overwrite);
       MyBatisGenerator myBatisGenerator = null;
       try {
         myBatisGenerator = new
         MyBatisGenerator(configuration,callback,warings);
       } catch (InvalidConfigurationException e) {
         e.printStackTrace();
       }
       try {
         myBatisGenerator.generate(null);
       } catch (SQLException e) {
         e.printStackTrace();
       } catch (IOException e) {
         e.printStackTrace();
       } catch (InterruptedException e) {
         e.printStackTrace();
       }
   }
}

MyBatis缓存

  • 什么是 MyBatis 缓存

使⽤缓存可以减少 Java 应⽤与数据库的交互次数,从⽽提升程序的运⾏效率。⽐如查询出 id = 1 的对
象,第⼀次查询出之后会⾃动将该对象保存到缓存中,当下⼀次查询时,直接从缓存中取出对象即可,
⽆需再次访问数据库。

  • MyBatis 缓存分类

⼀级缓存:SqlSession 级别,默认开启,并且不能关闭。

操作数据库时需要创建 SqlSession 对象,在对象中有⼀个 HashMap ⽤于存储缓存数据,不同的
SqlSession 之间缓存数据区域是互不影响的。

⼀级缓存的作⽤域是 SqlSession 范围的,当在同⼀个 SqlSession 中执⾏两次相同的 SQL 语句事,第⼀
次执⾏完毕会将结果保存到缓存中,第⼆次查询时直接从缓存中获取。

需要注意的是,如果 SqlSession 执⾏了 DML 操作(insert、update、delete),MyBatis 必须将缓存
清空以保证数据的准确性。

⼆级缓存:Mapper 级别,默认关闭,可以开启

使⽤⼆级缓存时,多个 SqlSession 使⽤同⼀个 Mapper 的 SQL 语句操作数据库,得到的数据会存在⼆
级缓存区,同样是使⽤ HashMap 进⾏数据存储,相⽐较于⼀级缓存,⼆级缓存的范围更⼤,多个
SqlSession 可以共⽤⼆级缓存,⼆级缓存是跨 SqlSession 的。

⼆级缓存是多个 SqlSession 共享的,其作⽤域是 Mapper 的同⼀个 namespace,不同的 SqlSession
两次执⾏相同的 namespace 下的 SQL 语句,参数也相等,则第⼀次执⾏成功之后会将数据保存到⼆级
缓存中,第⼆次可直接从⼆级缓存中取出数据。

代码

  • ⼀级缓存
public class Test4 {
  public static void main(String[] args) {
   InputStream inputStream =
Test.class.getClassLoader().getResourceAsStream("config.xml");
   SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new
SqlSessionFactoryBuilder();
   SqlSessionFactory sqlSessionFactory =
sqlSessionFactoryBuilder.build(inputStream);
   SqlSession sqlSession = sqlSessionFactory.openSession();
   AccountRepository accountRepository =
sqlSession.getMapper(AccountRepository.class);
   Account account = accountRepository.findById(1L);
   System.out.println(account);
   sqlSession.close();  //关闭sqlSession
   sqlSession = sqlSessionFactory.openSession();
   accountRepository = sqlSession.getMapper(AccountRepository.class);
   Account account1 = accountRepository.findById(1L);
   System.out.println(account1);
  }
  //会执行两次查询操作。
}
  • 二级缓存
  1. MyBatis ⾃带的⼆级缓存
  • config.xml 配置开启⼆级缓存
<settings>
 <!-- 打印SQL-->
 <setting name="logImpl" value="STDOUT_LOGGING" />
 <!-- 开启延迟加载 -->
 <setting name="lazyLoadingEnabled" value="true"/>
 <!-- 开启⼆级缓存 -->
 <setting name="cacheEnabled" value="true"/>
</settings>
  • Mapper.xml 中配置⼆级缓存
<cache></cache>
  • 实体类实现序列化接⼝
import java.io.Serializable;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account implements Serializable {
 private long id;
 private String username;
 private String password;
 private int age;
}
  1. ehcache ⼆级缓存
  • pom.xml 添加相关依赖
<dependency>
 <groupId>org.mybatis</groupId>
 <artifactId>mybatis-ehcache</artifactId>
 <version>1.0.0</version>
</dependency>
<dependency>
 <groupId>net.sf.ehcache</groupId>
 <artifactId>ehcache-core</artifactId>
 <version>2.4.3</version>
</dependency>
  • 添加 ehcache.xml
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xsi:noNamespaceSchemaLocation="../config/ehcache.xsd">
 <diskStore/>
 <defaultCache
 maxElementsInMemory="1000"
 maxElementsOnDisk="10000000"
 eternal="false"
 overflowToDisk="false"
 timeToIdleSeconds="120"
 timeToLiveSeconds="120"
 diskExpiryThreadIntervalSeconds="120"
 memoryStoreEvictionPolicy="LRU">
 </defaultCache>
</ehcache>
  • config.xml 配置开启⼆级缓存
<settings>
 <!-- 打印SQL-->
 <setting name="logImpl" value="STDOUT_LOGGING" />
 <!-- 开启延迟加载 -->
 <setting name="lazyLoadingEnabled" value="true"/>
 <!-- 开启⼆级缓存 -->
 <setting name="cacheEnabled" value="true"/>
</settings>
  • Mapper.xml 中配置⼆级缓存
<cache type="org.mybatis.caches.ehcache.EhcacheCache">
 <!-- 缓存创建之后,最后⼀次访问缓存的时间⾄缓存失效的时间间隔 -->
 <property name="timeToIdleSeconds" value="3600"/>
 <!-- 缓存⾃创建时间起⾄失效的时间间隔 -->
 <property name="timeToLiveSeconds" value="3600"/>
 <!-- 缓存回收策略,LRU表示移除近期使⽤最少的对象 -->
 <property name="memoryStoreEvictionPolicy" value="LRU"/>
</cache>
  • 实体类不需要实现序列化接⼝。
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Account {
 private long id;
 private String username;
 private String password;
 private int age;
}

MyBatis动态SQL

使⽤动态 SQL 可简化代码的开发,减少开发者的⼯作量,程序可以⾃动根据业务参数来决定 SQL 的组
成。
if 标签

<select id="findByAccount" parameterType="com.southwind.entity.Account"
resultType="com.southwind.entity.Account">
     select * from t_account where
     <if test="id!=0">
         id = #{id}
     </if>
     <if test="username!=null">
         and username = #{username}
     </if>
     <if test="password!=null">
         and password = #{password}
     </if>
     <if test="age!=0">
         and age = #{age}
     </if>
</select>

if 标签可以⾃动根据表达式的结果来决定是否将对应的语句添加到 SQL 中,如果条件不成⽴则不添加,
如果条件成⽴则添加。

where 标签

<select id="findByAccount" parameterType="com.southwind.entity.Account"
resultType="com.southwind.entity.Account">
     select * from t_account
     <where>
         <if test="id!=0">
             id = #{id}
         </if>
         <if test="username!=null">
             and username = #{username}
         </if>
         <if test="password!=null">
             and password = #{password}
         </if>
         <if test="age!=0">
             and age = #{age}
         </if>
     </where>
</select>

where 标签可以⾃动判断是否要删除语句块中的 and 关键字,如果检测到 where 直接跟 and 拼接,则
⾃动删除 and,通常情况下 if 和 where 结合起来使⽤。

choose 、when 标签

<select id="findByAccount" parameterType="com.southwind.entity.Account"
resultType="com.southwind.entity.Account">
     select * from t_account
     <where>
         <choose>
             <when test="id!=0">
                 id = #{id}
             </when>
             <when test="username!=null">
                 username = #{username}
             </when>
             <when test="password!=null">
                 password = #{password}
             </when>
             <when test="age!=0">
                 age = #{age}
             </when>
         </choose>
             </where>
</select>

trim 标签
trim 标签中的 prefix 和 suffix 属性会被⽤于⽣成实际的 SQL 语句,会和标签内部的语句进⾏拼接,如
果语句前后出现了 prefixOverrides 或者 suffixOverrides 属性中指定的值,MyBatis 框架会⾃动将其删
除。

<select id="findByAccount" parameterType="com.southwind.entity.Account"
resultType="com.southwind.entity.Account">
     select * from t_account
     <trim prefix="where" prefixOverrides="and">
         <if test="id!=0">
             id = #{id}
         </if>
         <if test="username!=null">
             and username = #{username}
         </if>
         <if test="password!=null">
             and password = #{password}
         </if>
         <if test="age!=0">
             and age = #{age}
         </if>
     </trim>
</select>

set 标签

set 标签⽤于 update 操作,会⾃动根据参数选择⽣成 SQL 语句。

<update id="update" parameterType="com.southwind.entity.Account">
     update t_account
     <set>
         <if test="username!=null">
             username = #{username},
         </if>
         <if test="password!=null">
             password = #{password},
         </if>
         <if test="age!=0">
             age = #{age}
         </if>
     </set>
     where id = #{id}
</update>

foreach 标签
foreach 标签可以迭代⽣成⼀系列值,这个标签主要⽤于 SQL 的 in 语句.

<select id="findByIds" parameterType="com.southwind.entity.Account"
resultType="com.southwind.entity.Account">
     select * from t_account
     <where>
           <foreach collection="ids" open="id in (" close=")" item="id"
separator=",">
               #{id}
           </foreach>
     </where>
</select>
posted @ 2024-02-25 22:57  不会des  阅读(9)  评论(0编辑  收藏  举报