MyBatis系列第2篇:入门篇,带你感受一下mybatis独特的魅力!

Mybatis系列目标:从入门开始开始掌握一个高级开发所需要的Mybatis技能。

这是mybatis系列第2篇。

本篇技术栈

  1. mysql5.7.25

  2. maven3.6.1

  3. jdk1.8

  4. idea

本篇主要内容

  1. 通过一个案例感受一下mybatis的强大之处

  2. mybatis开发项目的具体步骤

  3. 介绍mybatis中主要的几个对象

我们先来一个案例,让大家感受一下mybatis是多么的牛逼,我相信大家看了案例之后,会强烈的激发大家学习mybatis的兴趣。

案例:原来ibatis是这么强大

下面的案例,大家先不用关系代码为什么这么写,先感受一下效果,后面我们再来细说代码,案例代码文章尾部有获取方式

准备数据库

mysql中运行下面脚本:


       
       
  1. /*创建数据库javacode2018*/
  2. DROP DATABASE IF EXISTS  `javacode2018`;
  3. CREATE DATABASE  `javacode2018`;
  4. USE  `javacode2018`;
  5. /*创建表结构*/
  6. DROP TABLE IF EXISTS  `t_user`;
  7. CREATE TABLE t_user (
  8.   id BIGINT AUTO_INCREMENT PRIMARY KEY COMMENT  '主键,用户id,自动增长',
  9.    `name` VARCHAR( 32) NOT NULL DEFAULT  '' COMMENT  '姓名',
  10.    `age` SMALLINT NOT NULL DEFAULT  1 COMMENT  '年龄',
  11.    `salary` DECIMAL( 12, 2) NOT NULL DEFAULT  0 COMMENT  '薪水'
  12. ) COMMENT  '用户表';
  13. SELECT * FROM t_user;

上面脚本中,创建了一个javacode2018数据库,然后创建了一个用户表,里面有4个字段,id为主键自动增长。

我们的需求

对t_user表,我们有以下这些需求:

  1. 实现一个通用的插入操作:支持动态插入,可以根据传入的字段的值,动态生成所需要的各种insert语句

  2. 批量插入功能

  3. 实现一个通用的更新操作:支持动态更新操作,可以根据传入的字段,动态生成所需要的各种update语句

  4. 实现一个通用的查询操作:支持各种组合条件查询、支撑排序、分页、支持返回列的控制等各种复杂的查询需求

下面我们就来一个案例,将上面这些需求通过mybatis实现,先见证一下mybatis的强大之处。

创建maven项目

idea中创建maven项目,这个操作在maven系列中已经说过很多次了,以后大部分项目都是通过maven来玩的,maven这方面玩的不是太溜的,可以跳到文章尾部去看一下maven系列的文章。

项目采用maven中聚合及继承的方式来管理。

创建父项目

先创建父项目mybatis-series,父项目的坐标信息:


       
       
  1. <groupId>com.javacode2018</groupId>
  2. <artifactId>mybatis-series</artifactId>
  3. <version> 1.0-SNAPSHOT</version>
创建子项目

创建一个子模块chat01,子模块的坐标信息:


       
       
  1. <groupId>com.javacode2018</groupId>
  2. <artifactId>chat01</artifactId>
  3. <version> 1.0-SNAPSHOT</version>
项目结构

如下图:

引入mybatis依赖

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


       
       
  1. <?xml version= "1.0" encoding= "UTF-8"?>
  2. <project xmlns= "http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <modelVersion> 4.0 .0</modelVersion>
  6.     <groupId>com.javacode2018</groupId>
  7.     <artifactId>mybatis-series</artifactId>
  8.     <version> 1.0-SNAPSHOT</version>
  9.     <packaging>pom</packaging>
  10.     <modules>
  11.         <module>chat01</module>
  12.     </modules>
  13.     <properties>
  14.         <project.build.sourceEncoding>UTF -8</project.build.sourceEncoding>
  15.         <!-- 配置maven编译的时候采用的编译器版本 -->
  16.         <maven.compiler.compilerVersion> 1.8</maven.compiler.compilerVersion>
  17.         <!-- 指定源代码是什么版本的,如果源码和这个版本不符将报错,maven中执行编译的时候会用到这个配置,默认是 1.5,这个相当于javac命令后面的-source参数 -->
  18.         <maven.compiler.source> 1.8</maven.compiler.source>
  19.         <!-- 该命令用于指定生成的class文件将保证和哪个版本的虚拟机进行兼容,maven中执行编译的时候会用到这个配置,默认是 1.5,这个相当于javac命令后面的-target参数 -->
  20.         <maven.compiler.target> 1.8</maven.compiler.target>
  21.         <mybatis.version> 3.5 .3</mybatis.version>
  22.         <mysql.version> 5.1 .47</mysql.version>
  23.         <lombok.version> 1.18 .10</lombok.version>
  24.     </properties>
  25.     <dependencyManagement>
  26.         <dependencies>
  27.             <dependency>
  28.                 <groupId>org.mybatis</groupId>
  29.                 <artifactId>mybatis</artifactId>
  30.                 <version>${mybatis.version}</version>
  31.             </dependency>
  32.             <dependency>
  33.                 <groupId>mysql</groupId>
  34.                 <artifactId>mysql-connector-java</artifactId>
  35.                 <version>${mysql.version}</version>
  36.             </dependency>
  37.             <dependency>
  38.                 <groupId>org.projectlombok</groupId>
  39.                 <artifactId>lombok</artifactId>
  40.                 <version>${lombok.version}</version>
  41.                 <scope>provided</scope>
  42.             </dependency>
  43.             <dependency>
  44.                 <groupId>junit</groupId>
  45.                 <artifactId>junit</artifactId>
  46.                 <version> 4.12</version>
  47.                 <scope>test</scope>
  48.             </dependency>
  49.             <dependency>
  50.                 <groupId>ch.qos.logback</groupId>
  51.                 <artifactId>logback-classic</artifactId>
  52.                 <version> 1.2 .3</version>
  53.             </dependency>
  54.         </dependencies>
  55.     </dependencyManagement>
  56. </project>

