MyBatis基础入门

1.MyBatis 概述

  • MyBatis 是一个优秀的持久层框架,它对 jdbc 的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建 connection、创建 statement、手动设置参数、结果集检索等 jdbc 繁杂的过程代码。
  • Mybatis 通过 xml 或注解的方式将要执行的各种 statement(statement、preparedStatement、CallableStatement)配置起来,并通过 java 对象和 statement 中的 sql 进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射成 java 对象并返回。

2. 为什么要使用 MyBatis(使用 JDBC 编程有哪些问题)?

  1. 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。

  2. Sql 语句在代码中硬编码,造成代码不易维护,实际应用 sql 变化的可能较大,sql 变动需要改变 java 代码。

  3. 使用 preparedStatement 向占有位符号传参数存在硬编码,因为 sql 语句的 where 条件不一定,可能多也可能少,修改 sql 还要修改代码,系统不易维护。
  4. 对结果集解析存在硬编码(查询列名),sql 变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成 pojo 对象解析比较方便。

3.MyBatis 架构

  1. MyBatis 配置
    • SqlMapConfig.xml,此文件作为 mybatis 的全局配置文件,配置了mybatis 的运行环境等信息

    • mapper.xml 文件即sql 映射文件,文件中配置了操作数据库的 sql 语句。此文件需要在 SqlMapConfig.xml 中加载
  2. 通过 mybatis 环境等配置信息构造SqlSessionFactory 即会话工厂

  3. 由会话工厂创建 sqlSession 即会话,操作数据库需要通过 sqlSession 进行

  4. mybatis 底层自定义了 Executor 执行器接口操作数据库,Executor 接口有两个实现,一个是基本执行器、一个是缓存执行器。
  5. Mapped Statement 也是 mybatis 一个底层封装对象,它包装了 mybatis 配置信息及 sql 映射信息等。mapper.xml 文件中一个 sql 对应一个 Mapped Statement 对象,sql 的 id 即是 Mapped statement 的 id。

  6. Mapped Statement 对 sql 执行输入参数进行定义,包括 HashMap、基本类型、pojo,Executor 通过 Mapped Statement 在执行 sql 前将输入的 java 对象映射至 sql 中,输入参数映射就是 jdbc 编程中对 preparedStatement 设置参数。

  7. Mapped Statement 对 sql 执行输出结果进行定义,包括 HashMap、基本类型、pojo,Executor

4.MyBatis 入门

创建 Maven 工程

修改 pom.xml 导入 MyBatis 以及 Junit 和 MySql 驱动的 jar 包

<dependencies>
        <!-- MySQL 驱动 -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.29</version>
        </dependency>
    <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)">junit </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>junit<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>junit<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>4.12<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">scope</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>test<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">scope</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> mybatis </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
    <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> https://mvnrepository.com/artifact/org.mybatis/mybatis </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">dependency</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>org.mybatis<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">groupId</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>mybatis<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">artifactId</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>3.4.5<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">version</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

   </dependency>

</dependencies>

classpath 目录下创建 MyBatis 的核心配置文件 SqlMapConfig.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

<configuration>
<environments default="development">
<environment id="development">
<!-- 使用 jdbc 事务管理 -->
<transactionManager type="JDBC" />
<!-- 数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value
="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>

<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 加载映射文件 --&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">mappers</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">mapper </span><span style="color: rgba(255, 0, 0, 1)">resource</span><span style="color: rgba(0, 0, 255, 1)">="User.xml"</span> <span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">mappers</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</configuration>

 

创建测试数据库

 

创建 po 类  ---Po 类作为 mybatis 进行 sql 映射使用,po 类通常与数据库表对应

package pojo;
import java.util.Date;
public class User {
    private int id;
    private String username;// 用户姓名
    private String sex;// 性别
    private Date birthday;// 生日
    private String address;// 地址
getter and setter 方法......
    @Override
    public String toString() {
        return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
                + address + "]";
    }      
}

