MyBatis 介绍

MyBatis 是一款优秀的持久层框架,用于简化 JDBC 开发。

持久层:

  • 是负责将数据到保存到数据库的那一层代码。即,操作数据库的Java代码为持久层。

    而Mybatis就是对JDBC代码进行了封装。

  • 持久层是JavaEE三层架构中的一层。

    JavaEE三层架构:表现层、业务层、持久层。

框架:

  • 框架就是一个半成品软件,是一套可重用的、通用的、软件基础代码模型。
  • 使用框架的好处:在框架的基础之上构建软件编写更加高效、规范、通用、可扩展。

使用JDBC存在以下问题:

  • 硬编码

    手动注册驱动、获取连接、SQL语句等。

  • 操作繁琐

    手动设置参数、封装结果集等。

使用Mybatis:

  • 硬编码可以配置到配置文件。
  • 操作繁琐的地方Mybatis都自动完成。

配置 Mybatis

使用Maven导入Mybatis。

  1. pom.xml 配置文件中导入坐标:

     1<dependencies>
     2    <!--mybatis 依赖-->
     3    <dependency>
     4        <groupId>org.mybatis</groupId>
     5        <artifactId>mybatis</artifactId>
     6        <version>3.5.5</version>
     7    </dependency>
     8
     9    <!--mysql 驱动-->
    10    <dependency>
    11        <groupId>mysql</groupId>
    12        <artifactId>mysql-connector-java</artifactId>
    13        <version>5.1.46</version>
    14    </dependency>
    15</dependencies>
    
  2. 编写 mybatis-config.xml 文件:

    在模块下的 resources 目录下创建Mybatis的配置文件 mybatis-config.xml

     1<?xml version="1.0" encoding="UTF-8" ?>
     2<!DOCTYPE configuration
     3        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
     4        "http://mybatis.org/dtd/mybatis-3-config.dtd">
     5<configuration>
     6  <!-- 需要注意配置标签的前后顺序(按照MyBatis官方文档目录中的顺序去定义) -->
     7  <!-- 别名或包扫描 -->
     8  <typeAliases>
     9    <!-- name属性的值是实体类所在包 -->
    10    <!-- 包扫描后,别名默认为类名(不区分大小写) -->
    11    <!-- 使用别名可以简化映射配置文件中 resultType 属性值的编写 -->
    12    <package name="package.name.pojo"/>
    13  </typeAliases>
    14
    15  <!--
    16    environments:配置数据库的连接环境信息,
    17      可以配置多个environment信息,
    18      通过对应的default属性切换不同的environment
    19  -->
    20  <environments default="development">
    21    <!-- 可以配置多个<environment> -->
    22    <!-- 使用 id 给每段环境起名 -->
    23    <!-- 在 <environments> 中使用 default='environment-id' 来指定使用哪儿段配置 -->
    24    <environment id="development">
    25      <transactionManager type="JDBC"/>
    26      <dataSource type="POOLED">
    27        <!-- 
    28          数据库连接信息
    29          注意url、username和password
    30        -->
    31        <property name="driver" value="com.mysql.jdbc.Driver"/>
    32        <property name="url" value="jdbc:mysql:///mybatis1?useSSL=false"/>
    33        <property name="username" value="root"/>
    34        <property name="password" value="1234"/>
    35      </dataSource>
    36    </environment>
    37
    38    <environment id="test">
    39      <transactionManager type="JDBC"/>
    40      <dataSource type="POOLED">
    41        <!-- 数据库连接信息 -->
    42        <property name="driver" value="com.mysql.jdbc.Driver"/>
    43        <property name="url" value="jdbc:mysql:///mybatis2?useSSL=false"/>
    44        <property name="username" value="root"/>
    45        <property name="password" value="1234"/>
    46      </dataSource>
    47    </environment>
    48  </environments>
    49  <mappers>
    50    <!-- 加载映射文件 -->
    51    <!-- ...... -->
    52    <!-- 在下节中讲解 -->
    53  </mappers>
    54</configuration>
    

更多MyBatis配置请查看官方文档:MyBatis文档——配置


