最全面的Mybatis教程,从“开局”到“通关”,Ready Go!

前言

最全面的Mybatis教程,从“开局”到“通关”,Ready Go!

本文为 SSM框架 【Mybatis】 相关知识,MyBatis 是一款优秀的半自动的ORM持久层框架,下边将对 Mybatis的简介Mybatis的CRUD实现Mybatis的配置文件Mybatis的日志配置resultMap详解分页实现注解式开发Lombok的使用关联映射动态SQLMybatis缓存等进行详尽介绍~
🚩 Are you ready❓ Let’s Go ❗️

📌 博主主页: 小新要变强 的主页
👉 Java全栈学习路线可参考: 【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉 算法刷题路线可参考: 算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉 Java微服务开源项目可参考: 企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)

; 目录

SSM框架 【Mybatis】(一)

最全面的Mybatis教程,从“开局”到“通关”,Ready Go!

; 一、Mybatis简介

1️⃣什么是Mybatis

  • MyBatis 本是apache的一个开源项目【iBatis】;2010年这个项目由apache software foundation(Apache软件基金会) 迁移到了google code(谷歌的代码托管平台),并且改名为MyBatis;2013年11月迁移到Github。
  • MyBatis是一款优秀的持久层框架
  • MyBatis支持定制SQL、存储过程以及高级映射
  • Mybatis避免了几乎所有的JDBC代码和手动设置参数,以及获取结果集
  • Mybatis可以使用简单的XML或注解来配置和映射原生类型、接口和Java的POJO(Plain Old Java Objects,普通老式Java对象)为数据库中的记录

Mybatis的Maven仓库下载地址: https://mvnrepository.com/artifact/org.mybatis/mybatis
Mybatis的GitHub地址: https://github.com/mybatis/mybatis-3/releases
Mybatis的中文文档地址: https://mybatis.org/mybatis-3/zh/index.html

2️⃣持久化

持久化是将程序数据在持久状态和瞬时状态间转换的机制。通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据(比如持久化至数据库中,能够长久保存)。

  • 程序产生的数据首先都是在内存。
  • 内存是不可靠的,他丫的一断电数据就没了。
  • 那可靠的存储地方是哪里?硬盘、U盘、光盘等。
  • 我们的程序在运行时说的持久化通常就是指将内存的数据存在硬盘。

3️⃣持久层

对于分层的概念我们知道:

  • 业务是需要操作数据的
  • 数据是在磁盘上的
  • 具体业务调用具体的数据库操作,耦合度太高,复用性太差
  • 将操作数据库的代码统一抽离出来,自然就形成了介于业务层和数据库中间的独立的层

持久层的工作:

  • 完成持久化工作的代码块
  • 层之间的界限非常明显

4️⃣聊聊ORM

ORM,即Object-Relational Mapping(对象关系映射),它的作用是在关系型数据库和业务实体对象之间作一个映射,这样,我们在具体的操作业务对象的时候,就不需要再去和复杂的SQL语句打交道,只需简单的操作对象的属性和方法。

  • jpa(Java Persistence API)是java持久化规范,是orm框架的标准,主流orm框架都实现了这个标准。
  • hibernate: 全自动的框架,强大、复杂、笨重、学习成本较高,不够灵活,实现了jpa规范。Java Persistence API(Java 持久层 API)
  • MyBatis: 半自动的框架(懂数据库的人 才能操作) 必须要自己写sql,不是依照的jpa规范实现的。

很多人青睐 MyBatis ,原因是其提供了便利的 SQL 操作,自由度高,封装性好…… JPA对复杂 SQL 的支持不好,没有实体关联的两个表要做 join 的确要花不少功夫。

5️⃣MyBatis的优点和缺点

sql语句与代码分离,存放于xml配置文件中:

  • 优点:便于维护管理,不用在java代码中找这些语句;
  • 缺点:JDBC方式可以用打断点的方式调试,但是MyBatis调试比较复杂,一般要通过log4j日志输出日志信息帮助调试,然后在配置文件中修改。