创建 sql 映射文件 User.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">
<!-- namespace: 命名空间, 做 sql 隔离 -->
<mapper namespace="test">
<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 
id:sql语句唯一标识
parameterType:指定传入参数类型
resultType:返回结果集类型
#{}占位符:起到占位作用,如果传入的是基本类型(string,long,double,int,boolean,float等),那么#{}中的变量名称可以随意写.
 </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="findUserById"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="java.lang.Integer"</span><span style="color: rgba(255, 0, 0, 1)"> resultType</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo.User"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
    select * from user where id=#{id}
</span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 
如果返回结果为集合,可以调用selectList方法,这个方法返回的结果就是一个集合,所以映射文件中应该配置成集合泛型的类型
${}拼接符:字符串原样拼接,如果传入的参数是基本类型(string,long,double,int,boolean,float等),那么${}中的变量名称必须是value
注意:拼接符有sql注入的风险,所以慎重使用
 </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="findUserByUserName"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="java.lang.String"</span><span style="color: rgba(255, 0, 0, 1)"> resultType</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo.User"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
    select * from user where username like '%${value}%'
</span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 
#{}:如果传入的是pojo类型,那么#{}中的变量名称必须是pojo中对应的属性.属性.属性.....
如果要返回数据库自增主键:可以使用select LAST_INSERT_ID()
 </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">insert </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="insertUser"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo.User"</span> <span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 执行 select LAST_INSERT_ID()数据库函数,返回自增的主键
    keyProperty:将返回的主键放入传入参数的Id中保存.
    order:当前函数相对于insert语句的执行顺序,在insert前执行是before,在insert后执行是AFTER
    resultType:id的类型,也就是keyproperties中属性的类型
    </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">selectKey </span><span style="color: rgba(255, 0, 0, 1)">keyProperty</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(255, 0, 0, 1)"> order</span><span style="color: rgba(0, 0, 255, 1)">="AFTER"</span><span style="color: rgba(255, 0, 0, 1)"> resultType</span><span style="color: rgba(0, 0, 255, 1)">="java.lang.Integer"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
        select LAST_INSERT_ID()
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">selectKey</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
    insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">insert</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">delete </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="delUserById"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="int"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
    delete from user where id=#{id}
</span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">delete</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

<span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">update </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="updateUserById"</span><span style="color: rgba(255, 0, 0, 1)"> parameterType</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo.User"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
    update user set username=#{username} where id=#{id}
</span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">update</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>

</mapper>

加载映射文件 --mybatis 框架需要加载映射文件,将 User.xml 添加在 SqlMapConfig.xml

<!-- 加载映射文件 -->
    <mappers>
        <mapper resource="User.xml" />
    </mappers>

创建测试类 UserTest 进行测试

查询单个 User 对象

@Test
    public void test1() throws IOException {
        // 核心配置文件
        String resource = "SqlMapConfig.xml";
        // 通过流将核心配置文件加载进来
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 通过配置文件创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 通过会话工厂获取会话
        SqlSession openSession = factory.openSession();
        // 通过会话执行 sql 第一个参数是名称空间 +SqlID 第二个参数表示 sql 执行需要的参数
        User user = openSession.selectOne("test.findUserById", 1);
        System.out.println(user.toString());
        // 关闭会话
        openSession.close();
}</span></pre>

通过 username 进行模糊查询

@Test
    public void test2() throws IOException {
        // 核心配置文件
        String resource = "SqlMapConfig.xml";
        // 通过流将核心配置文件加载进来
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 通过配置文件创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 通过会话工厂获取会话
        SqlSession openSession = factory.openSession();
        // 调用 User.xml 中的魔化查询方法 返回集合
        List<User> selectList = openSession.selectList("test.findUserByName", "张");
        // 循环结果
        System.out.println(selectList.size());
        for (User user : selectList) {System.out.println(user.toString());
        }
        // 关闭会话
        openSession.close();}

添加一条 User 用户到数据库

