最全面的Mybatis教程,从“开局”到“通关”(一)

前言

在这里插入图片描述

本文为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微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)


目录

在这里插入图片描述

一、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>
      <!--mysql驱动-->
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.46</version>
      </dependency>
      <!--Mybatis-->
      <dependency>
          <groupId>org.mybatis</groupId>
          <artifactId>mybatis</artifactId>
          <version>3.5.2</version>
      </dependency>
      <!--junit-->
      <dependency>
          <groupId>junit</groupId>
          <artifactId>junit</artifactId>
          <version>4.12</version>
      </dependency>
  </dependencies>

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

🍀(4)添加配置文件

  • 在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>
    <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:

  //SqlSessionFactory --生产--> SqlSession
  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();
          }
      }
      //获取sqlSession
      //SqlSession完全包含了面向对象数据库执行SQL命令所需的方法
      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的配置文件
  • 注意事项:配置文件中不要写中文注释,如果非要写,解决方法见后面的异常解决方案
  <?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:命名空间,绑定mapper/Dao接口-->
  <mapper namespace="com.wang.dao.UserDao">
  <!--id:接口的方法,resultType:接口的返回值类型-->
      <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 sqlSession = MybatisUtils.getSqlSession();
          //获取mapper
          UserDao mapper = sqlSession.getMapper(UserDao.class);
          List<User> list = mapper.getUserList();
          for (User u:list){
              System.out.println(u);
          }
          //不推荐使用以下方式
          /*
          这种方式能够正常工作,对使用旧版本 MyBatis 的用户来说也比较熟悉。但现在有了一种更简洁的方    式——使用和指定语句的参数和返回值相匹配的接口(比如 BlogMapper.class),现在你的代码不仅更清晰,更加 类型安全,还不用担心可能出错的字符串字面值以及强制类型转换。
          */
          // List<User> list =  sqlSession.selectList("com.qian.dao.UserDao.getUserList");
          // for (User user : list) {
          //     System.out.println(user);
          // }
          
          //关闭SqlSession
          sqlSession.close();
      }
  }

三、使用Mybatis实现CRUD

1️⃣Mapper接口

public interface UserMapper {
    //查询全部用户
    List<User> getUserList();
    //根据id查询用户
    User getUserById(int id);
    //增加新的用户
    boolean insertNewUser(User u);
    //删除用户
    boolean deleteUserById(int id);
    boolean deleteUserByName(String name);
    //修改用户
    boolean updateUserById(User u);
}

2️⃣xxxMapper.xml文件

<?xml version="1.0" encoding="utf8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--namespace:命名空间,绑定mapper/Dao接口-->
<!--id:接口的方法,resultType:接口的返回值类型-->
<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 sqlSession = MybatisUtils.getSqlSession();
        try{
            //获取mapper
            UserMapper mapper = sqlSession.getMapper(UserMapper.class);
            
            // 查询全表
            List<User> list = mapper.getUserList();
            for (User u:list){
                System.out.println(u);
            }
            
            //根据id查询
            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
            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 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是一个配置属性的元素
2.settings设置,mybatis最为复杂的配置也是最重要的,会改变mybatis运行时候的行为
3.typeAliases别名(在TypeAliasRegistry中可以看到mybatis提供了许多的系统别名)
4.typeHandlers 类型处理器(比如在预处理语句中设置一个参数或者从结果集中获取一个参数时候,都会用到类型处理器,在TypeHandlerRegistry中定义了很多的类型处理器)
5.objectFactory 对象工厂(myabtis在构建一个结果返回的时候,会使用一个ObjectFactory去构建pojo)
6.plugins 插件
7.environments 环境变量
    environment 环境变量
       transactionManager 事务管理器
       dataSource 数据源
       databaseIdProvider 数据库厂商标识
8.mappers 映射器

下面针对几个重要的元素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]")
 - unpooled:这个数据源的实现只是每次被请求时打开和关闭连接。
 - pooled:这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来 , 这是一种使得并发 Web 应用快速响应请求的流行处理方式。
 - jndi:这个数据源的实现是为了能在如 Spring 或应用服务器这类容器中使用,容器可以集中或在外部配置数据源,然后放置一个 JNDI 上下文的引用。
  • 数据源也有很多第三方的实现,比如druid,hikari,dbcp,c3p0等等…
  • 具体的一套环境,通过设置id进行区别,id保证唯一!
  • 子元素节点:transactionManager - [ 事务管理器 ](以下两种事务管理器类型都不需要设置任何属性)