用逻辑标签控制动态SQL的拼接:

  • 优点:用标签代替编写逻辑代码;
  • 缺点:拼接复杂SQL语句时,没有代码灵活,拼写比较复杂。不要使用变通的手段来应对这种复杂的语句。

查询的结果集与java对象自动映射:

  • 优点:保证名称相同,配置好映射关系即可自动映射或者,不配置映射关系,通过配置列名=字段名也可完成自动映射。
  • 缺点:对开发人员所写的SQL依赖很强。

编写原生SQL:

  • 优点:接近JDBC,比较灵活。
  • 缺点:对SQL语句依赖程度很高;并且属于半自动,数据库移植比较麻烦,比如MySQL数据库编程Oracle数据库,部分的SQL语句需要调整。

最重要的一点,使用的人多!公司需要!

二、第一个MyBatis程序

实现步骤:搭建环境—>导入MyBatis—>编写相关代码—>测试

1️⃣搭建环境

🍀(1)搭建数据库


   create database mybatis;
   use mybatis;

   create table user(
      id int(20) not null,
      name varchar(30) default null,
      pwd varchar(30) default null,
      primary key(id)
   )engine=InnoDB default charset=utf8mb4;

   insert into user(id,name,pwd) values
  (1,'张三','123'),
  (2,'李四','123'),
  (3,'王五','123');

🍀(2)新建一个普通maven项目作为父项目,并导入sql驱动,mybatis,junit组件


  <dependencies>

      <dependency>
          <groupId>mysqlgroupId>
          <artifactId>mysql-connector-javaartifactId>
          <version>5.1.46version>
      dependency>

      <dependency>
          <groupId>org.mybatisgroupId>
          <artifactId>mybatisartifactId>
          <version>3.5.2version>
      dependency>

      <dependency>
          <groupId>junitgroupId>
          <artifactId>junitartifactId>
          <version>4.12version>
      dependency>
  dependencies>

🍀(3)新建一个新组件作为子级项目,普通maven的module

🍀(4)添加配置文件

  • 在src->main->resources目录下新建mybatis-config.xml文件,把官方的配置代码复制粘贴(不能在配置文件中写中文注释)
  • 配置文件的作用就是连接数据库

  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">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
          <property name="driver" value="${driver}"/> //数据库驱动,不同驱动可连接不同数据库服务器
          <property name="url" value="${url}"/> //连接数据库的目录
          <property name="username" value="${username}"/> //数据库名字,默认root
          <property name="password" value="${password}"/> //数据库密码,自己的数据库密码,一般为root
        dataSource>
      environment>
    environments>
  configuration>

2️⃣编写mybatis工具类

MybatisUtils.java:


  public class MybatisUtils {
      private static SqlSessionFactory sqlSessionFactory;

      static {
          try {
              String resource="mybatis-config.xml";
              InputStream inputStream = Resources.getResourceAsStream(resource);
              sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
          } catch (IOException e) {
              e.printStackTrace();
          }
      }

      public static SqlSession getSqlSession(){ return sqlSessionFactory.openSession();}
  }

3️⃣编写相关代码

🍀(1)实体类

  public class User {
      private int id;
      private String name;
      private String pwd;
      public User() { }
      public User(int id, String name, String pwd) {
          this.id = id;
          this.name = name;
          this.pwd = pwd;
      }
      public int getId() {
          return id;
      }
      public void setId(int id) {
          this.id = id;
      }
      public String getName() {
          return name;
      }
      public void setName(String name) {
          this.name = name;
      }
      public String getPwd() {
          return pwd;
      }
      public void setPwd(String pwd) {
          this.pwd = pwd;
      }
      @Override
      public String toString() {
          return "User{" +
                  "id=" + id +
                  ", name='" + name + '\'' +
                  ", pwd='" + pwd + '\'' +
                  '}';
      }
  }

🍀(2)Dao接口

  public interface UserDao {
      List<User> getUserList();
  }