使用 Mybatis

  • 编写 Mapper

    java 目录下创建与 pojo 对应的 Mapper接口 ClassNameMapper.java

    1public interface ClassNameMapper {
    2    // 方法
    3}
    
  • 编写 SQL 映射文件

    在模块的 resources 目录下创建与 pojo 对应的映射配置文件 ClassNameMapper.xml

    1<?xml version="1.0" encoding="UTF-8" ?>
    2<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    3<!-- namespace:名称空间 -->
    4<mapper namespace="package.name.mapper">
    5  <!-- 相应的SQL语句(XML映射) -->
    6</mapper>
    
  • 在Myb atis的配置文件 mybatis-config.xml 中加载映射文件:

    1. 直接加载映射文件:
    1<mappers>
    2  <mapper resource="com/abc/mapper/ClassNameMapper.xml"/>
    3</mappers>
    

    使用这种方式加载映射文件,多个映射文件需要定义多个 <mapper>,过于繁琐。

    1. Mapper代理方式(推荐):

    如果 Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载。

    1<mappers>
    2  <package name="com.abc.mapper"/>
    3</mappers>
    

注意:使用Mapper代理方式加载映射文件,Mapper接口与其对应的配置文件,它们的路径(包名)要相同。

即,在java目录下的 Mapper接口的包名,要和映射配置文件在 resources下的路径要一致。

Mapper接口的包名为 com.abc.mapper,那么其映射配置文件的路径则为 com/abc/mapper

了解 Maven项目结构,请查看:Maven标准化项目结构

实例

在 Mapper 接口中定义方法,方法名就是SQL映射文件中SQL语句的id,并保持参数类型和返回值类型一致。

