MyBatis学习笔记--中篇

MyBatis学习

文章目录

  • MyBatis学习
    • 1、MyBatis 配置解析
      • 1.1、核心配置文件
      • 1.2、事务管理器(transactionManager)
      • 1.3、数据源(DataSource)
      • 1.4、属性(properties)
      • 1.5、类型别名(typeAliases)
      • 1.6、设置(setting)
      • 1.7、映射器(Mapper)
      • 1.8、生命周期和作用域
    • 2、解决属性名和字段名不一致的问题(resultMap)
      • 2.1、问题
      • 2.2、resultMap(结果集映射)
        • 2.2.1、简单结果集映射
        • 2.2.2、复杂结果集映射
    • 3、日志
      • 3.1、日志工厂
      • 3.2、LOG4j
    • 4、分页
      • 4.1、使用Limit分页语法:
      • 4.2、分页插件PageHelper
    • 5、使用注解开发
      • 5.1、面向接口编程
      • 5.2、使用注解开发
    • 6、Lombok
      • 6.1、Lombok介绍
      • 6.2、Lombok的使用步骤

1、MyBatis 配置解析

1.1、核心配置文件

  • mybatis-config.xml
  • MyBatis的配置文件包含了会深深影响MyBatis行为的设置和属性信息
  • MyBatis默认的事务管理器就是JDBC,默认连接池就是POOlED

MyBatis学习笔记--中篇_第1张图片

1.2、事务管理器(transactionManager)

在 MyBatis 中有两种类型的事务管理器(也就是 type=“[JDBC|MANAGED]”):

  • JDBC – 这个配置直接使用了 JDBC 的提交和回滚功能,它依赖从数据源获得的连接来管理事务作用域。默认情况下,为了与某些驱动程序兼容,它在关闭连接时启用自动提交。然而,对于某些驱动程序来说,启用自动提交不仅是不必要的,而且是一个代价高昂的操作。
  • MANAGED – 这个配置几乎没做什么。它从不提交或回滚一个连接,而是让容器来管理事务的整个生命周期(比如 JEE 应用服务器的上下文)。 默认情况下它会关闭连接。

1.3、数据源(DataSource)

dataSource 元素使用标准的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
MyBatis学习笔记--中篇_第2张图片
POOLED– 这种数据源的实现利用“池”的概念将 JDBC 连接对象组织起来,避免了创建新的连接实例时所必需的初始化和认证时间。 这种处理方式很流行,能使并发 Web 应用快速响应请求。

1.4、属性(properties)

我们可以通过properties属性来实现引用配置文件
这些属性都是可外部配置动态替换的,既可以在典型的Java属性文件中配置,又可以通过properties元素的子元素来传递。【db.properties】
编写数据库配置文件db.properties(这个文件要放到上面)

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSl=true;useUnicode=true;characterEncoding=utf8;serverTimezone=UTC
username=root
password=123456

在配置文件中引入:


    <properties resource="db.properties">
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
    properties>
  • 可直接引入外部文件
  • 可以在其中增加一些属性配置
  • 如果两个文件有同一字段,优先使用外部配置文件的!

1.5、类型别名(typeAliases)

  • 1、实体类起别名

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


  <typeAliases>
        <typeAlias type="com.yjr.pojo.User" alias="user"/>
    typeAliases>
    
   <select id="getUserLikeValue" resultType="user" >
        select * from user  where name like "%"#{value}"%"
    select>
  • 2、包起别名

也可以指定一个包名,MyBatis 会在包名下面搜索需要的 Java Bean,例如:


    <typeAliases>

        <package name="com.yjr.pojo"/>
    typeAliases>

每一个在包 com.yjr.pojo 中的 Java Bean,在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名(大写也行)比如 com.yjr.pojo.User 的别名为 user(或User);若有注解,则别名为其注解值。见下面的例子:

@Alias("radan")
public class User {
    private int id;
    private String name;
    private String pwd;
}

总结:实体类比较少的时候多采用第一种方式;当实体类比较多的时候,建议采用第二种方式。

1.6、设置(setting)

  • cacheEnabled:全局性地开启或关闭所有映射器配置文件中已配置的任何缓存。
  • lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置 fetchType 属性来覆盖该项的开关状态。
  • mapUnderscoreToCamelCase:是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
  • logImpl:指定 MyBatis 所用日志的具体实现,未指定时将自动查找。SLF4J | LOG4J(3.5.9 起废弃) | LOG4J2

1.7、映射器(Mapper)

MapperRegistry:注册绑定我们的Mapper文件

方式一(使用resource的资源引用–这个用斜杠划分)----推荐使用:
这样即可以将xml文件放到resource目录下,也可以避免下面的这些问题。

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

方式二(使用Class文件绑定注册):

    <mappers>
        <mapper class="com.yjr.dao.UserMapper"/>
   mappers>