<!-- 语法 -->
<transactionManager type="[ JDBC | MANAGED ]"/>
  • 子元素节点:数据源(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文件-->
   <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文件里进行绑定

<?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="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 /falsetrue
lazyLoadingEnabled延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。true / falsefalse
useColumnLabel使用列标签代替列名。不同的驱动在这方面会有不同的表现,具体可参考相关驱动文档或通过测试这两种不同的模式来观察所用驱动的结果。true / falsetrue
useGeneratedKeys允许 JDBC 支持自动生成主键,需要驱动兼容。如果设置为 true 则这个设置强制使用自动生成主键,尽管一些驱动不能兼容但仍可正常工作(比如 Derby)。true / falseFalse
defaultStatementTimeout设置超时时间,它决定驱动等待数据库响应的秒数。Any positive integerNot Set (null)
mapUnderscoreToCamelCase是否开启自动驼峰命名规则(camel case)映射,即从经典数据库列名 A_COLUMN 到经典 Java 属性名 aColumn 的类似映射。true / falseFalse
logPrefix指定 MyBatis 增加到日志名称的前缀。Any StringNot set
logImpl指定 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.logback</groupId>
    <artifactId>logback-classic</artifactId>
    <version>${logback.version}</version>
</dependency>

🍀(2)log4j.properties配置文件

<?xml version="1.0" encoding="UTF-8"?>
<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.out</target>
        <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.log</file>
    </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;  		    //id
   private String name;   		//姓名,数据库为username
   private String password;     //密码,一致
   
   //构造
   //set/get
   //toString()
}

🍀(2)mapper接口

//根据id查询用户
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为主键 -->
   <id column="id" property="id"/>
   <!-- column是数据库表的列名 , property是对应实体类的属性名 -->
   <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教程,从“开局”到“通关”(二)
👉Java全栈学习路线可参考:【Java全栈学习路线】最全的Java学习路线及知识清单,Java自学方向指引,内含最全Java全栈学习技术清单~
👉算法刷题路线可参考:算法刷题路线总结与相关资料分享,内含最详尽的算法刷题路线指南及相关资料分享~
👉Java微服务开源项目可参考:企业级Java微服务开源项目(开源框架,用于学习、毕设、公司项目、私活等,减少开发工作,让您只关注业务!)

  • 62
    点赞
  • 48
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 101
    评论
