关于java:二MyBatis从入门到入土开发一个Mybatis项目

37次阅读

共计 21379 个字符,预计需要花费 54 分钟才能阅读完成。

这是 mybatis 系列第 2 篇。没看前文的倡议先去【Java 冢狐】公众号中查看前文,不便了解和把握这篇文章次要接着前文介绍了如何创立并应用 Mybatis。

实战演练

上一篇文章中咱们大体介绍了 MyBatis 是如何应用的以及其外部的一些逻辑,也辅助了一些代码进行了解说,上面咱们就把这些代码写完,让整个程序运行起来。

筹备数据库

mysql 中运行上面脚本:创立一个数据库

/* 创立数据库 mybatisdemo*/
DROP DATABASE IF EXISTS `mybatisdemo`;
CREATE DATABASE `mybatisdemo`;
USE `mybatisdemo`;
/* 创立表构造 */
DROP TABLE IF EXISTS `user`;
CREATE TABLE user (
  id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT '主键,用户 id,主动增长',
  `name` VARCHAR(32) NOT NULL DEFAULT ''COMMENT' 姓名 ',
  `age` SMALLINT NOT NULL DEFAULT 1 COMMENT '年龄',
  `salary` DECIMAL(12,2) NOT NULL DEFAULT 0 COMMENT '薪水'
) COMMENT '用户表';
SELECT * FROM user;

下面脚本中,创立了一个 mybatisdemo 数据库,而后创立了一个用户表,外面有 4 个字段,id 为主键且主动增长。

实现的性能

基于 user 表,咱们次要应用 mybatis 来演示以下几个性能

  • 通用的插入操作:反对动静插入。依据传入的字段的值,动静生成 insert 语句
  • 批量插入性能
  • 通用的更新操作:反对动静更新。依据传入的字段的值,动静生成 update 语句
  • 通用的查问操作:反对各种组合条件查问、分页、排序等各种简单查问需要

创立 maven 我的项目

idea 中创立 maven 我的项目,创立一个父我的项目 mybatis-demo 和一个子项目 chat01,如下所示

我的项目构造

如下图:

引入 mybatis 依赖

mybatis-demo/pom.xml 内容如下:

 <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- 配置 maven 编译的时候采纳的编译器版本 -->
        <maven.compiler.compilerVersion>1.8</maven.compiler.compilerVersion>
        <!-- 指定源代码是什么版本的,如果源码和这个版本不符将报错,maven 中执行编译的时候会用到这个配置,默认是 1.5,这个相当于 javac 命令前面的 -source 参数 -->
        <maven.compiler.source>1.8</maven.compiler.source>
        <!-- 该命令用于指定生成的 class 文件将保障和哪个版本的虚拟机进行兼容,maven 中执行编译的时候会用到这个配置,默认是 1.5,这个相当于 javac 命令前面的 -target 参数 -->
        <maven.compiler.target>1.8</maven.compiler.target>
        <mybatis.version>3.5.3</mybatis.version>
        <mysql.version>5.1.47</mysql.version>
        <lombok.version>1.18.10</lombok.version>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.mybatis</groupId>
                <artifactId>mybatis</artifactId>
                <version>${mybatis.version}</version>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <version>${mysql.version}</version>
            </dependency>
            <dependency>
                <groupId>org.projectlombok</groupId>
                <artifactId>lombok</artifactId>
                <version>${lombok.version}</version>
                <scope>provided</scope>
            </dependency>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>4.12</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.2.3</version>

            </dependency>
        </dependencies>
    </dependencyManagement>

chat01/pom.xml 内容如下:

    <dependencies>
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
        </dependency>
    </dependencies>

下面咱们引入了 mybatis 须要的包、mysql jdbc 驱动、lombok、单元测试须要的 junit 包、日志输入须要的 logback 包。

配置 logback

mybatis 在运行过程中会输入一些日志,比方 sql 信息、sql 的参数信息、执行的后果等信息,mybatis 中会通过 logback 输入进去。

在 chat01/src/main/resources 目录中新建文件 logback.xml,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name="zhonghu" level="debug" additivity="false">
        <appender-ref ref="STDOUT" />
    </logger>
</configuration>

创立 mybatis 相干文件

user.xml