注意点:

  • 接口和它的Mapper配置文件必须同名!
  • 接口和它的Mapper配置文件必须在同一个包下!

方式三(使用扫描包进行注册绑定):

    <mappers>
		 <package name="com.yjr.dao"/>
    mappers>

注意点:

  • 接口和它的Mapper配置文件必须同名!
  • 接口和它的Mapper配置文件必须在同一个包下!

1.8、生命周期和作用域

作用域、生命周期是至关重要的,因为错误的使用会导致非常严重的并发问题

SQLSessionFactoryBuilder:

  • 一旦创建了SQLSessionFactory,就不在需要它
  • 一般放在局部变量

SQLSessionFactory:

  • 简单想象为:数据库连接池
  • SQLSessionFactory一旦被创建就应该在应用的运行期间一直存在,没有理由丢弃它或重新创建另一个实例。
  • 因此SQLSessionFactory的最佳作用域是应用作用域。
  • 最简单的就是使用单例模式或者静态单例模式。

SQLSession:

  • 连接到连接池的一个请求!
  • SQLSession的实例不是线程安全的,因此不能被共享的,所以它的最佳作用域是请求或方法作用域。
  • 用完之后需要赶紧关闭 ,否则资源被占用!

2、解决属性名和字段名不一致的问题(resultMap)

2.1、问题

数据库中的字段:

在这里插入图片描述

实体类中的字段:


public class User {
    private int id;
    private String name;
    private String password; //显然不一致
}

结果:
在这里插入图片描述

问题:当实体类的字段名和数据库中字段名不一致时,程序可以执行,但是测试的结果是查询的所有记录的该字段值为null。
解决方法:

  • 在sql字段中起别名
 <select id="getAllUsers" resultType="User">
        select id,name,pwd as password from user
   </select>

2.2、resultMap(结果集映射)

  • resultMap 元素是 MyBatis 中最重要最强大的元素。
  • ResultMap 的设计思想是,对简单的语句做到零配置,对于复杂一点的语句,只需要描述语句之间的关系就行了。
2.2.1、简单结果集映射

column:数据库中的字段 property:实体类中的属性

 
    <resultMap id="userMap" type="User">
        
        <result property="id" column="id"/>
        <result property="name" column="name"/>
        <result property="password" column="pwd"/>
    resultMap>
    
    <select id="getAllUsers" resultMap="userMap">
        select * from user
    select>
2.2.2、复杂结果集映射

3、日志

在这里插入图片描述

  • SLF4J (掌握)
  • LOG4J (掌握)
  • LOG4J2
  • JDK_LOGGING
  • COMMONS_LOGGING
  • STDOUT_LOGGING (掌握)
    NO_LOGGING

3.1、日志工厂

在MyBatis中具体事宜哪一个日志,在设置中设定!
STDOUT_LOGGING标准日志输出
在mybatis核心配置文件中,配置日志。

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

STDOUT_LOGGING标准日志–打印结果
MyBatis学习笔记--中篇_第3张图片

3.2、LOG4j

什么是log4j?

  • Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件等。
  • 可以控制每一条日志的输出格式
  • 通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程。
  • 可以通过一个配置文件来灵活地进行配置,而不需要修改应用的代码
  1. 先导入LOG4j的相关依赖
 
        <dependency>
            <groupId>log4jgroupId>
            <artifactId>log4jartifactId>
            <version>1.2.17version>
        dependency>
        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-apiartifactId>
            <version>1.7.25version>
        dependency>
        <dependency>
            <groupId>org.slf4jgroupId>
            <artifactId>slf4j-simpleartifactId>
            <version>1.7.25version>
            <scope>testscope>
        dependency>
        
  1. 配置log.properties文件
#将等级为DEBUG的日志信息输出到console和file这两个目的地,console和file的定义在下面的代码
log4j.rootLogger=debug, console, file

#控制台输出的相关设置
log4j.appender.console = org.apache.log4j.ConsoleAppender
log4j.appender.console.target = System.out
log4j.appender.console.Threshold = debug
log4j.appender.console.layout = org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern =  [%c] -%m%n

#文件输出的相关设置
log4j.appender.file = org.apache.log4j.RollingFileAppender
log4j.appender.file.File=./log/yjr.log

log4j.appender.file.MaxFileSize = 10mb
log4j.appender.file.Threshold = DEBUG
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = [%p][%d{yy-MM-dd}][%c]%m%n

#日志输出级别
log4j.logger.org.mybatis = debug
log4j.logger.java.sql = debug
log4j.logger.java.sql.Statement = debug
log4j.logger.java.sql.ResultSet = debug
log4j.logger.java.sql.PreparedStatement  = debug
  1. 配置log4j为日志的实现
    <settings>
        <setting name="logImpl" value="LOG4J"/>
    settings>
  1. log4j的使用