### 回答1: 华为OLT(Optical Line Terminal)是华为公司推出的一种用于光纤接入的设备,是光纤通信网络的核心设备之一。下面是华为OLT开局配置教程。 1. 连接OLT设备:首先,将OLT设备与上级设备(如光纤交换机)进行连接。确保连接线路无损坏,插头连接牢固。 2. 进入OLT设备:使用电脑通过网线将其与OLT设备进行连接。在浏览器中输入OLT设备的IP地址,进入OLT设备的界面。 3. 登录OLT设备:在OLT设备界面上输入默认的用户名和密码进行登录。通常,默认的用户名为admin,密码为admin或者为空。 4. 创建VLAN:在OLT设备界面上找到VLAN菜单,点击进入。在此处可以创建所需的VLAN。 5. 配置端口:选择需要配置的端口,进入端口配置界面。在此处可以设置端口参数,如速率、模式等。根据需求进行设置。 6. 配置线路模板:选择需要配置的线路模板,进入线路模板配置界面。在此处可以设置线路模板的参数,如带宽、业务类型等。 7. 创建虚拟接口:在OLT设备界面上找到虚拟接口菜单,点击进入。在此处可以创建需要的虚拟接口,并进行相应的配置。 8. 配置业务:选择需要配置的业务,进入业务配置界面。在此处可以设置业务的参数,如IP地址、子网掩码等。 9. 验证配置:完成所有配置后,进行配置的验证。检查线路是否正常工作,各个业务是否正常连接,确保配置的正确性。 10. 保存配置:完成所有配置并验证通过后,将配置保存。确保配置的持久性,防止重启或断电后配置丢失。 以上是华为OLT开局配置的简要教程。具体配置过程可能有所差异,根据不同设备型号和版本可能会有所不同。在实际操作中应严格按照设备的说明文档进行配置,确保配置的正确性和稳定性。 ### 回答2: 华为OLT的开局配置是指在OLT设备初始化启动时进行的一系列配置步骤,以确保设备正常运行和提供网络服务。 首先,开局配置需要连接到OLT的管理口,可以使用网线将管理口连接到电脑的网口。 然后,通过电脑的网络设置,为管理口配置一个IP地址和子网掩码,保证能够与OLT设备进行通信。 接下来,打开浏览器,输入OLT的管理IP地址,在登录界面输入默认的用户名和密码进行登录。默认的用户名一般为admin,密码为admin或者huawei。 登录后,进入OLT设备的Web界面,选择“系统配置”菜单,对OLT进行基本配置,如设备名称、时钟同步参数等。同时,需要设置TELNET或SSH接入方式,以便远程管理和配置。 然后,点击“端口配置”菜单,对OLT的上联口和PON口进行配置。上联口用于连接到上级网络设备,一般设置为对应的接口类型和速率。PON口用于连接到ONU设备,需要配置PON口的属性,如VLAN绑定、QoS策略等。 此外,还需要进行VLAN配置、用户和服务配置等。VLAN配置包括创建VLAN,配置VLAN接入方式和转发方式等。用户和服务配置包括创建用户,配置用户接入限制和服务模板等。 最后,保存配置并重启OLT设备,使配置生效。 通过以上步骤,就可以完成华为OLT的开局配置,使设备能够正常运行并提供网络服务。当然,具体的配置操作和界面可能因不同的OLT型号而有所差异,以上是一个基本的配置流程。在实际操作中,用户还需根据网络需求和具体情况进行相应的配置调整。 ### 回答3: 华为OLT(Optical Line Terminal)是一种用于接入光纤宽带的设备,它在光纤网络中起到核心交换和分发的重要作用。下面是华为OLT开局配置的简要教程。 首先,在连接OLT设备之前,需要准备好相应的光纤接入线路和光纤终端设备。确保光纤线路的连接正常以及终端设备的良好工作状态。 第二步是进入OLT设备的配置界面。通常,可以通过网络连接到OLT设备的管理口,并使用预设的IP地址进行登录。然后,在登录成功后,进入系统的配置界面。 接下来,创建逻辑型端口(LP)和线路型端口(LP)以及相关的VLAN(Virtual Local Area Network)。通过配置逻辑型端口,可以实现ONT(Optical Network Terminal)端口与线路型端口之间的绑定。而通过配置VLAN,可以实现不同用户之间的隔离和管理。 在创建端口和VLAN之后,需要进行业务规划和配置。这包括设置用户接入类型(如宽带、语音等)、带宽限制、路由配置等。根据实际需求,进行相应的参数配置和规则设置。 最后,进行OLT设备的基本安全配置。这包括设置管理口的访问权限和密码、开启设备日志记录等。确保OLT设备的安全性和稳定性。 以上是华为OLT开局配置的简要教程。在实际操作中,可能会涉及更多细节和复杂的配置设置。因此,建议在进行配置操作时,参考相关的华为OLT设备的官方文档和操作手册,以确保正确和顺利完成配置工作。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小新要变强

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值