chat01/src/main/resources 目录中新建 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">
<mapper namespace="zhonghu.mybatis.chat01.UserMapper">

    <!-- 插入 -->
    <insert id="insert" parameterType="zhonghu.mybatis.chat01.UserModel" keyProperty="id" useGeneratedKeys="true">
        <![CDATA[ INSERT INTO `user`]]>
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id!=null">
                <![CDATA[ `id`,]]>
            </if>
            <if test="name!=null">
                <![CDATA[ `name`,]]>
            </if>
            <if test="age!=null">
                <![CDATA[ `age`,]]>
            </if>
            <if test="salary!=null">
                <![CDATA[ `salary`,]]>
            </if>
        </trim>
        <![CDATA[ VALUES]]>
        <trim prefix="(" suffix=")" suffixOverrides=",">
            <if test="id!=null">
                <![CDATA[ #{id}, ]]>
            </if>
            <if test="name!=null">
                <![CDATA[ #{name}, ]]>
            </if>
            <if test="age!=null">
                <![CDATA[ #{age}, ]]>
            </if>
            <if test="salary!=null">
                <![CDATA[ #{salary}, ]]>
            </if>
        </trim>
    </insert>

    <!-- 批量插入 -->
    <insert id="insertBatch" parameterType="map">
        <![CDATA[ INSERT INTO `user` (`id`, `name`, `age`, `salary`) VALUES ]]>
        <foreach collection="list" separator="," item="item">
            (#{item.id}, #{item.name}, #{item.age}, #{item.salary})
        </foreach>
    </insert>

    <!-- 更新 -->
    <update id="update" parameterType="zhonghu.mybatis.chat01.UserModel">
        <![CDATA[ UPDATE `user`]]>
        <set>
            <if test="name!=null">
                <![CDATA[ `name` = #{name}, ]]>
            </if>
            <if test="age!=null">
                <![CDATA[ `age` = #{age}, ]]>
            </if>
            <if test="salary!=null">
                <![CDATA[ `salary` = #{salary}, ]]>
            </if>
        </set>
        <where>
            <if test="id!=null">
                <![CDATA[ AND `id` = #{id} ]]>
            </if>
        </where>
    </update>

    <!-- 更新 -->
    <update id="updateByMap" parameterType="map">
        <![CDATA[ UPDATE `user`]]>
        <set>
            <if test="name!=null">
                <![CDATA[ `name` = #{name}, ]]>
            </if>
            <if test="age!=null">
                <![CDATA[ `age` = #{age}, ]]>
            </if>
            <if test="salary!=null">
                <![CDATA[ `salary` = #{salary}, ]]>
            </if>
        </set>
        <where>
            <if test="id!=null">
                <![CDATA[ AND `id` = #{id} ]]>
            </if>
        </where>
    </update>

    <!-- 删除 -->
    <delete id="delete" parameterType="map">
        <![CDATA[DELETE FROM `user`]]>
        <where>
            <if test="id!=null">
                <![CDATA[ AND `id` = #{id} ]]>
            </if>
        </where>
    </delete>


    <!-- 查问记录 -->
    <select id="getModelList" parameterType="map" resultType="zhonghu.mybatis.chat01.UserModel">
        <![CDATA[SELECT]]>
        <choose>
            <when test="tableColumnList!=null and tableColumnList.size() >= 1">
                <foreach collection="tableColumnList" item="item" separator=",">
                    <![CDATA[ ${item} ]]>
                </foreach>
            </when>
            <otherwise>
                <![CDATA[
                `id`,
                `name`,
                `age`,
                `salary`
                ]]>
            </otherwise>
        </choose>
        <![CDATA[
        FROM
        `user` a
        ]]>
        <where>
            <if test="id!=null and id.toString()!=''">
                <![CDATA[ AND a.`id` = #{id} ]]>
            </if>
            <if test="idList!=null and idList.size() >= 1">
                <![CDATA[ AND a.`id` IN]]>
                <foreach collection="idList" item="item" open="(" separator="," close=")">
                    <![CDATA[ #{item} ]]>
                </foreach>
            </if>
            <if test="name!=null and name.toString()!=''">
                <![CDATA[ AND a.`name` = #{name} ]]>
            </if>
            <if test="age!=null and age.toString()!=''">
                <![CDATA[ AND a.`age` = #{age} ]]>
            </if>
            <if test="salary!=null and salary.toString()!=''">
                <![CDATA[ AND a.`salary` = #{salary} ]]>
            </if>
            <if test="nameLike!=null and nameLike.toString()!=''">
                <![CDATA[ AND a.`name` like '%${nameLike}%' ]]>
            </if>
            <if test="salaryGte!=null and salaryGte.toString()!=''">
                <![CDATA[ AND a.`salary` >= #{salaryGte} ]]>
            </if>
        </where>
        <if test="sort!=null and sort.toString()!=''">
            <![CDATA[ order by ${sort} ]]>
        </if>
        <if test="skip!=null and pageSize!=null">
            <![CDATA[ LIMIT #{skip},#{pageSize} ]]>
        </if>
    </select>

</mapper>
mybatis-config.xml

chat01/src/main/resources 目录中新建 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>
    <properties>
        <property name="driver" value="com.mysql.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mybatisdemo?characterEncoding=UTF-8"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    </properties>
    <environments default="development">
        <environment id="development">
            <transactionManager type="JDBC"/>
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
        <mapper resource="mapper/user.xml"/>
    </mappers>
</configuration>

UserMapper 接口

package zhonghu.mybatis.chat01;

import java.util.List;
import java.util.Map;

public interface UserMapper {

    /**
     * 插入用户信息
     *
     * @param userModel
     * @return
     */
    void insert(UserModel userModel);

    /**
     * 批量插入用户信息
     *
     * @param userModelList
     */
    void insertBatch(List<UserModel> userModelList);

    /**
     * 更新用户信息
     *
     * @param userModel
     * @return
     */
    int update(UserModel userModel);

    /**
     * 通过 map 来更新用户记录
     *
     * @param map
     * @return
     */
    int updateByMap(Map<String, Object> map);

    /**
     * 通过 map 来删除用户记录
     *
     * @param map
     * @return
     */
    int delete(Map<String, Object> map);

    /**
     * 查问用户列表
     *
     * @param map
     * @return
     */
    List<UserModel> getModelList(Map<String, Object> map);

}
UserModel 类
package zhonghu.mybatis.chat01;

import lombok.*;

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@ToString
public class UserModel {
    private Long id;
    private String name;
    private Integer age;
    private Double salary;
}

这个类下面的注解都是都是 lombok 中的,通过这些注解,lombok 能够帮忙咱们主动生成下面 4 个字段的 get 办法、set 办法、无参构造方法、有参有参构造方法、builder 模式构建对象的代码、重写 toString 办法,这些都在代码编译为字节码之前会写进去,通过 lombok 代码是不是精简了很多。

UserUtil 类
package zhonghu.mybatis.chat01;

import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;

@Slf4j
public class UserUtil {private static SqlSessionFactory sqlSessionFactory = build();

    public static SqlSessionFactory build() {
        try {return new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {log.error(e.getMessage(), e);
            throw new RuntimeException(e);
        }
    }

    @FunctionalInterface
    public interface SessionCall<O> {O call(SqlSession session) throws Exception;
    }

    @FunctionalInterface
    public interface MapperCall<T, O> {O call(T mapper) throws Exception;
    }

    public static <T, O> O callMapper(Class<T> tClass, MapperCall<T, O> mapper) throws Exception {return call(session -> mapper.call(session.getMapper(tClass)));
    }

    public static <O> O call(SessionCall<O> sessionCall) throws Exception {try (SqlSession session = sqlSessionFactory.openSession(true);) {return sessionCall.call(session);
        }
    }
}

创立单元测试类 UserMapperTest

chat01\src\test\java\zhonghu\mybatis\chat01 中创立 UserMapperTest,代码如下:

package zhonghu.mybatis.chat01;

import lombok.extern.slf4j.Slf4j;
import org.junit.Test;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
public class UserMapperTest {

    // 动静插入
    @Test
    public void insert() throws Exception {UserModel userModel1 = UserModel.builder().name("Java 冢狐").build();
        UserUtil.callMapper(UserMapper.class, mapper -> {mapper.insert(userModel1);
            return null;
        });
        log.info("插入后果:{}", this.getModelById(userModel1.getId()));
        log.info("---------------------");
        UserModel userModel2 = UserModel.builder().name("冢狐").age(23).salary(50000.00).build();
        UserUtil.callMapper(UserMapper.class, mapper -> {mapper.insert(userModel2);
            return null;
        });
        log.info("插入后果:{}", this.getModelById(userModel2.getId()));
    }

    // 批量插入
    @Test
    public void insertBatch() throws Exception {List<UserModel> userModelList = new ArrayList<>();
        for (int i = 1; i <= 5; i++) {userModelList.add(UserModel.builder().name("Java 冢狐 -" + i).age(23 + i).salary(10000.00 * i).build());
            userModelList.add(UserModel.builder().name("Mybatis-" + i).age(18 + i).salary(10000.00 * i).build());
        }
        UserUtil.callMapper(UserMapper.class, mapper -> {mapper.insertBatch(userModelList);
            return null;
        });

        List<UserModel> userModelList1 = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(null));
        log.info("后果:{}", userModelList1);
    }

    // 依据用户 id 删除数据
    @Test
    public void delete() throws Exception {Map<String, Object> map = new HashMap<>();
        // 须要删除的用户 id
        map.put("id", 1);
        Integer count = UserUtil.callMapper(UserMapper.class, mapper -> mapper.delete(map));
        log.info("删除行数:{}", count);
    }

    // 动静更新
    @Test
    public void update() throws Exception {
        // 将 userId= 2 的 name 批改为:批改冢狐
        Long userId1 = 2L;
        Integer count = UserUtil.callMapper(UserMapper.class, mapper -> mapper.update(UserModel.builder().id(userId1).name("批改冢狐").build()));
        log.info("更新行数:{}", count);

        log.info("---------------------");
        // 将 userId= 3 的 name 批改为:批改冢狐, 薪水为:6666.66
        Long userId2 = 3L;
        count = UserUtil.callMapper(UserMapper.class, mapper -> mapper.update(UserModel.builder().id(userId2).name("批改冢狐").salary(6666.66D).build()));
        log.info("更新行数:{}", count);
    }

    // 按用户 id 查问
    public UserModel getModelById(Long userId) throws Exception {
        // 查问指定 id 的数据
        Map<String, Object> map = new HashMap<>();
        map.put("id", userId);
        return UserUtil.callMapper(UserMapper.class, mapper -> {List<UserModel> userModelList = mapper.getModelList(map);
            if (userModelList.size() == 1) {return userModelList.get(0);
            }
            return null;
        });
    }

    // 查问所有数据
    @Test
    public void getModelList1() throws Exception {List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(null));
        log.info("后果:{}", userModelList);
    }

    // 查问多个用户 id 对应的数据
    @Test
    public void getModelListByIds() throws Exception {List<Integer> idList = Arrays.asList(2, 3, 4).stream().collect(Collectors.toList());
        Map<String, Object> map = new HashMap<>();
        map.put("idList", idList);

        List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(map));
        log.info("后果:{}", userModelList);
    }

    // 多条件 & 指定返回的列
    @Test
    public void getModelList2() throws Exception {
        // 查问姓名中蕴含 Java 冢狐以及薪资大于 3 万的用户 id、姓名
        Map<String, Object> map = new HashMap<>();
        map.put("nameLike", "Java 冢狐");
        map.put("salaryGte", 30000.00D);
        // 须要返回的列
        List<String> tableColumnList = new ArrayList<>();
        tableColumnList.add("id");
        tableColumnList.add("name");
        map.put("tableColumnList", tableColumnList);

        List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(map));
        log.info("后果:{}", userModelList);
    }

    // 条件过滤 & 排序 & 分页查问数据 & 只返回用户 id、salary
    @Test
    public void getPage() throws Exception {
        // 查问姓名中蕴含 Java 冢狐以及薪资大于 3 万的用户 id,依照薪资顺叙,每页 5 条取第 1 页
        Map<String, Object> map = new HashMap<>();
        map.put("nameLike", "Java 冢狐");
        map.put("salaryGte", 30000.00D);

        // 退出排序参数
        map.put("sort", "salary desc");

        // 退出分页参数
        int page = 1;
        int pageSize = 5;
        map.put("skip", (page - 1) * pageSize);
        map.put("pageSize", pageSize);

        // 退出须要返回的列
        List<String> tableColumnList = new ArrayList<>();
        tableColumnList.add("id");
        tableColumnList.add("salary");
        map.put("tableColumnList", tableColumnList);

        List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(map));
        log.info("后果:{}", userModelList);
    }
}

我的项目最终构造如下

测试:动静插入

运行动静插入,输入如下:

29:45.734 [main] DEBUG z.mybatis.chat01.UserMapper.insert - ==>  Preparing: INSERT INTO `user` (`name`) VALUES (?) 
29:45.755 [main] DEBUG z.mybatis.chat01.UserMapper.insert - ==> Parameters: Java 冢狐 (String)
29:45.843 [main] DEBUG z.mybatis.chat01.UserMapper.insert - <==    Updates: 1
29:45.859 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a WHERE a.`id` = ? 
29:45.859 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 1(Long)
29:45.871 [main] DEBUG z.m.chat01.UserMapper.getModelList - <==      Total: 1
29:45.871 [main] INFO  z.mybatis.chat01.UserMapperTest - 插入后果:UserModel(id=1, name=Java 冢狐, age=1, salary=0.0)
29:45.873 [main] INFO  z.mybatis.chat01.UserMapperTest - ---------------------
29:45.873 [main] DEBUG z.mybatis.chat01.UserMapper.insert - ==>  Preparing: INSERT INTO `user` (`name`, `age`, `salary`) VALUES (?, ?, ?) 
29:45.874 [main] DEBUG z.mybatis.chat01.UserMapper.insert - ==> Parameters: 冢狐 (String), 23(Integer), 50000.0(Double)
29:46.081 [main] DEBUG z.mybatis.chat01.UserMapper.insert - <==    Updates: 1
29:46.082 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a WHERE a.`id` = ? 
29:46.082 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 2(Long)
29:46.083 [main] DEBUG z.m.chat01.UserMapper.getModelList - <==      Total: 1
29:46.083 [main] INFO  z.mybatis.chat01.UserMapperTest - 插入后果:UserModel(id=2, name= 冢狐, age=23, salary=50000.0)
  • 数据库数据变为:

这个办法次要有 4 步操作:

  • 插入一条用户记录,用户记录只有 name 字段有值
  • 去 db 中查问步骤 1 中插入的记录
  • 插入一条用户记录,这次插入的记录所有字段都指定了值
  • 去 db 中查问步骤 3 中插入的记录

两次插入调用都是 mapper.insert 办法,传入的都是 UserModel 对象,惟一不同的是这个对象构建的时候字段的值不一样,最初再认真看一下下面输入的 sql,产生的 2 个 insert 也是不一样的,这个 mapper.insert 办法能够依据 UserModel 对象字段是否有值来组装咱们须要的 sql,这就实现了动静插入

测试:批量插入

运行批量插入,输入如下:

33:49.134 [main] DEBUG z.m.chat01.UserMapper.insertBatch - ==>  Preparing: INSERT INTO `user` (`id`, `name`, `age`, `salary`) VALUES (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) 
33:49.155 [main] DEBUG z.m.chat01.UserMapper.insertBatch - ==> Parameters: null, Java 冢狐 -1(String), 24(Integer), 10000.0(Double), null, Mybatis-1(String), 19(Integer), 10000.0(Double), null, Java 冢狐 -2(String), 25(Integer), 20000.0(Double), null, Mybatis-2(String), 20(Integer), 20000.0(Double), null, Java 冢狐 -3(String), 26(Integer), 30000.0(Double), null, Mybatis-3(String), 21(Integer), 30000.0(Double), null, Java 冢狐 -4(String), 27(Integer), 40000.0(Double), null, Mybatis-4(String), 22(Integer), 40000.0(Double), null, Java 冢狐 -5(String), 28(Integer), 50000.0(Double), null, Mybatis-5(String), 23(Integer), 50000.0(Double)
33:49.378 [main] DEBUG z.m.chat01.UserMapper.insertBatch - <==    Updates: 10
33:49.387 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a 
33:49.387 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 
33:49.397 [main] DEBUG z.m.chat01.UserMapper.getModelList - <==      Total: 12
33:49.397 [main] INFO  z.mybatis.chat01.UserMapperTest - 后果:[UserModel(id=1, name=Java 冢狐, age=1, salary=0.0), UserModel(id=2, name= 冢狐, age=23, salary=50000.0), UserModel(id=3, name=Java 冢狐 -1, age=24, salary=10000.0), UserModel(id=4, name=Mybatis-1, age=19, salary=10000.0), UserModel(id=5, name=Java 冢狐 -2, age=25, salary=20000.0), UserModel(id=6, name=Mybatis-2, age=20, salary=20000.0), UserModel(id=7, name=Java 冢狐 -3, age=26, salary=30000.0), UserModel(id=8, name=Mybatis-3, age=21, salary=30000.0), UserModel(id=9, name=Java 冢狐 -4, age=27, salary=40000.0), UserModel(id=10, name=Mybatis-4, age=22, salary=40000.0), UserModel(id=11, name=Java 冢狐 -5, age=28, salary=50000.0), UserModel(id=12, name=Mybatis-5, age=23, salary=50000.0)]

这次批量插入了 10 条用户记录,能够看到有这样的输入:

33:49.378 [main] DEBUG z.m.chat01.UserMapper.insertBatch - <==    Updates: 10

下面这个示意插入影响的行数,10 示意插入了 10 行。

批量插入之后,又执行了全表查问,这次插入了 10 条,加上后面的 2 个单条插入,表中总计 12 条记录。

  • 数据库数据变为:

测试:依据用户 id 删除数据

运行删除,输入如下:

44:52.064 [main] DEBUG z.mybatis.chat01.UserMapper.delete - ==>  Preparing: DELETE FROM `user` WHERE `id` = ? 
44:52.083 [main] DEBUG z.mybatis.chat01.UserMapper.delete - ==> Parameters: 1(Integer)
44:52.383 [main] DEBUG z.mybatis.chat01.UserMapper.delete - <==    Updates: 1
44:52.386 [main] INFO  z.mybatis.chat01.UserMapperTest - 删除行数:1
  • 数据库后果如下:

测试:动静更新

运行动静更新代码,输入如下:

45:44.648 [main] DEBUG z.mybatis.chat01.UserMapper.update - ==>  Preparing: UPDATE `user` SET `name` = ? WHERE `id` = ? 
45:44.670 [main] DEBUG z.mybatis.chat01.UserMapper.update - ==> Parameters: 批改冢狐 (String), 2(Long)
45:44.788 [main] DEBUG z.mybatis.chat01.UserMapper.update - <==    Updates: 1
45:44.790 [main] INFO  z.mybatis.chat01.UserMapperTest - 更新行数:1
45:44.792 [main] INFO  z.mybatis.chat01.UserMapperTest - ---------------------
45:44.793 [main] DEBUG z.mybatis.chat01.UserMapper.update - ==>  Preparing: UPDATE `user` SET `name` = ?, `salary` = ? WHERE `id` = ? 
45:44.793 [main] DEBUG z.mybatis.chat01.UserMapper.update - ==> Parameters: 批改冢狐 (String), 6666.66(Double), 3(Long)
45:44.980 [main] DEBUG z.mybatis.chat01.UserMapper.update - <==    Updates: 1
45:44.981 [main] INFO  z.mybatis.chat01.UserMapperTest - 更新行数:1

2 个更新,调用都是 mapper.update 办法,传入的都是 UserModel 类型的参数,只是 2 个 UserModel 对象的字段值不一样,最初产生的 2 个 update 语句也是不一样的,这个 update 语句是 mybatis 动静组装的,mybatis 能够依据 UserModel 中字段是否为 NULL,来拼装 sql。

  • 数据库后果

测试:动静查问

查问所有数据

运行查问有数据代码,输入如下:

46:56.345 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a 
46:56.364 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 
46:56.376 [main] DEBUG z.m.chat01.UserMapper.getModelList - <==      Total: 11
46:56.380 [main] INFO  z.mybatis.chat01.UserMapperTest - 后果:[UserModel(id=2, name= 批改冢狐, age=23, salary=50000.0), UserModel(id=3, name= 批改冢狐, age=24, salary=6666.66), UserModel(id=4, name=Mybatis-1, age=19, salary=10000.0), UserModel(id=5, name=Java 冢狐 -2, age=25, salary=20000.0), UserModel(id=6, name=Mybatis-2, age=20, salary=20000.0), UserModel(id=7, name=Java 冢狐 -3, age=26, salary=30000.0), UserModel(id=8, name=Mybatis-3, age=21, salary=30000.0), UserModel(id=9, name=Java 冢狐 -4, age=27, salary=40000.0), UserModel(id=10, name=Mybatis-4, age=22, salary=40000.0), UserModel(id=11, name=Java 冢狐 -5, age=28, salary=50000.0), UserModel(id=12, name=Mybatis-5, age=23, salary=50000.0)]

能够看到 sql 是没有查问条件的。

查问多个用户 id 对应的数据

运行查问多个用户 id 对应数据,输入如下:

47:46.118 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT `id`, `name`, `age`, `salary` FROM `user` a WHERE a.`id` IN (? , ? , ?) 
47:46.139 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 2(Integer), 3(Integer), 4(Integer)
47:46.150 [main] DEBUG z.m.chat01.UserMapper.getModelList - <==      Total: 3
47:46.151 [main] INFO  z.mybatis.chat01.UserMapperTest - 后果:[UserModel(id=2, name= 批改冢狐, age=23, salary=50000.0), UserModel(id=3, name= 批改冢狐, age=24, salary=6666.66), UserModel(id=4, name=Mybatis-1, age=19, salary=10000.0)]

下面这个依照 id 列表查问也是比拟罕用的,比方咱们在电商中查问订单列表,还须要查问每个订单对应的商品,此时能够先查问订单列表,而后在通过订单列表拿到所有的商品 id 汇合,而后通过商品 id 汇合去通过下面的形式检索商品信息,只须要 2 次查问就能够查问出订单及商品的信息了。

多条件 & 指定返回的列

运行多条件查问语句,查问姓名中蕴含 Java 冢狐以及薪资大于 3 万的用户 id、姓名,输入如下:

48:34.925 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT id , name FROM `user` a WHERE a.`name` like '%Java 冢狐 %' AND a.`salary` >= ? 
48:34.945 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 30000.0(Double)
48:34.955 [main] DEBUG z.m.chat01.UserMapper.getModelList - <==      Total: 3
48:34.955 [main] INFO  z.mybatis.chat01.UserMapperTest - 后果:[UserModel(id=7, name=Java 冢狐 -3, age=null, salary=null), UserModel(id=9, name=Java 冢狐 -4, age=null, salary=null), UserModel(id=11, name=Java 冢狐 -5, age=null, salary=null)]

看一下下面 select 语句,select 前面只有 id,name2 个字段,where 前面有多个条件,这种查问也是比拟罕用的,有些表可能有几十个字段,可能咱们只须要几个字段,就能够应用下面这种查问。

条件过滤 & 排序 & 分页查问数据 & 只返回用户 id、salary

运行分页查问,查问姓名中蕴含 Java 冢狐以及薪资大于 3 万的用户 id,依照薪资顺叙,每页 5 条取第 1 页,输入如下:

49:03.709 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT id , salary FROM `user` a WHERE a.`name` like '%Java 冢狐 %' AND a.`salary` >= ? order by salary desc LIMIT ?,? 
49:03.728 [main] DEBUG z.m.chat01.UserMapper.getModelList - ==> Parameters: 30000.0(Double), 0(Integer), 5(Integer)
49:03.739 [main] DEBUG z.m.chat01.UserMapper.getModelList - <==      Total: 3
49:03.740 [main] INFO  z.mybatis.chat01.UserMapperTest - 后果:[UserModel(id=11, name=null, age=null, salary=50000.0), UserModel(id=9, name=null, age=null, salary=40000.0), UserModel(id=7, name=null, age=null, salary=30000.0)]

大家次要看一下输入的 sql,如下:

SELECT id , salary FROM `user` a WHERE a.`name` like '%Java 冢狐 %' AND a.`salary` >= ? order by salary desc LIMIT ?,?

这个 sql 会依据查问条件,主动构建出咱们须要的 sql,非常的不便和简洁

案例总结

下面列举的一些用例基本上蕴含了咱们对 db 所需的大部分操作,动静 sql 解决方面体现的最为强劲,如果让咱们本人写,咱们须要写很多判断,而用 mybatis 这么简略就实现了,咱们在 java 代码中没有看到一个判断拼接语句,而这些 sql 的判断拼接都在一个文件中:user.xml 中,这个就是 mybatis 中外围的文件,咱们须要写的 sql 及判断逻辑基本上都在这个 xml 中,大家能够认真去看一下这个 xml 文件。

最初

  • 如果感觉看完有播种,心愿能关注一下,顺便给我点个赞,这将会是我更新的最大能源,感激各位的反对
  • 欢送各位关注我的公众号【java 冢狐】,专一于 java 和计算机基础知识,保障让你看完有所播种,不信你打我
  • 求一键三连:点赞、转发、在看。
  • 如果看完有不同的意见或者倡议,欢送多多评论一起交换。感激各位的反对以及厚爱。

——我是冢狐,和你一样酷爱编程。

欢送关注公众号“Java 冢狐”,获取最新消息

正文完
 0