🍀(3)xxxMapper.xml配置文件

  • 接口的实现类要改为以xxxMapper.xml的配置文件
  • 注意事项:配置文件中不要写中文注释,如果非要写,解决方法见后面的异常解决方案

  DOCTYPE mapper
          PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
          "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

  <mapper namespace="com.wang.dao.UserDao">

      <select id="getUserList" resultType="com.wang.pojo.User">
          select * from mybatis.user where id = #{id}
      select>
  mapper>

每一个Mapper.xml文件都需要在src->main->resources目录下的mybatis-config.xml核心配置文件中注册:

<mappers>
  <mapper resource="com/wang/dao/UserMapper.xml">
mappers>

4️⃣测试

  public class UserDaoTest {
      @Test
      public void test(){

          SqlSession sqlSession = MybatisUtils.getSqlSession();

          UserDao mapper = sqlSession.getMapper(UserDao.class);
          List<User> list = mapper.getUserList();
          for (User u:list){
              System.out.println(u);
          }

          sqlSession.close();
      }
  }

三、使用Mybatis实现CRUD

1️⃣Mapper接口

public interface UserMapper {

    List<User> getUserList();

    User getUserById(int id);

    boolean insertNewUser(User u);

    boolean deleteUserById(int id);
    boolean deleteUserByName(String name);

    boolean updateUserById(User u);
}

2️⃣xxxMapper.xml文件


DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.wang.dao.UserMapper">
    <select id="getUserList" resultType="com.wang.pojo.User">
        select * from mybatis.user
    select>
    <select id="getUserById" parameterType="int" resultType="com.wang.pojo.User">
        select * from mybatis.user where id=#{id}
    select>

    <insert id="insertNewUser" parameterType="com.wang.pojo.User">
        insert into mybatis.user (id, name, pwd) VALUES (#{id},#{name},#{pwd})
    insert>
    <delete id="deleteUserById" parameterType="int">
        delete from mybatis.user where id=#{id}
    delete>
    <delete id="deleteUserByName" parameterType="String">
        delete from mybatis.user where name=#{name}
    delete>
    <update id="updateUserById" parameterType="com.wang.pojo.User">
        update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
    update>
mapper>

3️⃣测试类

public class UserDaoTest {
    @Test
    public void test(){

        SqlSession sqlSession = MybatisUtils.getSqlSession();
        try{

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

            List<User> list = mapper.getUserList();
            for (User u:list){
                System.out.println(u);
            }

            User user = mapper.getUserById(1);
            System.out.println(user);

            User user1 = new User(4,"李四","25615");
            boolean isInserted = mapper.insertNewUser(user1);
            sqlSession.commit();

            if (mapper.insertNewUser(new User(4,"李四","25615"))) sqlSession.commit();

            if (mapper.deleteUserById(4))sqlSession.commit();
            if (mapper.deleteUserByName("李四"))sqlSession.commit();

            if (mapper.updateUserById(new User(4,"王五","6849816")))sqlSession.commit();

        }finally {

            sqlSession.close();
        }
    }
}

4️⃣Map的使用

map可以代替任何的实体类,所以当我们数据比较复杂时,可以适当考虑使用map来完成相关工作。
🍀(1)写方法

UserMapper.java:

  User getUser(Map<String,Object> map);
  boolean addUser(Map<String,Object> map);

🍀(2)写sql

UserMapper.xml:

  <select id="getUser" parameterType="map" resultType="com.qian.pojo.User">
      select * from mybatis.user where id=#{userId}
  select>
  <insert id="addUser" parameterType="map">
      insert into mybatis.user (id, name, pwd) VALUES (#{userId},#{userName},#{password})
  insert>

🍀(3)测试

Test.java:

  @Test
  public void test(){

      SqlSession sqlSession = MybatisUtils.getSqlSession();
      UserMapper mapper = sqlSession.getMapper(UserMapper.class);
      Map<String, Object> map = new HashMap<String, Object>();
      map.put("userId",5);
      User user = mapper.getUser(map);
      System.out.println(user);
      map.put("userId",5);
      map.put("userName","孙悟空");
      map.put("password","123456");
      if (mapper.addUser(map)) sqlSession.commit();
      sqlSession.close();
  }

5️⃣模糊查询

🍀方案一:在Java代码中拼串

Test.java:

string name = "%IT%";
list<name> names = mapper.getUserByName(name);

UserMapper.xml:

<select id= "getUsersByName">
    select * from user where name like #{name}
select>

🍀方案二:在配置文件中拼接1

Test.java:

string name = "IT";
list<User> users = mapper.getUserByName(name);

UserMapper.xml:

<select id= "getUsersByName">
    select * from user where name like "%"#{name}"%"
select>

🍀方案三:在配置文件中拼接2

Test.java:

string name = "IT";
list<User> users = mapper.getUserByName(name);

UserMapper.xml:

<select id= "getUsersByName">
    select * from user where name like "%${name}%"
select>

四、Mybatis配置文件

1️⃣ 核心配置文件

核心配置文件mybatis-config.xml包含了会深深影响 MyBatis 行为的设置和属性信息。 配置文件的层次结构如下(顺序不能乱):

1.properties&#x662F;&#x4E00;&#x4E2A;&#x914D;&#x7F6E;&#x5C5E;&#x6027;&#x7684;&#x5143;&#x7D20;
2.settings&#x8BBE;&#x7F6E;&#xFF0C;mybatis&#x6700;&#x4E3A;&#x590D;&#x6742;&#x7684;&#x914D;&#x7F6E;&#x4E5F;&#x662F;&#x6700;&#x91CD;&#x8981;&#x7684;&#xFF0C;&#x4F1A;&#x6539;&#x53D8;mybatis&#x8FD0;&#x884C;&#x65F6;&#x5019;&#x7684;&#x884C;&#x4E3A;
3.typeAliases&#x522B;&#x540D;&#xFF08;&#x5728;TypeAliasRegistry&#x4E2D;&#x53EF;&#x4EE5;&#x770B;&#x5230;mybatis&#x63D0;&#x4F9B;&#x4E86;&#x8BB8;&#x591A;&#x7684;&#x7CFB;&#x7EDF;&#x522B;&#x540D;&#xFF09;
4.typeHandlers &#x7C7B;&#x578B;&#x5904;&#x7406;&#x5668;&#xFF08;&#x6BD4;&#x5982;&#x5728;&#x9884;&#x5904;&#x7406;&#x8BED;&#x53E5;&#x4E2D;&#x8BBE;&#x7F6E;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x6216;&#x8005;&#x4ECE;&#x7ED3;&#x679C;&#x96C6;&#x4E2D;&#x83B7;&#x53D6;&#x4E00;&#x4E2A;&#x53C2;&#x6570;&#x65F6;&#x5019;&#xFF0C;&#x90FD;&#x4F1A;&#x7528;&#x5230;&#x7C7B;&#x578B;&#x5904;&#x7406;&#x5668;&#xFF0C;&#x5728;TypeHandlerRegistry&#x4E2D;&#x5B9A;&#x4E49;&#x4E86;&#x5F88;&#x591A;&#x7684;&#x7C7B;&#x578B;&#x5904;&#x7406;&#x5668;&#xFF09;
5.objectFactory &#x5BF9;&#x8C61;&#x5DE5;&#x5382;&#xFF08;myabtis&#x5728;&#x6784;&#x5EFA;&#x4E00;&#x4E2A;&#x7ED3;&#x679C;&#x8FD4;&#x56DE;&#x7684;&#x65F6;&#x5019;&#xFF0C;&#x4F1A;&#x4F7F;&#x7528;&#x4E00;&#x4E2A;ObjectFactory&#x53BB;&#x6784;&#x5EFA;pojo)
6.plugins &#x63D2;&#x4EF6;
7.environments &#x73AF;&#x5883;&#x53D8;&#x91CF;
&#x2003;&#x2003;  environment &#x73AF;&#x5883;&#x53D8;&#x91CF;
&#x2003;&#x2003;&#x2003;    transactionManager &#x4E8B;&#x52A1;&#x7BA1;&#x7406;&#x5668;
&#x2003;&#x2003;&#x2003;    dataSource &#x6570;&#x636E;&#x6E90;
&#x2003;&#x2003;&#x2003;    databaseIdProvider &#x6570;&#x636E;&#x5E93;&#x5382;&#x5546;&#x6807;&#x8BC6;
8.mappers &#x6620;&#x5C04;&#x5668;

下面针对几个重要的元素environments,properties,mappers,typeAliases,settings进行讲解。

2️⃣environments(环境)

environments可以为mybatis配置多环境运行,将SQL映射到多个不同的数据库上,必须指定其中一个为默认运行环境(通过default指定),如果想切换环境修改default的值即可。

最常见的就是,生产环境和开发环境,两个环境切换必将导致数据库的切换。

<environments default="development">
 <environment id="development">
   <transactionManager type="JDBC">
     <property name="..." value="..."/>
   transactionManager>
   <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>

  <environment id="product">
       <transactionManager type="JDBC">
         <property name="..." value="..."/>
       transactionManager>
       <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>
  • dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
  • 数据源是必须配置的。有三种内建的数据源类型:
type="[UNPOOLED|POOLED|JNDI]"&#xFF09;
 - unpooled&#xFF1A;&#x8FD9;&#x4E2A;&#x6570;&#x636E;&#x6E90;&#x7684;&#x5B9E;&#x73B0;&#x53EA;&#x662F;&#x6BCF;&#x6B21;&#x88AB;&#x8BF7;&#x6C42;&#x65F6;&#x6253;&#x5F00;&#x548C;&#x5173;&#x95ED;&#x8FDE;&#x63A5;&#x3002;
 - pooled&#xFF1A;&#x8FD9;&#x79CD;&#x6570;&#x636E;&#x6E90;&#x7684;&#x5B9E;&#x73B0;&#x5229;&#x7528;&#x201C;&#x6C60;&#x201D;&#x7684;&#x6982;&#x5FF5;&#x5C06; JDBC &#x8FDE;&#x63A5;&#x5BF9;&#x8C61;&#x7EC4;&#x7EC7;&#x8D77;&#x6765; , &#x8FD9;&#x662F;&#x4E00;&#x79CD;&#x4F7F;&#x5F97;&#x5E76;&#x53D1; Web &#x5E94;&#x7528;&#x5FEB;&#x901F;&#x54CD;&#x5E94;&#x8BF7;&#x6C42;&#x7684;&#x6D41;&#x884C;&#x5904;&#x7406;&#x65B9;&#x5F0F;&#x3002;
 - jndi&#xFF1A;&#x8FD9;&#x4E2A;&#x6570;&#x636E;&#x6E90;&#x7684;&#x5B9E;&#x73B0;&#x662F;&#x4E3A;&#x4E86;&#x80FD;&#x5728;&#x5982; Spring &#x6216;&#x5E94;&#x7528;&#x670D;&#x52A1;&#x5668;&#x8FD9;&#x7C7B;&#x5BB9;&#x5668;&#x4E2D;&#x4F7F;&#x7528;&#xFF0C;&#x5BB9;&#x5668;&#x53EF;&#x4EE5;&#x96C6;&#x4E2D;&#x6216;&#x5728;&#x5916;&#x90E8;&#x914D;&#x7F6E;&#x6570;&#x636E;&#x6E90;&#xFF0C;&#x7136;&#x540E;&#x653E;&#x7F6E;&#x4E00;&#x4E2A; JNDI &#x4E0A;&#x4E0B;&#x6587;&#x7684;&#x5F15;&#x7528;&#x3002;
  • 数据源也有很多第三方的实现,比如druid,hikari,dbcp,c3p0等等…

  • 具体的一套环境,通过设置id进行区别,id保证唯一!

  • 子元素节点:transactionManager – [ 事务管理器 ](以下两种事务管理器类型都不需要设置任何属性)
<!-- 语法 -->
<transactionmanager type="[ JDBC | MANAGED ]">
</transactionmanager>
  • 子元素节点:数据源(dataSource)

3️⃣properties(属性)

数据库连接信息我们最好放在一个单独的文件中。

🍀(1)在资源目录下新建一个db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/ssm?useSSL=true&useUnicode=true&characterEncoding=utf8
username=root
password=root

🍀(2)将db.properties文件导入核心配置文件

<configuration>

   <properties resource="db.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>
configuration>

4️⃣mappers(映射器)

mappers的存在就是要对写好的mapper和xml进行统一管理,要不然系统怎么知道我们写了哪些mapper。

🍀(1)常用引入方式

<mappers>

    <mapper resource="com/wan/dao/userMapper.xml"/>

    <mapper class="com.wang.dao.AdminMapper"/>
mappers>

🍀(2)在Mapper文件里进行绑定


DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.wang.mapper.UserMapper">

mapper>

namespace中文意思:命名空间,作用是namespace的命名必须跟某个接口同名,这才能找到实现绑定。

5️⃣typeAliases(类型别名)

类型别名可为 Java 类型设置一个缩写名字。 它仅用于 XML 配置,意在降低冗余的全限定类名书写。

在mybatis-config.xml -> configuration进行配置:

  <typeAliases>
      <typeAlias type="com.wang.pojo.User" alias="user">typeAlias>

      <package name="com.wang.pojo"/>
  typeAliases>
  • 配置以后xxxMapper.xml的返回值(resultType)就可以替换为resultType user
  • 实体类较少的时候使用第一种,较多就直接扫描包目录
  • 第二种也可以用注解@Alias(“xxx”)给类起别名

6️⃣settings(设置)

settings能对我的一些核心功能进行配置,如懒加载、日志实现、缓存开启关闭等。

简单参数说明:

参数描述有效值默认值cacheEnabled该配置影响的所有映射器中配置的缓存的全局开关。true /falsetruelazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。true / falsefalseuseColumnLabel使用列标签代替列名。不同的驱动在这方面会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。true / falsetrueuseGeneratedKeys允许 JDBC 支持自动生成主键,需要驱动兼容。如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。true / falseFalsedefaultStatementTimeout设置超时时间,它决定驱动等待数据库响应的秒数。Any positive integerNot Set (null)mapUnderscoreToCamelCase是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。true / falseFalselogPrefix指定 MyBatis 增加到日志名称的前缀。Any StringNot setlogImpl指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J / LOG4J / LOG4J2 / JDK_LOGGING / COMMONS_LOGGING / STDOUT_LOGGING / NO_LOGGINGNot set

完整的 settings 元素,有很多可以配置的选项(可以自行了解):

<settings>

     <setting name="cacheEnabled" value="true"/>

     <setting name="lazyLoadingEnabled" value="true"/>

     <setting name="multipleResultSetsEnabled" value="true"/>
     <setting name="useColumnLabel" value="true"/>
     <setting name="useGeneratedKeys" value="false"/>
     <setting name="autoMappingBehavior" value="PARTIAL"/>
     <setting name="autoMappingUnknownColumnBehavior" value="WARNING"/>
     <setting name="defaultExecutorType" value="SIMPLE"/>
     <setting name="defaultStatementTimeout" value="25"/>
     <setting name="defaultFetchSize" value="100"/>
     <setting name="safeRowBoundsEnabled" value="false"/>
     <setting name="mapUnderscoreToCamelCase" value="false"/>
     <setting name="localCacheScope" value="SESSION"/>
     <setting name="jdbcTypeForNull" value="OTHER"/>
     <setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/>
settings>

五、Mybatis日志配置

配置日志的一个重要原因是想在调试的时候能观察到sql语句的输出,能查看中间过程

1️⃣标准日志实现

指定 MyBatis 应该使用哪个日志记录实现。如果此设置不存在,则会自动发现日志记录实现。
STDOUT_LOGGING:标准输出日志。

 <configuration>
      <properties resource="db.properties"/>
      <settings>
          <setting name="logImpl" value="STDOUT_LOGGING"/>
      settings>
      ... ...

  <configuration>

2️⃣组合logback完成日志功能

🍀(1)导入log4j的包

<dependency>
    <groupId>ch.qos.logbackgroupId>
    <artifactId>logback-classicartifactId>
    <version>${logback.version}version>
dependency>

🍀(2)log4j.properties配置文件


<configuration>

    <property name="pattern" value="%d{yyyy-MM-dd HH:mm:ss} %c [%thread] %-5level %msg%n"/>
    <property name="log_dir" value="d:/logs" />

    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">
        <target>System.outtarget>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}pattern>
        encoder>
    appender>

    <appender name="file" class="ch.qos.logback.core.FileAppender">

        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${pattern}pattern>
        encoder>

        <file>${log_dir}/sql.logfile>
    appender>

    <root level="ALL">
        <appender-ref ref="console"/>
    root>

    <logger name="mybatis.sql" level="debug" additivity="false">
        <appender-ref ref="console"/>
        <appender-ref ref="file"/>
    logger>

configuration>

🍀(3)setting设置日志实现

<settings>
   <setting name="logImpl" value="SLF4J"/>
settings>

六、resultMap详解

如果数据库字段和实体的字段是一一对应,那么MyBatis会【自动映射】,但是如果不一致,比如一个叫user一个叫username,那么就需要我们手动的建立一一映射的关系了。

🍀(1)Java实体类

public class User {

   private int id;
   private String name;
   private String password;

}

🍀(2)mapper接口


User selectUserById(int id);

🍀(3)mapper映射文件

<select id="selectUserById" resultType="user">
  select * from user where id = #{id}
select>

🍀(4)测试与结果分析

Test.java:

@Test
public void testSelectUserById() {
   UserMapper mapper = session.getMapper(UserMapper.class);
   User user = mapper.selectUserById(1);
   System.out.println(user);
   session.close();
}

结果:

User{id=1, name='null', password='123'}

查询出来发现 name为空 . 说明出现了问题!

分析:

  • select * from user where id = #{id} 可以看做select id,username,password from user where id = #{id}
  • mybatis会根据这些查询的列名(会将列名转化为小写,数据库不区分大小写) , 利用反射去对应的实体类中查找相应列名的set方法设值,当然找不到username

解决方案:

方案一:为列名指定别名 , 别名和java实体类的属性名一致 。

<select id="selectUserById" resultType="User">
  select id , username as name ,password from user where id = #{id}
select>

方案二:使用结果集映射->ResultMap 【推荐】

<resultMap id="UserMap" type="User">

   <id column="id" property="id"/>

   <result column="username" property="name"/>
   <result column="password" property="password"/>
resultMap>

<select id="selectUserById" resultMap="UserMap">
  select id , username , password from user where id = #{id}
select>

结论:

这个地方我们手动调整了映射关系,称之为【手动映射】。但如果不调整呢? MyBatis当然会按照 约定自动映射。
当然 约定的最基本的操作就是全部都一样,还有就是下划线和驼峰命名的自动转化。

<settings>

    <setting name="mapUnderscoreToCamelCase" value="true"/>
settings>

后记

最全面的Mybatis教程,从“开局”到“通关”,Ready Go!
↪️ 本文下接:最全面的Mybatis教程,从”开局”到”通关”(二)
👉 Java全栈学习路线可参考: 【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉 算法刷题路线可参考: 算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉 Java微服务开源项目可参考: 企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)

Original: https://blog.csdn.net/qq_42146402/article/details/127701358
Author: 小新要变强
Title: 最全面的Mybatis教程,从“开局”到“通关”,Ready Go!

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/654571/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球