MyBatis学习笔记--中篇_第4张图片
简单使用

  1. 在要使用Log4j的类中,导入包import org.apache.log4j.Logger;
  2. 日志对象,参数为当前的class
    static   Logger logger= Logger.getLogger(UserDaoTest.class);
  1. 日志级别
        logger.info("info:进入了testLog4j方法");
        logger.debug("debug:进入了testLog4j方法");
        logger.error("error:进入了testLog4j方法");

4、分页

思考:为什么分页?–减少数据的处理量

4.1、使用Limit分页语法:

select * from  user limit startIndex,pageSize #startIndex:其实下标(默认从0开始,pageSize :一页的大小)
select * from  user  limit 3; #[0,n]

使用MyBatis实现分页,核心SQL

  • 接口
    //分页
    List<User> getUserByLimit(Map<String,Integer> map);
  • Mapper.xml
    
    <select id="getUserByLimit" parameterType="map" resultMap="userMap" >
        select * from user limit #{startIndex},#{pageSize}
    select>
  • 测试
 @Test
    public void getUserByLimit() throws IOException {
        HashMap hashMap=new HashMap();
        hashMap.put("startIndex",0);
        hashMap.put("pageSize",2);
        //1.获取SQLSession对象
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //方式一:getMapper-----目前最好用
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        System.out.println(mapper.getUserByLimit(hashMap));
        sqlSession.close();

    }

4.2、分页插件PageHelper

参考资料:PageHelper中文文档

5、使用注解开发

5.1、面向接口编程

根本原因:解耦,可拓展,提高复用;在分层开发中,上层不管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性更好。
接口的理解:

  • 接口从更深层次的理解,就是定义(规范,约束)与实现的分离
  • 接口的本身反映了系统设计人员对系统的抽象理解。
  • 接口应有两类:
    • 第一类是对一个个体的抽象,它可对应为一个抽象体(Abstract Class);
    • 第二类是对一个个体某一方面的抽象,即形成一个抽象面(interface);
  • 一个体由可能有多个抽象面。抽象体与抽象面试有区别的。
    三个面向区别:
  • 面向对象是指:我们考虑问题时,以对象为单位,考虑它的属性及方法。
  • 面向过程是指,我们在考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现。
  • 接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题,更多体现的是对系统整体的架构。

5.2、使用注解开发

  1. 注解直接在接口上实现
   //查询所有用户
    @Select("select * from user")
    List<User> getAllUsers();
  1. 需要在核心配置文件中绑定接口

    <mappers>
        <mapper class="com.yjr.dao.UserMapper"/>
    mappers>
  1. 测试
    @Test
    public void getAllUsersTest() throws IOException {
        //1.获取SQLSession对象
        SqlSession sqlSession = MyBatisUtils.getSqlSession();
        //方式一:getMapper-----目前最好用
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        System.out.println(mapper.getAllUsers());
        sqlSession.close();

    }

注意点(实体类和数据库中的字段出现不一致):

   @Select("select * from user")
    @Results({
            @Result(property = "id", column = "id"),
            @Result(property = "name", column = "name"),
            @Result(property = "password", column = "pwd")
            //column :数据库中的名字  property:实体类中的名字
    })

    List<User> getAllUsers();

用@Results注解来解决上述问题。
MyBatis详细的执行流程
MyBatis学习笔记--中篇_第5张图片

6、Lombok

6.1、Lombok介绍

Lombok项目是一个java库,它可以自动插入到编辑器和构建工具中,增强java的性能。不需要再写getter、setter或equals方法,只要有一个注解,就有一个功能齐全的构建器、自动记录变量等等。

常用注解:

MyBatis学习笔记--中篇_第6张图片

@Data:无参构造、get、set、toString、hasCode、equals
@AllArgsConstructor:有参构造
@NoArgsConstructor:无参构造
@toString:生成一个toSring()方法
@Getter:给所有的属性生成get方法
@Setter:给所有的属性生成set方法
Lombok的优点:

  • 能通过注解的1方法自动生成构造器、getter/setter、equals、hashcode、toString等方法,提升了开发效率
  • 让代码变得简洁,不用过多的去关注相应的方法
  • 属性做修改时,也简化了维护为这些属性所生成的getter/setter方法等。

Lombok的缺点:

  • 不支持多种参数构造器的重载
  • 虽然省去了手动创建各种方法的麻烦,但大大降低了源代码的可读性和完整性,降低了阅读源代码的舒适度。

6.2、Lombok的使用步骤

使用步骤:

  1. 在IDEA中按照Lombok插件!
  2. 在项目中导入lombok的包

<dependency>
    <groupId>org.projectlombokgroupId>
    <artifactId>lombokartifactId>
    <version>1.18.24version>
    <scope>providedscope>
dependency>

  1. 在实体类上加注解
package com.yjr.pojo;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

@NoArgsConstructor
@Data
@AllArgsConstructor
public class User {
    private int id;
    private String name;
    private String password;
}

你可能感兴趣的:(MyBatis,mybatis,学习,笔记)