@Test
    public void test3() throws IOException {
        // 核心配置文件
        String resource = "SqlMapConfig.xml";
        // 通过流将核心配置文件加载进来
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 通过配置文件创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 通过会话工厂获取会话
        SqlSession openSession = factory.openSession();
        // 创建需要插入的 User 对象
        User user = new User();
        user.setUsername("Jimisun");
        user.setSex("1");
        user.setAddress("北京");
        System.out.println("==== 插入前的 User 的 id=" + user.getId());
        // 会话调用插入的 sql
        openSession.insert("test.insertUser", user);
        // 默认 mybatis 自动开启事务, 需要手动提交事务
        openSession.commit();
        System.out.println("==== 插入后的 User 的 id=" + user.getId());
        // 关闭会话
        openSession.close();}

删除一条记录

@Test
    public void test4() throws IOException {
        // 核心配置文件
        String resource = "SqlMapConfig.xml";
        // 通过流将核心配置文件加载进来
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 通过配置文件创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 通过会话工厂获取会话
        SqlSession openSession = factory.openSession();
        // 会话执行 sql 操作
        openSession.delete("test.deleteUserById", 1);
        // 提交事务
        openSession.commit();
        // 关闭会话
        openSession.close();}

更新一条记录

@Test
    public void test5() throws Exception {
        // 核心配置文件
        String resource = "SqlMapConfig.xml";
        // 通过流将核心配置文件加载进来
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 通过配置文件创建会话工厂
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
        // 通过会话工厂获取会话
        SqlSession openSession = factory.openSession();
        //创建 User 对象
        User user = new User ();
        user.setId(1);
        user.setUsername("王麻子");
        openSession.update("test.updateByUserId", user);
        //提交事务
        openSession.commit();
        //关闭会话
        openSession.close();
}</span></pre>

 5. 使用 MyBatis 的开发方法

  • 原生 Dao 方法
    • UserDao  接口
    • UserDaoImpl  实现类
      • findUserById()  ----- 方法内使用 MyBatis 框架进行操作
        // 核心配置文件
                String resource = "SqlMapConfig.xml";
                // 通过流将核心配置文件加载进来
                InputStream inputStream = Resources.getResourceAsStream(resource);
                // 通过配置文件创建会话工厂
                SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
                // 通过会话工厂获取会话
                SqlSession openSession = factory.openSession();
                // 通过会话执行 sql 第一个参数是名称空间 +SqlID 第二个参数表示 sql 执行需要的参数
                User user = openSession.selectOne("test.findUserById", 1);
                System.out.println(user.toString());
                // 关闭会话
                openSession.close();
  • Mapper 接口开发    ----Mapper 接口开发方法只需要程序员编写 Mapper 接口(相当于 Dao 接口),由Mybatis 框架根据接口定义创建接口的动态代理对象,代理对象的方法体同上边 Dao 接口实现类方法。
    • 开发规范
      • Mapper.xml 文件中的 namespace 与 mapper 接口的类路径相同。

      • Mapper 接口方法名和 Mapper.xml 中定义的每个 statement 的 id 相同
      • Mapper 接口方法的输入参数类型和 mapper.xml 中定义的每个 sql 的 parameterType 的类型相同

      • Mapper 接口方法的输出参数类型和 mapper.xml 中定义的每个 sql 的 resultType 的类型相同

    • 开发目录
      • UserDao   接口 遵循上面规则
      • UserServiceImpl 直接调用
            @Test
            public void testFindUserById() throws Exception{
                SqlSession openSession = factory.openSession();
                //通过 getMapper 方法来实例化接口
                UserMapper mapper = openSession.getMapper(UserMapper.class);
        
            User user </span>= mapper.findUserById(1<span style="color: rgba(0, 0, 0, 1)">);
            System.out.println(user);
        }</span></pre>
        

 6.SqlMapConfig.xml 配置文件

  • properties(属性) 常用于加载配置文件
    <properties resource="db.properties"></properties>
    <environments default="development">
            <environment id="development">
            <!-- 使用 jdbc 事务管理-->
            <transactionManager type="JDBC" />
            <!-- 数据库连接池-->
            <dataSource type="POOLED">
                <property name="driver" value="${jdbc.driver}" />
                <property name="url" value="${jdbc.url}" />
                <property name="username" value="${jdbc.username}" />
                <property name="password" value="${jdbc.password}" />
            </dataSource>
            </environment>
    </environments>
  • typeAliases(类型别名)

    <typeAliases> 
            <!-- 定义单个 pojo 类别名
            type: 类的全路劲名称
            alias: 别名
             -->
            <typeAlias type="cn.itheima.pojo.User" alias="user"/> 
    
        <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 使用包扫描的方式批量定义别名 
        定以后别名等于类名,不区分大小写,但是建议按照java命名规则来,首字母小写,以后每个单词的首字母大写
        </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">package </span><span style="color: rgba(255, 0, 0, 1)">name</span><span style="color: rgba(0, 0, 255, 1)">="cn.itheima.pojo"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">typeAliases</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
    
  • mappers(映射器)

    • 相对于类路径的资源
      <mapper resource="sqlmap/User.xml" />
    • 使用 mapper 接口开发
      <mapper class="cn.redrat.mybatis.mapper.UserMapper"/>
    • 注册指定包下所有的 mapper 接口
      <package name="cn.redrat.mybatis.mapper"/>
      • 注意:此种方法要求 mapper 接口名称和 mapper 映射文件名称相同,且放在同一个目录中。