chat01/pom.xml内容如下:


       
       
  1. <?xml version= "1.0" encoding= "UTF-8"?>
  2. <project xmlns= "http://maven.apache.org/POM/4.0.0"
  3.          xmlns:xsi= "http://www.w3.org/2001/XMLSchema-instance"
  4.          xsi:schemaLocation= "http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  5.     <parent>
  6.         <artifactId>mybatis-series</artifactId>
  7.         <groupId>com.javacode2018</groupId>
  8.         <version> 1.0-SNAPSHOT</version>
  9.     </parent>
  10.     <modelVersion> 4.0 .0</modelVersion>
  11.     <artifactId>chat01</artifactId>
  12.     <dependencies>
  13.         <dependency>
  14.             <groupId>org.mybatis</groupId>
  15.             <artifactId>mybatis</artifactId>
  16.         </dependency>
  17.         <dependency>
  18.             <groupId>mysql</groupId>
  19.             <artifactId>mysql-connector-java</artifactId>
  20.         </dependency>
  21.         <dependency>
  22.             <groupId>org.projectlombok</groupId>
  23.             <artifactId>lombok</artifactId>
  24.         </dependency>
  25.         <dependency>
  26.             <groupId>junit</groupId>
  27.             <artifactId>junit</artifactId>
  28.         </dependency>
  29.         <dependency>
  30.             <groupId>ch.qos.logback</groupId>
  31.             <artifactId>logback-classic</artifactId>
  32.         </dependency>
  33.     </dependencies>
  34. </project>

上面我们引入了mybatis需要的包、mysql jdbc驱动、lombok、单元测试需要的junit包、日志输出需要的logback包。

这里lombok可能大家没有用过,这个东西可以自动帮我们生成javabean的一些代码,比如get、set方法,可以节省开发编写代码的量,这个以后有空了写一篇文章来介绍。

配置logback

mybatis在运行过程中会输出一些日志,比如sql信息、sql的参数信息、执行的结果等信息,mybatis中会通过logback输出出来。

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


       
       
  1. <?xml version= "1.0" encoding= "UTF-8"?>
  2. <configuration>
  3.     <appender name= "STDOUT" class= "ch.qos.logback.core.ConsoleAppender">
  4.         <encoder>
  5.             <pattern>%d{mm:ss.SSS} [%thread] % -5level %logger{ 36} - %msg%n</pattern>
  6.         </encoder>
  7.     </appender>
  8.     <logger name= "com.javacode2018" level= "debug" additivity= "false">
  9.         <appender-ref ref= "STDOUT" />
  10.     </logger>
  11. </configuration>
创建mybatis相关文件
user.xml