例如,为 User对象定义 selectAll()selectById()方法:

  • 创建 User表:

     1CREATE DATABASE mybatis;
     2USE mybatis;
     3
     4DROP table IF EXISTS tb_user;
     5
     6CREATE table tb_user (
     7    id INT PRIMARY KEY AUTO_INCREMENT,
     8    username VARCHAR(20),
     9    password VARCHAR(20),
    10    gender CHAR(1),
    11    addr VARCHAR(30)
    12);
    13
    14INSERT INTO tb_user VALUES (NULL, 'zhangsan', '123', '男', '北京');
    15INSERT INTO tb_user VALUES (NULL, '李四', '234', '女', '天津');
    16INSERT INTO tb_user VALUES (NULL, '王五', '11', '男', '西安');
    
  • pojo包下定义 User实体类:

     1package com.linner.pojo;
     2
     3public class User {
     4    private Integer id;
     5    private String username;
     6    private String password;
     7    private String gender;
     8    private String addr;
     9
    10    public Integer getId() {
    11        return id;
    12    }
    13
    14    public void setId(Integer id) {
    15        this.id = id;
    16    }
    17
    18    public String getUsername() {
    19        return username;
    20    }
    21
    22    public void setUsername(String username) {
    23        this.username = username;
    24    }
    25
    26    public String getPassword() {
    27        return password;
    28    }
    29
    30    public void setPassword(String password) {
    31        this.password = password;
    32    }
    33
    34    public String getGender() {
    35        return gender;
    36    }
    37
    38    public void setGender(String gender) {
    39        this.gender = gender;
    40    }
    41
    42    public String getAddr() {
    43        return addr;
    44    }
    45
    46    public void setAddr(String addr) {
    47        this.addr = addr;
    48    }
    49
    50    @Override
    51    public String toString() {
    52        return "User{" +
    53                "id=" + id +
    54                ", username='" + username + '\'' +
    55                ", password='" + password + '\'' +
    56                ", gender='" + gender + '\'' +
    57                ", addr='" + addr + '\'' +
    58                '}';
    59    }
    60}
    
  • mapper包下定义 UserMapper:

     1package com.linner.pojo;
     2
     3import com.linner.pojo.User;
     4import org.apache.ibatis.annotations.Select;
     5
     6import java.util.List;
     7
     8public interface UserMapper {
     9    List<User> selectAll();
    10    User selectById(int id);
    11    // 更多操作接口
    12}
    
  • resources目录下创建与 UserMapper包名对应的路径,并添加 UserMapper.xml映射配置文件:

     1<?xml version="1.0" encoding="UTF-8" ?>
     2<!DOCTYPE mapper
     3        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     4        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     5
     6<mapper namespace="com.linner.mapper.UserMapper">
     7    <!-- 
     8      select语句使用<select>
     9        id          为对应Mapper类中的方法名
    10        resultType  为对应的实体类, 使用了<typeAliases>包扫描, 省略了包名
    11     -->
    12    <select id="selectAll" resultType="user">
    13        SELECT *
    14        FROM tb_user;
    15    </select>
    16
    17    <select id="selectById" resultType="user">
    18        SELECT *
    19        FROM tb_user
    20        WHERE id = #{id};
    21    </select>
    22
    23    <!-- 更多XML映射 -->
    24</mapper>
    
  • resources目录下,配置 mybatis-config.xml文件:

     1<?xml version="1.0" encoding="UTF-8" ?>
     2<!DOCTYPE configuration
     3        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
     4        "http://mybatis.org/dtd/mybatis-3-config.dtd">
     5<configuration>
     6    <!-- 别名或包扫描 -->
     7    <!-- 使用别名可以简化映射配置文件中 resultType 属性值的编写 -->
     8    <typeAliases>
     9        <package name="com.linner.pojo"/>
    10    </typeAliases>
    11    <environments default="development">
    12        <environment id="development">
    13            <transactionManager type="JDBC"/>
    14            <dataSource type="POOLED">
    15                <!-- 数据库连接信息 -->
    16                <property name="driver" value="com.mysql.jdbc.Driver"/>
    17                <property name="url" value="jdbc:mysql:///mybatis?useSSL=false&useServerPerpStmts=true&characterEncoding=UTF-8"/>
    18                <property name="username" value="root"/>
    19                <property name="password" value="1234"/>
    20            </dataSource>
    21        </environment>
    22    </environments>
    23    <mappers>
    24        <!-- Mapper代理方式-->
    25        <package name="com.linner.mapper"/>
    26    </mappers>
    27</configuration>
    
  • 编写测试类:

     1package com.linner.test;
     2
     3import com.linner.mapper.UserMapper;
     4import com.linner.pojo.User;
     5import org.apache.ibatis.io.Resources;
     6import org.apache.ibatis.session.SqlSession;
     7import org.apache.ibatis.session.SqlSessionFactory;
     8import org.apache.ibatis.session.SqlSessionFactoryBuilder;
     9import org.junit.Test;
    10
    11import java.io.IOException;
    12import java.io.InputStream;
    13import java.util.List;
    14
    15public class UserMapperTest {
    16
    17    @Test
    18    public void testSelectAll() throws IOException {
    19        // 1. 加载mybatis的核心配置文件,获取SqlSessionFactory
    20        String resource = "./mybatis-config.xml";
    21        InputStream inputStream = Resources.getResourceAsStream(resource);
    22        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    23
    24        // 2. 获取SqlSession对象,用它来执行SQL
    25        SqlSession sqlSession = sqlSessionFactory.openSession();
    26
    27        // 3. 执行sql语句
    28        // 3.1 方式一:
    29        // List<User> users = sqlSession.selectList("com.linner.mapper.UserMapper.selectAll");
    30        // 3.2 方式二:
    31        // 3.2.1 获取UserMapper接口的代理对象
    32        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    33        // 3.2.2 执行对应Mapper对象的方法
    34        List<User> users = userMapper.selectAll();
    35
    36        // 4. 处理数据(模拟)
    37        System.out.println(users);
    38
    39        // 5. 释放资源(仅需释放SqlSession对象)
    40        sqlSession.close();
    41    }
    42
    43    @Test
    44    public void testSelectById() throws IOException {
    45        // 模拟接收参数
    46        int id = 1;
    47
    48        // 1. 获取sqlSessionFactory
    49        String resource = "./mybatis-config.xml";
    50        InputStream inputStream = Resources.getResourceAsStream(resource);
    51        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    52
    53        // 2. 获取SqlSession对象
    54        SqlSession sqlSession = sqlSessionFactory.openSession();
    55
    56        // 3. 获取Mapper接口的代理对象
    57        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    58
    59        // 4. 执行方法
    60        User user = userMapper.selectById(id);
    61        // 5. 处理数据(模拟)
    62        System.out.println(user);
    63
    64        // 6. 释放资源
    65        sqlSession.close();
    66    }
    67}
    

XML 映射器

通过在 XxxMapper.xml 中使用元素来定义各种CRUD操作。

常用的元素如下(按照定义的顺序给出):

  • <sql> – 可被其它语句引用的可重用语句块。
  • <insert> – 映射插入语句。
  • <update> – 映射更新语句。
  • <delete> – 映射删除语句。
  • <select> – 映射查询语句。

Select

查询所有数据

xml 配置文件:

1<select id="selectAll" resultType="user">
2    SELECT *
3    FROM tb_user
4</select>

Mapper 接口方法:

1List<User> selectAll();
  • id:相应 Mapper 接口中的方法名。
  • resultType:相应 Mapper 接口中的返回值类型(可自动封装为对象,不区分大小写)。
  • Mapper 接口返回值:返回一个List<User>。这个返回值可以是UserList<User>ArrayList<User>等,MyBatis会根据返回值自动封装。

根据id字段查询

xml 配置文件:

1<select id="selectById" resultType="user">
2    SELECT * FROM tb_user WHERE id = #{id};
3</select>

Mapper 接口方法:

1User selectById(int id);

<select>中,#{id}为相应 Mapper 接口中的参数 id#{id}被称为参数占位符,相当于JDBC中的?占位符。

多条件动态查询

xml 配置文件:

 1<select id="selectByCondition" resultType="user">
 2    SELECT *
 3    FROM tb_user
 4    <where>
 5        <if test="username != null and username != '' ">
 6            username = #{username}
 7        </if>
 8        <if test="password != null and password != '' ">
 9            AND password = #{password}
10        </if>
11        <if test="gender != null and gender != '' ">
12            AND gender = #{gender}
13        </if>
14        <if test="addr != null and addr != '' ">
15            AND addr = #{addr}
16        </if>
17    </where>
18</select>

多条件查询使用了动态SQL<where><if>。如果仅需查询某部分字段,仅仅使用SQL语句在实现上有难度。而Mybatis就提供了动态SQL方便了我们的实现。

  • <if>:能根据User对象的值来决定是否在SQL语句中加入其包含的语句。

  • <where>:只会在子元素返回任何内容的情况下才插入WHERE子句。

    而且,若子句的开头为ANDOR<where>元素也会将它们去除。

单条件动态查询

xml 配置文件:

 1<select id="selectByConditionSingle" resultMap="brandResultMap">
 2    SELECT *
 3    FROM tb_brand
 4    <where><!--使用where标签确保不会出错-->
 5        <choose><!--相当于switch-->
 6            <when test="status != null"><!--相当于case-->
 7                status = #{status}
 8            </when>
 9            <when test="companyName != null and companyName != '' "><!--相当于case-->
10                company_name like #{companyName}
11            </when>
12            <when test="brandName != null and brandName != '' "><!--相当于case-->
13                brand_name like #{brandName}
14            </when>
15            <!--没有条件输入很可能会报错,使用<otherwise>保底-->
16            <!--如果没有使用<where>,则必须使用<otherwise>-->
17            <!--<otherwise>
18                1 = 1
19            </otherwise>-->
20        </choose>
21    </where>
22</select>

单条件动态查询使用了<where><choose><when><otherwise>,它们都是MyBatis提供的动态SQL元素。

<choose><when>(必须)和<otherwise>元素配合使用。它会根据子元素<when>test属性来判断要选择哪个<when><otherwise>元素。

如果<choose>外没有被<where>包裹则必须使用<otherwise>来包裹一个永真的条件SQL语句,以确保SQL语句不会出错。如果被<where>包裹了,<where>会根据需要判断是否要添加WHERE子句。

<choose><when><otherwise>switch语句的作用十分相似。

Insert

xml 配置文件:

1<insert id="add" useGeneratedKeys="true" keyProperty="id">
2    INSERT INTO tb_user (username, password, ordered, gender,
3                          addr)
4    VALUES (#{username}, #{password}, #{ordered}, #{gender},
5            #{addr});
6</insert>

Mapper 接口方法:

1boolean add(User user);

接口方法直接传入对象即可,对象成员要与 VALUES 子句中的参数一一对应(参数符号中的名称要与对象的成员名称相同)。

如果XML映射中只有一个参数,那么这个参数的名称不必与接口的参数名称相同。

  • id:含义与 <insert> 的含义相同,为相应 Mapper 接口中的方法名(以下 id均为此含义,省略)。

  • useGeneratedKeys

    • 值为 true 时,Mybatis 会使用 JDBC 的 getGeneratedKeys 方法来取出由数据库内部生成的主键(如自增的主键)。
    • 默认为 false
  • keyPropertygetGeneratedKeys 获取到的主键值所要赋予的对象成员名。MyBatis 会使用 getGeneratedKeys 的返回值来设置它的值。

    如,keyProperty="id"——直接将获取到的主键值赋值给 user.id

    如果生成列不止一个,可以用逗号分隔多个属性名称。

  • Mapper 接口返回值:boolean,插入成功返回 true,插入失败返回 false

    返回值也可以选择忽略,将add()接口的返回值设置为void即可。

Update

xml 配置文件:

 1<update id="update">
 2    UPDATE tb_user
 3    <set>
 4        <if test="username != null and username != '' ">
 5            username = #{username},
 6        </if>
 7        <if test="password != null and password != '' ">
 8            password = #{password},
 9        </if>
10        <if test="ordered != null">
11            ordered = #{ordered},
12        </if>
13        <if test="gender != null and (gender == '男' or gender == '女')">
14            gender = #{gender},
15        </if>
16        <if test="addr != null and addr != ''">
17            addr = #{addr}
18        </if>
19    </set>
20    WHERE id = #{id};
21</update>

Mapper 接口方法:

1int update(User user);

<update> 中有一些用 <set> 包裹起来的 <if>。这是因为需要使用 <set> 动态包含需要更新的列,忽略其它不更新的列。从而能根据User对象的值来决定要更新哪些数据,并且动态地改变SQL语句。

Update的Mapper接口返回值是int类型,返回更新的行数。同样可以将接口的返回值设置为void来忽略它。

Delete

删除单行数据

xml 配置文件:

1<delete id="deleteById">
2    DELETE
3    FROM tb_user
4    WHERE id = #{id};
5</delete>

Mapper 接口方法:

1int deleteById(int id);

删除多行数据

xml 配置文件:

 1<delete id="deleteByIds">
 2    DELETE
 3    FROM tb_brand
 4    WHERE id
 5    IN
 6    <!--
 7        <foreach>参数:
 8            - item: 代表数组参数中的每个元素
 9            - separator: 分隔符
10            - open: 插入开始符
11            - close: 插入结束符
12    -->
13    <foreach collection="ids" item="id" separator="," open="(" close=")">
14        #{id}
15    </foreach>
16</delete>

Mapper 接口方法:

1int deleteByIds(@Param("ids") int[] ids);

Mybatis提供了 <foreach> 标签遍历数组,拼接SQL语句。<foreach> 同样也是动态SQL

更多XML映射器请查看官方文档:MyBatis文档——XML映射器

结果映射

resultMap

假设SQL表中的字段与实体类的成员变量名无法一一对应,会导致SQL语句的传参出现问题。例如:

1CREATE table tb_user (
2    user_id INT PRIMARY KEY AUTO_INCREMENT,
3    user_name VARCHAR(20),
4    user_password VARCHAR(20),
5    user_gender CHAR(1),
6    user_addr VARCHAR(30)
7);
 1public class User {
 2    private Integer id;
 3    private String username;
 4    private String password;
 5    private String gender;
 6    private String addr;
 7
 8    // setter 和 getter
 9    // ...
10}

那么可以使用<resultMap>元素来对表字段和成员名做一个映射(结果映射):

 1<!--
 2    <resultMap>:
 3        - id: 唯一标识
 4        - type: 映射的类型,支持别名
 5-->
 6<resultMap id="userResultMap" type="user">
 7    <!--
 8        两种标签:
 9            - <id>: 完成主键字段的映射
10                - column: 表的列名
11                - property: 实体类的属性名
12            - <result>: 完成一般字段的映射
13                - column: 表的列名
14                - property: 实体类的属性名
15    -->
16    <id column="user_id" property="id">
17    <result column="user_name" property="userame"/>
18    <result column="user_password" property="password"/>
19    <result column="user_gender" property="gender"/>
20    <result column="user_addr" property="addr"/>
21</resultMap>
22
23<select id="selectAll" resultMap="userResultMap">
24    SELECT *
25    FROM tb_user
26</select>

要使用结果映射,需要把<select>中的resultType属性替换为resultMap,并且其属性值为<resultMap>id值。

自动映射

当自动映射查询结果时,MyBatis 会获取结果中返回的列名并在 Java 类中查找相同名字的属性(忽略大小写)。

接上节例子,使用SQL语句的 AS 来实现:

1<select id="selectAll" resultType="user">
2    SELECT 
3        user_id AS "id",
4        user_name AS "username",
5        user_password AS "password",
6        user_gender AS gender,
7        user_addr AS "addr"
8    FROM tb_user
9</select>
  • 通常数据库列使用大写字母组成的单词命名,单词间用下划线分隔;而 Java 属性一般遵循驼峰命名法约定。为了在这两种命名方式之间启用自动映射,需要将 mapUnderscoreToCamelCase 设置为 true

    1<!-- 配置mybatis自动转换为驼峰式命名 -->
    2  <settings>
    3    <setting name="mapUnderscoreToCamelCase" value="true"/>
    4</settings>
    
  • <resultMap>和自动映射可以混用。

参数

MyBatis有两种参数:

  • #{p} —— 会自动转义。
  • ${p} —— 不会自动转义。

官方文档:MyBatis——XML映射器参数

MyBatis 参数封装:

  • 单个参数:

    1. POJO类型: 直接使用,保证 属性名参数占位符名称 一致

    2. Map类型: 直接使用,保证 键名参数占位符名称 一致

    3. Collection: 封装为Map集合

      相当于:

      1map.put("arg0", collection集合)
      2map.put("collection", collection集合)
      
      • 使用@Param注解,替换Map集合中默认的arg键名
    4. List: 封装为Map集合

      相当于:

      1map.put("arg0", list集合)
      2map.put("collection", list集合)
      3map.put("list", list集合)
      
      • 使用@Param注解,替换Map集合中默认的arg键名
    5. Array: 封装为Map集合

      相当于:

      1map.put("arg0", 数组)
      2map.put("array", 数组)
      
      • 使用@Param注解,替换Map集合中默认的arg键名
    6. 其他类型: 直接使用,且占位符名称和参数名称可以不相同

  • 多个参数: 封装为Map集合

    • 每个参数有两个键:

      相当于:

      1map.put("arg0", 参数值1)
      2map.put("param1", 参数值1)
      3map.put("arg1", 参数值2)
      4map.put("param2", 参数值2)
      
    • 使用@Param注解,替换Map集合中默认的arg键名:

      相当于:

      1@Param("username") 参数类型 参数名
      2map.put("username", 参数值1)
      3map.put("param1", 参数值1)
      

示例:

1public interface UserMapper {
2    User selectById(int id);
3    List<User> selectByCondition(
4            @Param("username") String username,
5            @Param("password") String password);
6}

注解实现CRUD

对于简单的SQL语句来说,使用注解开发会比配置文件开发更加方便。

1@Select(value = "SELECT * FROM tb_user WHERE id = #{id}")
2User selectById(int id);

注意:注解是用来替换映射配置文件方式配置的,所以使用了注解,就不需要再映射配置文件中书写对应的 statement

Mybatis 针对 CURD 操作都提供了对应的注解:

  • 查询 :@Select
  • 添加 :@Insert
  • 修改 :@Update
  • 删除 :@Delete

注解适合用于完成简单功能,而使用配置文件来完成复杂功能。如果使用注解来完成动态SQL之类的复杂功能,就需要使用到MyBatis提供的SQL构建器来完成。详情请阅读官方SQL构建器文档:MyBatis文档——SQL语句构建器


动态SQL

动态 SQL 是 MyBatis 的强大特性之一。

MyBatis提供的动态SQL元素有:

  • <if>
  • <choose> (<when>, <otherwise>)
  • <trim> (<where>, <set>)
  • <foreach>

更多与动态SQL请查看官方文档:MyBatis文档——动态SQL


SqlSessionFactory工具类抽取

MyBatis重复代码会造成一些问题:

  • 不利于后期的维护。
  • SqlSessionFactory工厂类进行重复创建。

对于Mybatis的基础操作出现的重复代码,可以使用一个静态代码块来自动加载:

 1public class SqlSessionFactoryUtils {
 2
 3    private static SqlSessionFactory sqlSessionFactory;
 4
 5    static {
 6        // 静态代码块会随着类的加载而自动执行,且只执行一次
 7        try {
 8            String resource = "mybatis-config.xml";
 9            InputStream inputStream = Resources.getResourceAsStream(resource);
10            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
11        } catch (IOException e) {
12            e.printStackTrace();
13        }
14    }
15
16
17    public static SqlSessionFactory getSqlSessionFactory(){
18        return sqlSessionFactory;
19    }
20}

工具类抽取以后,以后在对Mybatis的SqlSession进行操作的时候,就可以直接使用:

1SqlSessionFactory sf = SqlSessionFactoryUtils.getSqlSessionFactory();