7. 输入映射和输出映射

  • Mapper.xml 映射文件中定义了操作数据库的 sql,每个 sql 是一个 statement,映射文件是 mybatis 的核心。
    • parameterType(输入类型)

      • 传递基本类型包含 String
      • 传递 pojo 对象
      • 传递 vo 对象
    • resultType(输出类型)

      • 返回 pojo 类型
      • 返回集合
      • 返回基本类型包含 String

 

8. 动态 Sql -- 通过 mybatis 提供的各种标签方法实现动态拼接 sql

  • if
    <!-- 传递 pojo 综合查询用户信息   注意要做不等于空字符串校验-->
        <select id="findUserList" parameterType="user" resultType="user">
            select * from user 
            where 1=1 
            <if test="id!=null">
            and id=#{id}
            </if>
            <if test="username!=null and username!=''">
            and username like '%${username}%'
            </if>
    </select>
  • where
    <select id="findUserList" parameterType="user" resultType="user">
            select * from user 
            <where>
            <if test="id!=null and id!=''">
            and id=#{id}
            </if>
            <if test="username!=null and username!=''">
            and username like '%${username}%'
            </if>
            </where>
    </select

     where 标签的作用可以去掉 sql 语句中的 where 1=1 并自动处理第一个 and

  • foreach
    <select id="findUserByIds" parameterType="cn.redrat.pojo.QueryVo" resultType="cn.redrat.pojo.User">
            select * from user
            <where>
                <if test="ids != null">
                    <!-- 
                    foreach: 循环传入的集合参数
                    collection: 传入的集合的变量名称
                    item: 每次循环将循环出的数据放入这个变量中
                    open: 循环开始拼接的字符串
                    close: 循环结束拼接的字符串
                    separator: 循环中拼接的分隔符
                     -->
                    <foreach collection="ids" item="id" open="id in (" close=")" separator=",">
                        #{id}
                    </foreach>
                </if>
            </where>
        </select>