chat01/src/main/resources目录中新建user.xml,内容如下:


       
       
  1. <?xml version= "1.0" encoding= "UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC  "-//mybatis.org//DTD Mapper 3.0//EN"
  3.          "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  4. <mapper namespace= "com.javacode2018.mybatis.chat01.UserMapper">
  5.     <!-- 插入 -->
  6.     <insert id= "insert" parameterType= "com.javacode2018.mybatis.chat01.UserModel" keyProperty= "id" useGeneratedKeys= "true">
  7.         <![CDATA[ INSERT INTO  `t_user` ]]>
  8.         <trim prefix= "(" suffix= ")" suffixOverrides= ",">
  9.             < if test= "id!=null">
  10.                 <![CDATA[  `id`, ]]>
  11.             </ if>
  12.             < if test= "name!=null">
  13.                 <![CDATA[  `name`, ]]>
  14.             </ if>
  15.             < if test= "age!=null">
  16.                 <![CDATA[  `age`, ]]>
  17.             </ if>
  18.             < if test= "salary!=null">
  19.                 <![CDATA[  `salary`, ]]>
  20.             </ if>
  21.         </trim>
  22.         <![CDATA[ VALUES ]]>
  23.         <trim prefix= "(" suffix= ")" suffixOverrides= ",">
  24.             < if test= "id!=null">
  25.                 <![CDATA[ #{id}, ]]>
  26.             </ if>
  27.             < if test= "name!=null">
  28.                 <![CDATA[ #{name}, ]]>
  29.             </ if>
  30.             < if test= "age!=null">
  31.                 <![CDATA[ #{age}, ]]>
  32.             </ if>
  33.             < if test= "salary!=null">
  34.                 <![CDATA[ #{salary}, ]]>
  35.             </ if>
  36.         </trim>
  37.     </insert>
  38. <!-- 批量插入 -->
  39. <insert id= "insertBatch" parameterType= "map">
  40.     <![CDATA[ INSERT INTO  `t_user` ( `id``name``age``salary`) VALUES ]]>
  41.     <foreach collection= "list" separator= "," item= "item">
  42.         (#{item.id}, #{item.name}, #{item.age}, #{item.salary})
  43.     </foreach>
  44. </insert>
  45.     <!-- 更新 -->
  46.     <update id= "update" parameterType= "com.javacode2018.mybatis.chat01.UserModel">
  47.         <![CDATA[ UPDATE  `t_user` ]]>
  48.         <set>
  49.             < if test= "name!=null">
  50.                 <![CDATA[  `name` = #{name}, ]]>
  51.             </ if>
  52.             < if test= "age!=null">
  53.                 <![CDATA[  `age` = #{age}, ]]>
  54.             </ if>
  55.             < if test= "salary!=null">
  56.                 <![CDATA[  `salary` = #{salary}, ]]>
  57.             </ if>
  58.         </set>
  59.         <where>
  60.             < if test= "id!=null">
  61.                 <![CDATA[ AND  `id` = #{id} ]]>
  62.             </ if>
  63.         </where>
  64.     </update>
  65.     <!-- 更新 -->
  66.     <update id= "updateByMap" parameterType= "map">
  67.         <![CDATA[ UPDATE  `t_user` ]]>
  68.         <set>
  69.             < if test= "name!=null">
  70.                 <![CDATA[  `name` = #{name}, ]]>
  71.             </ if>
  72.             < if test= "age!=null">
  73.                 <![CDATA[  `age` = #{age}, ]]>
  74.             </ if>
  75.             < if test= "salary!=null">
  76.                 <![CDATA[  `salary` = #{salary}, ]]>
  77.             </ if>
  78.         </set>
  79.         <where>
  80.             < if test= "id!=null">
  81.                 <![CDATA[ AND  `id` = #{id} ]]>
  82.             </ if>
  83.         </where>
  84.     </update>
  85.     <!-- 删除 -->
  86.     < delete id= "delete" parameterType= "map">
  87.         <![CDATA[
  88.             DELETE FROM  `t_user`
  89.         ]]>
  90.         <where>
  91.             < if test= "id!=null">
  92.                 <![CDATA[ AND  `id` = #{id} ]]>
  93.             </ if>
  94.         </where>
  95.     </ delete>
  96.     <!-- 查询记录 -->
  97.     < select id= "getModelList" parameterType= "map" resultType= "com.javacode2018.mybatis.chat01.UserModel">
  98.         <![CDATA[
  99.         SELECT
  100.         ]]>
  101.         <choose>
  102.             <when test= "tableColumnList!=null and tableColumnList.size() >= 1">
  103.                 <foreach collection= "tableColumnList" item= "item" separator= ",">
  104.                     <![CDATA[ ${item} ]]>
  105.                 </foreach>
  106.             </when>
  107.             <otherwise>
  108.                 <![CDATA[
  109.                  `id`,
  110.                  `name`,
  111.                  `age`,
  112.                  `salary`
  113.                 ]]>
  114.             </otherwise>
  115.         </choose>
  116.         <![CDATA[
  117.         FROM
  118.          `t_user` a
  119.         ]]>
  120.         <where>
  121.             < if test= "id!=null and id.toString()!=''">
  122.                 <![CDATA[ AND a. `id` = #{id} ]]>
  123.             </ if>
  124.             < if test= "idList!=null and idList.size() >= 1">
  125.                 <![CDATA[ AND a. `id` IN ]]>
  126.                 <foreach collection= "idList" item= "item" open= "(" separator= ","  close= ")">
  127.                     <![CDATA[ #{item} ]]>
  128.                 </foreach>
  129.             </ if>
  130.             < if test= "name!=null and name.toString()!=''">
  131.                 <![CDATA[ AND a. `name` = #{name} ]]>
  132.             </ if>
  133.             < if test= "age!=null and age.toString()!=''">
  134.                 <![CDATA[ AND a. `age` = #{age} ]]>
  135.             </ if>
  136.             < if test= "salary!=null and salary.toString()!=''">
  137.                 <![CDATA[ AND a. `salary` = #{salary} ]]>
  138.             </ if>
  139.             < if test= "nameLike!=null and nameLike.toString()!=''">
  140.                 <![CDATA[ AND a. `name` like  '%${nameLike}%' ]]>
  141.             </ if>
  142.             < if test= "salaryGte!=null and salaryGte.toString()!=''">
  143.                 <![CDATA[ AND a. `salary` >= #{salaryGte} ]]>
  144.             </ if>
  145.         </where>
  146.         < if test= "sort!=null and sort.toString()!=''">
  147.             <![CDATA[ order by ${sort} ]]>
  148.         </ if>
  149.         < if test= "skip!=null and pageSize!=null">
  150.             <![CDATA[ LIMIT #{skip},#{pageSize} ]]>
  151.         </ if>
  152.     </ select>
  153. </mapper>
mybatis-config.xml

chat01/src/main/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.     <properties>
  7.         <property name= "driver" value= "com.mysql.jdbc.Driver"/>
  8.         <property name= "url" value= "jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8"/>
  9.         <property name= "username" value= "root"/>
  10.         <property name= "password" value= "root123"/>
  11.     </properties>
  12.     <environments  default= "development">
  13.         <environment id= "development">
  14.             <transactionManager  type= "JDBC"/>
  15.             <dataSource  type= "POOLED">
  16.                 <property name= "driver" value= "${driver}"/>
  17.                 <property name= "url" value= "${url}"/>
  18.                 <property name= "username" value= "${username}"/>
  19.                 <property name= "password" value= "${password}"/>
  20.             </dataSource>
  21.         </environment>
  22.     </environments>
  23.     <mappers>
  24.         <mapper resource= "mapper/user.xml"/>
  25.     </mappers>
  26. </configuration>
UserMapper接口

       
       
  1. package com.javacode2018.mybatis.chat01;
  2. import java.util.List;
  3. import java.util.Map;
  4. /**
  5.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活!
  6.  */
  7. public  interface UserMapper {
  8.      /**
  9.      * 插入用户信息
  10.      *
  11.      * @param userModel
  12.      * @return
  13.      */
  14.     void insert(UserModel userModel);
  15.      /**
  16.      * 批量插入用户信息
  17.      *
  18.      * @param userModelList
  19.      */
  20.     void insertBatch(List<UserModel> userModelList);
  21.      /**
  22.      * 更新用户信息
  23.      *
  24.      * @param userModel
  25.      * @return
  26.      */
  27.      int update(UserModel userModel);
  28.      /**
  29.      * 通过map来更新用户记录
  30.      *
  31.      * @param map
  32.      * @return
  33.      */
  34.      int updateByMap(Map<String, Object>  map);
  35.      /**
  36.      * 通过map来删除用户记录
  37.      *
  38.      * @param map
  39.      * @return
  40.      */
  41.      int  delete(Map<String, Object>  map);
  42.      /**
  43.      * 查询用户列表
  44.      *
  45.      * @param map
  46.      * @return
  47.      */
  48.     List<UserModel> getModelList(Map<String, Object>  map);
  49. }
UserModel类

       
       
  1. package com.javacode2018.mybatis.chat01;
  2. import lombok.*;
  3. /**
  4.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活!
  5.  */
  6. @Getter
  7. @Setter
  8. @NoArgsConstructor
  9. @AllArgsConstructor
  10. @Builder
  11. @ToString
  12. public class UserModel {
  13.     private Long id;
  14.     private String name;
  15.     private Integer age;
  16.     private Double salary;
  17. }

这个类上面的注解都是都是lombok中的,通过这些注解,lombok可以帮助我们自动生成上面4个字段的get方法、set方法、无参构造方法、有参有参构造方法、builder模式构建对象的代码、重写toString方法,这些都在代码编译为字节码之前会写进去,通过lombok代码是不是精简了很多,最后生成的代码大家可以反编译一下UserModel.class去看一下,感受一下,此处我们就不贴出来了。

UserUtil类

       
       
  1. package com.javacode2018.mybatis.chat01;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.apache.ibatis.io.Resources;
  4. import org.apache.ibatis.session.SqlSession;
  5. import org.apache.ibatis.session.SqlSessionFactory;
  6. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  7. import java.io.IOException;
  8. /**
  9.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活!
  10.  */
  11. @Slf4j
  12. public class UserUtil {
  13.     private static SqlSessionFactory sqlSessionFactory = build();
  14.     public static SqlSessionFactory build() {
  15.         try {
  16.              return  new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream( "mybatis-config.xml"));
  17.         } catch (IOException e) {
  18.             log. error(e.getMessage(), e);
  19.             throw  new RuntimeException(e);
  20.         }
  21.     }
  22.     @FunctionalInterface
  23.     public  interface SessionCall<O> {
  24.         O call(SqlSession session) throws Exception;
  25.     }
  26.     @FunctionalInterface
  27.     public  interface MapperCall<T, O> {
  28.         O call(T mapper) throws Exception;
  29.     }
  30.     public static <T, O> O callMapper(Class<T> tClass, MapperCall<T, O> mapper) throws Exception {
  31.          return call(session -> mapper.call(session.getMapper(tClass)));
  32.     }
  33.     public static <O> O call(SessionCall<O> sessionCall) throws Exception {
  34.         try (SqlSession session = sqlSessionFactory.openSession( true);) {
  35.              return sessionCall.call(session);
  36.         }
  37.     }
  38. }
创建单元测试类UserMapperTest

chat01\src\test\java\com\javacode2018\mybatis\chat01中创建UserMapperTest,代码如下:


       
       
  1. package com.javacode2018.mybatis.chat01;
  2. import lombok.extern.slf4j.Slf4j;
  3. import org.junit.Test;
  4. import java.util.*;
  5. import java.util.stream.Collectors;
  6. /**
  7.  * 公众号:路人甲Java,工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活!
  8.  */
  9. @Slf4j
  10. public class UserMapperTest {
  11.      //动态插入
  12.     @Test
  13.     public void insert() throws Exception {
  14.         UserModel userModel1 = UserModel.builder().name( "路人甲Java").build();
  15.         UserUtil.callMapper(UserMapper.class, mapper -> {
  16.             mapper.insert(userModel1);
  17.              return null;
  18.         });
  19.         log.info( "插入结果:{}", this.getModelById(userModel1.getId()));
  20.         log.info( "---------------------");
  21.         UserModel userModel2 = UserModel.builder().name( "路人").age( 30).salary( 50000.00).build();
  22.         UserUtil.callMapper(UserMapper.class, mapper -> {
  23.             mapper.insert(userModel2);
  24.              return null;
  25.         });
  26.         log.info( "插入结果:{}", this.getModelById(userModel2.getId()));
  27.     }
  28.      //批量插入
  29.     @Test
  30.     public void insertBatch() throws Exception {
  31.         List<UserModel> userModelList =  new ArrayList<>();
  32.          for ( int i =  1; i <=  5; i++) {
  33.             userModelList.add(UserModel.builder().name( "路人甲Java-" + i).age( 30 + i).salary( 10000.00 * i).build());
  34.             userModelList.add(UserModel.builder().name( "javacode2018-" + i).age( 30 + i).salary( 10000.00 * i).build());
  35.         }
  36.         UserUtil.callMapper(UserMapper.class, mapper -> {
  37.             mapper.insertBatch(userModelList);
  38.              return null;
  39.         });
  40.         List<UserModel> userModelList1 = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(null));
  41.         log.info( "结果:{}", userModelList1);
  42.     }
  43.      //根据用户id删除数据
  44.     @Test
  45.     public void  delete() throws Exception {
  46.         Map<String, Object>  map =  new HashMap<>();
  47.          //需要删除的用户id
  48.          map.put( "id"1);
  49.         Integer count = UserUtil.callMapper(UserMapper.class, mapper -> mapper. delete( map));
  50.         log.info( "删除行数:{}", count);
  51.     }
  52.      //动态更新
  53.     @Test
  54.     public void update() throws Exception {
  55.          //将userId=2的name修改为:路人
  56.         Long userId1 =  2L;
  57.         Integer count = UserUtil.callMapper(UserMapper.class, mapper -> mapper.update(UserModel.builder().id(userId1).name( "ready").build()));
  58.         log.info( "更新行数:{}", count);
  59.         log.info( "---------------------");
  60.          //将userId=3的name修改为:路人,薪水为:1000.88
  61.         Long userId2 =  3L;
  62.         count = UserUtil.callMapper(UserMapper.class, mapper -> mapper.update(UserModel.builder().id(userId2).name( "ready").salary( 1000.88D).build()));
  63.         log.info( "更新行数:{}", count);
  64.     }
  65.      //按用户id查询
  66.     public UserModel getModelById(Long userId) throws Exception {
  67.          //查询指定id的数据
  68.         Map<String, Object>  map =  new HashMap<>();
  69.          map.put( "id", userId);
  70.          return UserUtil.callMapper(UserMapper.class, mapper -> {
  71.             List<UserModel> userModelList = mapper.getModelList( map);
  72.              if (userModelList.size() ==  1) {
  73.                  return userModelList.get( 0);
  74.             }
  75.              return null;
  76.         });
  77.     }
  78.      //查询所有数据
  79.     @Test
  80.     public void getModelList1() throws Exception {
  81.         List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList(null));
  82.         log.info( "结果:{}", userModelList);
  83.     }
  84.      //查询多个用户id对应的数据
  85.     @Test
  86.     public void getModelListByIds() throws Exception {
  87.         List<Integer> idList = Arrays.asList( 234).stream().collect(Collectors.toList());
  88.         Map<String, Object>  map =  new HashMap<>();
  89.          map.put( "idList", idList);
  90.         List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList( map));
  91.         log.info( "结果:{}", userModelList);
  92.     }
  93.      //多条件 & 指定返回的列
  94.     @Test
  95.     public void getModelList2() throws Exception {
  96.          //查询姓名中包含路人甲java以及薪资大于3万的用户id、姓名
  97.         Map<String, Object>  map =  new HashMap<>();
  98.          map.put( "nameLike""路人甲java");
  99.          map.put( "salaryGte"30000.00D);
  100.          //需要返回的列
  101.         List<String> tableColumnList =  new ArrayList<>();
  102.         tableColumnList.add( "id");
  103.         tableColumnList.add( "name");
  104.          map.put( "tableColumnList", tableColumnList);
  105.         List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList( map));
  106.         log.info( "结果:{}", userModelList);
  107.     }
  108.      //条件过滤 & 排序 & 分页查询数据 & 只返回用户id、salary
  109.     @Test
  110.     public void getPage() throws Exception {
  111.          //查询姓名中包含路人甲java以及薪资大于3万的用户id,按照薪资倒叙,每页5条取第1页
  112.         Map<String, Object>  map =  new HashMap<>();
  113.          map.put( "nameLike""路人甲java");
  114.          map.put( "salaryGte"30000.00D);
  115.          //加入排序参数
  116.          map.put( "sort""salary desc");
  117.          //加入分页参数
  118.          int page =  1;
  119.          int pageSize =  5;
  120.          map.put( "skip", (page -  1) * pageSize);
  121.          map.put( "pageSize", pageSize);
  122.          //加入需要返回的列
  123.         List<String> tableColumnList =  new ArrayList<>();
  124.         tableColumnList.add( "id");
  125.         tableColumnList.add( "salary");
  126.          map.put( "tableColumnList", tableColumnList);
  127.         List<UserModel> userModelList = UserUtil.callMapper(UserMapper.class, mapper -> mapper.getModelList( map));
  128.         log.info( "结果:{}", userModelList);
  129.     }
  130. }
项目最终结构如下

用例:动态插入

运行UserMapperTest#insert,输出如下:


       
       
  1. 37: 58.556 [main] DEBUG c.j.mybatis.chat01.UserMapper.insert - ==>  Preparing: INSERT INTO  `t_user` (  `name` ) VALUES ( ? ) 
  2. 37: 58.605 [main] DEBUG c.j.mybatis.chat01.UserMapper.insert - ==> Parameters: 路人甲Java(String)
  3. 37: 58.613 [main] DEBUG c.j.mybatis.chat01.UserMapper.insert - <==    Updates:  1
  4. 37: 58.641 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT  `id``name``age``salary` FROM  `t_user` a WHERE a. `id` = ? 
  5. 37: 58.641 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==> Parameters:  1(Long)
  6. 37: 58.663 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - <==      Total:  1
  7. 37: 58.664 [main] INFO  c.j.mybatis.chat01.UserMapperTest - 插入结果:UserModel(id= 1, name=路人甲Java, age= 1, salary= 0.0)
  8. 37: 58.667 [main] INFO  c.j.mybatis.chat01.UserMapperTest - ---------------------
  9. 37: 58.668 [main] DEBUG c.j.mybatis.chat01.UserMapper.insert - ==>  Preparing: INSERT INTO  `t_user` (  `name``age``salary` ) VALUES ( ?, ?, ? ) 
  10. 37: 58.675 [main] DEBUG c.j.mybatis.chat01.UserMapper.insert - ==> Parameters: 路人(String),  30(Integer),  50000.0(Double)
  11. 37: 58.679 [main] DEBUG c.j.mybatis.chat01.UserMapper.insert - <==    Updates:  1
  12. 37: 58.681 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT  `id``name``age``salary` FROM  `t_user` a WHERE a. `id` = ? 
  13. 37: 58.681 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==> Parameters:  2(Long)
  14. 37: 58.683 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - <==      Total:  1
  15. 37: 58.683 [main] INFO  c.j.mybatis.chat01.UserMapperTest - 插入结果:UserModel(id= 2, name=路人, age= 30, salary= 50000.0)

UserMapperTest#insert这个方法主要有4步操作:

步骤1:插入一条用户记录,用户记录只有name字段有值

步骤2:去db中查询步骤1中插入的记录

步骤3:插入一条用户记录,这次插入的记录所有字段都指定了值

步骤4:去db中查询步骤3中插入的记录

重点来了:大家认真看一下UserMapperTest#insert方法的代码,两个插入调用都是mapper.insert方法,传入的都是UserModel对象,唯一不同的是这个对象构建的时候字段的值不一样,最后再认真看一下上面输出的sql,产生的2个insert也是不一样的,这个mapper.insert方法可以根据UserModel对象字段是否有值来组装我们需要的sql,是不是很牛逼,这就是动态插入。

用例:批量插入

运行UserMapperTest#insertBatch,输出如下:


       
       
  1. 38: 12.425 [main] DEBUG c.j.m.chat01.UserMapper.insertBatch - ==>  Preparing: INSERT INTO  `t_user` ( `id``name``age``salary`) VALUES (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) , (?, ?, ?, ?) 
  2. 38: 12.476 [main] DEBUG c.j.m.chat01.UserMapper.insertBatch - ==> Parameters: null, 路人甲Java -1(String),  31(Integer),  10000.0(Double), null, javacode2018 -1(String),  31(Integer),  10000.0(Double), null, 路人甲Java -2(String),  32(Integer),  20000.0(Double), null, javacode2018 -2(String),  32(Integer),  20000.0(Double), null, 路人甲Java -3(String),  33(Integer),  30000.0(Double), null, javacode2018 -3(String),  33(Integer),  30000.0(Double), null, 路人甲Java -4(String),  34(Integer),  40000.0(Double), null, javacode2018 -4(String),  34(Integer),  40000.0(Double), null, 路人甲Java -5(String),  35(Integer),  50000.0(Double), null, javacode2018 -5(String),  35(Integer),  50000.0(Double)
  3. 38: 12.484 [main] DEBUG c.j.m.chat01.UserMapper.insertBatch - <==    Updates:  10
  4. 38: 12.502 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT  `id``name``age``salary` FROM  `t_user` a 
  5. 38: 12.502 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==> Parameters: 
  6. 38: 12.521 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - <==      Total:  12
  7. 38: 12.521 [main] INFO  c.j.mybatis.chat01.UserMapperTest - 结果:[UserModel(id= 1, name=路人甲Java, age= 1, salary= 0.0), UserModel(id= 2, name=路人, age= 30, salary= 50000.0), UserModel(id= 3, name=路人甲Java -1, age= 31, salary= 10000.0), UserModel(id= 4, name=javacode2018 -1, age= 31, salary= 10000.0), UserModel(id= 5, name=路人甲Java -2, age= 32, salary= 20000.0), UserModel(id= 6, name=javacode2018 -2, age= 32, salary= 20000.0), UserModel(id= 7, name=路人甲Java -3, age= 33, salary= 30000.0), UserModel(id= 8, name=javacode2018 -3, age= 33, salary= 30000.0), UserModel(id= 9, name=路人甲Java -4, age= 34, salary= 40000.0), UserModel(id= 10, name=javacode2018 -4, age= 34, salary= 40000.0), UserModel(id= 11, name=路人甲Java -5, age= 35, salary= 50000.0), UserModel(id= 12, name=javacode2018 -5, age= 35, salary= 50000.0)]

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

40:40.727 [main] DEBUG c.j.m.chat01.UserMapper.insertBatch - <==    Updates: 10

上面这个表示插入影响的行数,10表示插入了10行。

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

用例:根据用户id删除数据

运行UserMapperTest#delete,输出如下:


       
       
  1. 38: 36.498 [main] DEBUG c.j.mybatis.chat01.UserMapper. delete - ==>  Preparing: DELETE FROM  `t_user` WHERE  `id` = ? 
  2. 38: 36.551 [main] DEBUG c.j.mybatis.chat01.UserMapper. delete - ==> Parameters:  1(Integer)
  3. 38: 36.560 [main] DEBUG c.j.mybatis.chat01.UserMapper. delete - <==    Updates:  1
  4. 38: 36.561 [main] INFO c.j.mybatis.chat01.UserMapperTest - 删除行数: 1
用例:动态更新

运行UserMapperTest#update,输出如下:


       
       
  1. 38: 51.289 [main] DEBUG c.j.mybatis.chat01.UserMapper.update - ==>  Preparing: UPDATE  `t_user` SET  `name` = ? WHERE  `id` = ? 
  2. 38: 51.347 [main] DEBUG c.j.mybatis.chat01.UserMapper.update - ==> Parameters: ready(String),  2(Long)
  3. 38: 51.355 [main] DEBUG c.j.mybatis.chat01.UserMapper.update - <==    Updates:  1
  4. 38: 51.356 [main] INFO c.j.mybatis.chat01.UserMapperTest - 更新行数: 1
  5. 38: 51.358 [main] INFO  c.j.mybatis.chat01.UserMapperTest - ---------------------
  6. 38: 51.359 [main] DEBUG c.j.mybatis.chat01.UserMapper.update - ==>  Preparing: UPDATE  `t_user` SET  `name` = ?,  `salary` = ? WHERE  `id` = ? 
  7. 38: 51.360 [main] DEBUG c.j.mybatis.chat01.UserMapper.update - ==> Parameters: ready(String),  1000.88(Double),  3(Long)
  8. 38: 51.363 [main] DEBUG c.j.mybatis.chat01.UserMapper.update - <==    Updates:  1
  9. 38: 51.364 [main] INFO c.j.mybatis.chat01.UserMapperTest - 更新行数: 1

UserMapperTest#update方法,大家也认真看一下,2个更新,调用都是mapper.update方法,传入的都是UserModel类型的参数,只是2个UserModel对象的字段值不一样,最后产生的2个update语句也是不一样的,这个update语句是mybatis动态组装的,mybatis可以根据UserModel中字段是否为NULL,来拼装sql,这个更新是不是很强大。

用例:动态查询
查询所有数据

运行UserMapperTest#getModelList1,输出如下:


       
       
  1. 39: 10.552 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT  `id``name``age``salary` FROM  `t_user` a 
  2. 39: 10.611 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==> Parameters: 
  3. 39: 10.639 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - <==      Total:  11
  4. 39: 10.639 [main] INFO  c.j.mybatis.chat01.UserMapperTest - 结果:[UserModel(id= 2, name=ready, age= 30, salary= 50000.0), UserModel(id= 3, name=ready, age= 31, salary= 1000.88), UserModel(id= 4, name=javacode2018 -1, age= 31, salary= 10000.0), UserModel(id= 5, name=路人甲Java -2, age= 32, salary= 20000.0), UserModel(id= 6, name=javacode2018 -2, age= 32, salary= 20000.0), UserModel(id= 7, name=路人甲Java -3, age= 33, salary= 30000.0), UserModel(id= 8, name=javacode2018 -3, age= 33, salary= 30000.0), UserModel(id= 9, name=路人甲Java -4, age= 34, salary= 40000.0), UserModel(id= 10, name=javacode2018 -4, age= 34, salary= 40000.0), UserModel(id= 11, name=路人甲Java -5, age= 35, salary= 50000.0), UserModel(id= 12, name=javacode2018 -5, age= 35, salary= 50000.0)]

可以看到sql是没有查询条件的。

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

运行UserMapperTest#getModelListByIds,输出如下:


       
       
  1. 39: 38.000 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT  `id``name``age``salary` FROM  `t_user` a WHERE a. `id` IN ( ? , ? , ? ) 
  2. 39: 38.064 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==> Parameters:  2(Integer),  3(Integer),  4(Integer)
  3. 39: 38.096 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - <==      Total:  3
  4. 39: 38.097 [main] INFO  c.j.mybatis.chat01.UserMapperTest - 结果:[UserModel(id= 2, name=ready, age= 30, salary= 50000.0), UserModel(id= 3, name=ready, age= 31, salary= 1000.88), UserModel(id= 4, name=javacode2018 -1, age= 31, salary= 10000.0)]

上面这个按照id列表查询也是比较常用的,比如我们在电商中查询订单列表,还需要查询每个订单对应的商品,此时可以先查询订单列表,然后在通过订单列表拿到所有的商品id集合,然后通过商品id集合去通过上面的方式检索商品信息,只需要2次查询就可以查询出订单及商品的信息了。

多条件 & 指定返回的列

运行UserMapperTest#getModelList2,查询姓名中包含路人甲java以及薪资大于3万的用户id、姓名,输出如下:


       
       
  1. 41: 12.185 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT id , name FROM  `t_user` a WHERE a. `name` like  '%路人甲java%' AND a. `salary` >= ? 
  2. 41: 12.275 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==> Parameters:  30000.0(Double)
  3. 41: 12.311 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - <==      Total:  3
  4. 41: 12.312 [main] INFO  c.j.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

运行UserMapperTest#getModelList3,查询姓名中包含路人甲java以及薪资大于3万的用户id,按照薪资倒叙,每页5条取第1页,输出如下:


       
       
  1. 44: 00.719 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==>  Preparing: SELECT id , salary FROM  `t_user` a WHERE a. `name` like  '%路人甲java%' AND a. `salary` >= ? order by salary desc LIMIT ?,? 
  2. 44: 00.775 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - ==> Parameters:  30000.0(Double),  0(Integer),  5(Integer)
  3. 44: 00.805 [main] DEBUG c.j.m.chat01.UserMapper.getModelList - <==      Total:  3
  4. 44: 00.806 [main] INFO  c.j.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`t_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文件。

mybatis开发项目的具体步骤

项目中引入mybatis maven配置

       
       
  1. <dependency>
  2.     <groupId>org.mybatis</groupId>
  3.     <artifactId>mybatis</artifactId>
  4.     <version>${mybatis.version}</version>
  5. </dependency>

上面的mybatis.version版本,大家可以在maven社区中央仓库中去查找最新的,目前最新的是3.5.3

创建mybatis配置文件

mybatis配置文件为xml格式,可以放在resource目录下面,如上面案例中的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.     <properties>
  7.         <property name= "driver" value= "com.mysql.jdbc.Driver"/>
  8.         <property name= "url" value= "jdbc:mysql://localhost:3306/javacode2018?characterEncoding=UTF-8"/>
  9.         <property name= "username" value= "root"/>
  10.         <property name= "password" value= "root123"/>
  11.     </properties>
  12.     <environments  default= "development">
  13.         <environment id= "development">
  14.             <transactionManager  type= "JDBC"/>
  15.             <dataSource  type= "POOLED">
  16.                 <property name= "driver" value= "${driver}"/>
  17.                 <property name= "url" value= "${url}"/>
  18.                 <property name= "username" value= "${username}"/>
  19.                 <property name= "password" value= "${password}"/>
  20.             </dataSource>
  21.         </environment>
  22.     </environments>
  23.     <mappers>
  24.         <mapper resource= "mapper/user.xml"/>
  25.     </mappers>
  26. </configuration>

这个文件主要是对mybatis进行全局配置,比如数据源、事务的配置,如上面的datasource元素用来配置数据源,数据源中就需要指定数据库的一些配置信息;还有其他更多的配置,此处先不做具体说明,后面我们慢慢来,整个系列完成之后,这些配置大家都会懂的。

创建mapper xml文件

如上面案例中的user.xml,大家在打开看看,我们需要对t_user表所有操作sql就写在这个文件中,下一篇文章我们会详细介绍mapper xml文件的各种写法,user.xml文件是对t_user表的所有操作一般都会放在这个里面,mybatis如何使用到这个文件呢,我们需要在上面的mybatis配置文件中引入这个mapper文件,如案例中在mybatis-config.xml有下面这样的内容:


       
       
  1. <mappers>
  2.     <mapper resource= "mapper/user.xml"/>
  3. </mappers>

mappers元素中可以有多个mapper文件,我们开发的项目中可能有很多表需要操作,那么对应会有很多mapper xml文件,我们都需要在mappers元素中进行引入,然后mybatis才会使用到。

创建Mapper接口

开发者如何去调用user.xml中的各种操作去执行sql呢,这时我们就需要一个Mapper接口了Mapper接口会和mapper xml建立映射关系,当我们调用Mapper接口中的方法的时候,会间接的调用到mapper xml中的各种数据的sql操作,Mapper接口如何和Mapper xml文件关联的呢?

大家去看一下user.xml文件中有个这样的一个配置:

<mapper namespace="com.javacode2018.mybatis.chat01.UserMapper">

注意上面的namespace的值,对应的是UserMapper这个接口完整的引用,通过这个namespace,UserMapper接口就可以user.xml建立了映射关系。

user.xml中又有很多db操作,这些操作会和UserMapper接口中的方法建立映射关系,当调用UserMapper中的方法的时候,间接的会调用到user.xml中对应的操作。

user.xml中有下面一段配置:


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

UserMapper中有个insertBatch方法和上面这个insert批量插入对应,如下:


       
       
  1. /**
  2.  * 批量插入用户信息
  3.  *
  4.  * @param userModelList
  5.  */
  6. void insertBatch(List<UserModel> userModelList);

所以当我们调用UserMapper中的insertBatch方法的时候,会间接调用到user.xml中的 id="insertBatch"这个操作。

提示一下:接口和mapper xml映射起来间接调用,是通过java动态代理实现的,后面我们会详解如何实现的。

下面我们就可以使用mybatis来操作db了。

通过mybatis获取Mapper接口执行对db的操作

上面我们说了,我们可以通过mapper接口来执行对db的操作,获取Mapper的主要代码如下:


       
       
  1. SqlSessionFactoryBuilder sqlSessionFactoryBuilder =  new SqlSessionFactoryBuilder();
  2. SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(Resources.getResourceAsStream( "mybatis-config.xml"));
  3. SqlSession sqlSession = sqlSessionFactory.openSession( true);
  4. UserMapper mapper = sqlSession.getMapper(UserMapper.class);

上面代码中使用到了mybatis中的核心组件,我们具体来看一下。

Mybatis核心对象介绍
SqlSessionFactoryBuilder

这个是一个构建器,通过名字大家也可以感觉到SqlSessionFactoryBuilder构建器,是用来构建SqlSessionFactory对象的,SqlSessionFactoryBuilder可以通过读取mybatis的配置文件,然后构建一个SqlSessionFactory对象,一个项目中有很多mapper xml文件,如果每次操作都去重新解析是非常慢的,那么怎么办?

能不能第一次解析好然后放在内存中,以后直接使用,SqlSessionFactoryBuilder就是搞这个事情的,将mybatis配置文件、mapper xml文件、mapper xml文件和Mapper 接口的映射关系,这些都先给解析好,然后放在java对象中,java对象存在于内存中,内存中访问会非常快的,那么我们每次去用的时候就不需要重新去解析xml了,SqlSessionFactoryBuilder解析配置之后,生成的对象就是SqlSessionFactory,这个是一个重量级的对象,创建他是比较耗时的,所以一般一个db我们会创建一个SqlSessionFactory对象,然后在系统运行过程中会一直存在,而SqlSessionFactoryBuilder用完了就可以释放了。

SqlSessionFactory

通过名字可以知道,这个是一个工厂,是用来创建SqlSession的工厂,SqlSessionFactory是一个重量级的对象,一般一个db对应一个SqlSessionFactory对象,系统运行过程中会一直存在。

SqlSessionFactory是一个接口,这个接口有2个实现DefaultSqlSessionFactorySqlSessionManager,一般都是通过SqlSessionFactoryBuilder来创建SqlSessionFactory对象。

通过SqlSessionFactoryBuilder来创建SqlSessionFactory对象主要有2种方式,一种通过读取mybatis配置文件的方式,另外一种是硬编码的方式,这个后面会专门抽一篇文件介绍这块,springboot中会使用到硬编码的方式,所以这块会详细介绍。

SqlSession

我们通过jdbc操作数据库需要先获取一个Connection连接,然后拿着这个连接去对db进行操作,在mybatis中SqlSession就类似于jdbc中Connection连接对象,在mybatis中叫做Sql会话对象,一般我们一个db操作使用一个SqlSession对象,所以这个对象一般是方法级别的,方法结束之后,这个对象就销毁了,这个对象可以调用sqlSessionFactory.openSession的方法来进行获取。

我们可以直接通过SqlSession对象来调用mapper xml中各种db操作,需要指定具体的操作的id,id的格式为namespace.操作的id

Mapper接口

我们可以通过SqlSession直接调用mapper xml中的db操作,不过更简单的以及推荐的方式是使用Mapper接口,Mapper接口中的方法和mapper xml文件中的各种db操作建立了映射关系,是通过Mapper接口完整名称+方法名称mapper xml中的namespace+具体操作的id来进行关联的,然后我们直接调用Mapper接口中的方法就可以间接的操作db了,使用想当方便,Mapper接口需要通过SqlSession获取,传入Mapper接口对应的Class对象,然后会返回这个接口的实例,如:

UserMapper mapper = sqlSession.getMapper(UserMapper.class);

总结

本篇文章主要通过一个案例来感受一下mybatis可以干什么,以及他的强大之处,还需要大家掌握mybatis开发项目的具体步骤,后面的文章将对mybatis中具体的知识点做详细介绍,让大家成为mybatis高手。

案例代码获取方式

扫码添加微信备注:mybatis案例,即可获取

MyBatis系列

  1. MyBatis系列第1篇:MyBatis未出世之前我们那些痛苦的经历

更多好文章

  1. Java高并发系列(共34篇)

  2. MySql高手系列(共27篇)

  3. Maven高手系列(共10篇)

  4. 聊聊db和缓存一致性常见的实现方式

  5. 接口幂等性这么重要,它是什么?怎么实现?

感谢大家的阅读,也欢迎您把这篇文章分享给更多的朋友一起阅读!谢谢!

路人甲java

▲长按图片识别二维码关注

路人甲Java:工作10年的前阿里P7分享Java、算法、数据库方面的技术干货!坚信用技术改变命运,让家人过上更体面的生活!来源:https://itsoku.blog.csdn.net/article/details/103397329

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值