9.MyBatis 关联查询核心示例

  • 一对一查询
    <!-- 一对一: 自动映射 -->
        <select id="findOrdersAndUser1" resultType="cn.redrat.pojo.CustomOrders">
            select a.*, b.id uid, username, birthday, sex, address 
            from orders a, user b 
            where a.user_id = b.id
        </select>
    
    <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 一对一:手动映射 </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
    <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 
    id:resultMap的唯一标识
    type:将查询出的数据放入这个指定的对象中
    注意:手动映射需要指定数据库中表的字段名与java中pojo类的属性名称的对应关系
     </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">resultMap </span><span style="color: rgba(255, 0, 0, 1)">type</span><span style="color: rgba(0, 0, 255, 1)">="cn.<span style="color: rgba(0, 0, 255, 1)">redrat</span>.pojo.Orders"</span><span style="color: rgba(255, 0, 0, 1)"> id</span><span style="color: rgba(0, 0, 255, 1)">="orderAndUserResultMap"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
        <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> id标签指定主键字段对应关系
        column:列,数据库中的字段名称
        property:属性,java中pojo中的属性名称
         </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">id </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        
        <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> result:标签指定非主键字段的对应关系 </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="user_id"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="userId"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="createtime"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="createtime"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="note"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="note"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        
        <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 这个标签指定单个对象的对应关系 
        property:指定将数据放入Orders中的user属性中
        javaType:user属性的类型
        </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">association </span><span style="color: rgba(255, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">="user"</span><span style="color: rgba(255, 0, 0, 1)"> javaType</span><span style="color: rgba(0, 0, 255, 1)">="cn.<span style="color: rgba(0, 0, 255, 1)">redrat</span>.pojo.User"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">id </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="uid"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="username"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="username"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="birthday"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="birthday"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="sex"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="sex"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="address"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="address"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">association</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">resultMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="findOrdersAndUser2"</span><span style="color: rgba(255, 0, 0, 1)"> resultMap</span><span style="color: rgba(0, 0, 255, 1)">="orderAndUserResultMap"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
        select a.*, b.id uid, username, birthday, sex, address 
        from orders a, user b 
        where a.user_id = b.id
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>
    
  • 一对多
    <resultMap type="cn.redrat.pojo.User" id="userAndOrdersResultMap">
            <id column="id" property="id"/>
            <result column="username" property="username"/>
            <result column="birthday" property="birthday"/>
            <result column="sex" property="sex"/>
            <result column="address" property="address"/>
    
        <span style="color: rgba(0, 128, 0, 1)">&lt;!--</span><span style="color: rgba(0, 128, 0, 1)"> 指定对应的集合对象关系映射
        property:将数据放入User对象中的ordersList属性中
        ofType:指定ordersList属性的泛型类型
         </span><span style="color: rgba(0, 128, 0, 1)">--&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">collection </span><span style="color: rgba(255, 0, 0, 1)">property</span><span style="color: rgba(0, 0, 255, 1)">="ordersList"</span><span style="color: rgba(255, 0, 0, 1)"> ofType</span><span style="color: rgba(0, 0, 255, 1)">="cn.<span style="color: rgba(0, 0, 255, 1)">redrat</span>.pojo.Orders"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">id </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="oid"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="id"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="user_id"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="userId"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="number"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
            <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">result </span><span style="color: rgba(255, 0, 0, 1)">column</span><span style="color: rgba(0, 0, 255, 1)">="createtime"</span><span style="color: rgba(255, 0, 0, 1)"> property</span><span style="color: rgba(0, 0, 255, 1)">="createtime"</span><span style="color: rgba(0, 0, 255, 1)">/&gt;</span>
        <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">collection</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">resultMap</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span>
    <span style="color: rgba(0, 0, 255, 1)">&lt;</span><span style="color: rgba(128, 0, 0, 1)">select </span><span style="color: rgba(255, 0, 0, 1)">id</span><span style="color: rgba(0, 0, 255, 1)">="findUserAndOrders"</span><span style="color: rgba(255, 0, 0, 1)"> resultMap</span><span style="color: rgba(0, 0, 255, 1)">="userAndOrdersResultMap"</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span><span style="color: rgba(0, 0, 0, 1)">
        select a.*, b.id oid ,user_id, number, createtime 
        from user a, orders b where a.id = b.user_id
    </span><span style="color: rgba(0, 0, 255, 1)">&lt;/</span><span style="color: rgba(128, 0, 0, 1)">select</span><span style="color: rgba(0, 0, 255, 1)">&gt;</span></pre>