MyBatis从前世到今生一网打尽(上)

本文涉及的产品
云数据库 RDS MySQL,集群系列 2核4GB
推荐场景:
搭建个人博客
RDS MySQL Serverless 基础系列,0.5-2RCU 50GB
云数据库 RDS PostgreSQL,集群系列 2核4GB
简介: 框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种认为,框架是可被应用开发者定制的应用骨架、模板。​ 简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来说框架一个舞台,你在舞台上做表演。在框架基础上加入你要完成的功能。

1.JPG


一、框架概述


1.1 软件开发常用结构


1.1.1、三层架构


2.JPG


三层架构包含的三层:

  1. 界面层(User Interface layer)
  2. 业务逻辑层(Business Logic Layer)
  3. 数据访问层(Data access layer)

三层架构分别的职责是:

  1. 界面层(表示层,视图层):主要功能是接受用户的数据,显示请求的处理结果。使用 web 页面和 用户交互,手机 app 也就是表示层的,用户在 app 中操作,业务逻辑在服务器端处理。


  1. 业务逻辑层:接收表示传递过来的数据,检查数据,计算业务逻辑,调用数据访问层获取数据。


  1. 数据访问层:与数据库打交道。主要实现对数据的增、删、改、查。将存储在数据库中的数据提交 给业务层,同时将业务层处理的数据保存到数据库。
    他们处理请求的交互过程是:用户——> 界面层——>业务逻辑层——>数据访问层——>DB 数据库


1.1.2、为什么要使用三层架构


  1. 结构清晰,耦合度低,各层分工明确。
  2. 可维护性高,可拓展性高。
  3. 有利于标准化。
  4. 开发人员可以只关注整个结构中的其中某一层的功能实现。
  5. 有利于各层逻辑的复用。


1.2、框架初探究


1.2.1、什么是框架


框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种认为,框架是可被应用开发者定制的应用骨架、模板。 简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来说框架一个舞台,你在舞台上做表演。在框架基础上加入你要完成的功能。 框架安全的,可复用的,不断升级的软件。


1.2.1、框架解决的问题


框架要解决的最重要的一个问题是技术整合,在 J2EE 的 框架中,有着各种各样的技术,不同的应用,系统使用不同的技术解决问题。需要从 J2EE 中选择不同的技术,而技术自身的复杂性,有导致更大的风险。


企业在开发软件项目时,主要目的是解决业务问题。 即要求企业负责技术本身,又要求解决业务问题。这是大多数企业不能完成的。框架把相关的技术融合在一起,企业开发可以集中在业务领域方面。


1.3、常用框架


1.3.1、Mybatis


MyBatis 是一个优秀的基于 java 的持久层框架,内部封装了 jdbc,开发者只需要关注 sql 语句本身,而不需要处理加载驱动、创建连接、创建 statement、关闭连接,资源等繁杂的过程。
  MyBatis 通过 xml 或注解两种方式将要执行的各种 sql 语句配置起来,并通过 java 对象和 sql 的动态参数进行映射生成最终执行的 sql 语句,最后由 mybatis 框架执行 sql 并将结果映射为 java对象并返回。
复制代码


1.3.2、Spring


Spring 框架为了解决软件开发的复杂性而创建的。Spring 使用的是基本的 JavaBean 来完成以前非常复杂的企业级开发。Spring 解决了业务对象,功能模块之间的耦合,不仅在 javase,web 中使用,大部分 Java 应用都可以从 Spring 中受益。
  Spring 是一个轻量级控制反转(IoC)和面向切面(AOP)的容器。
复制代码


1.3.3、SpringMVC


Spring MVC 属于 SpringFrameWork 3.0 版本加入的一个模块,为 Spring 框架提供了构建 Web应用程序的能力。现在可以 Spring 框架提供的 SpringMVC 模块实现 web 应用开发,在 web 项目中可以无缝使用 Spring 和 Spring MVC 框架
复制代码


二、Mybatis简介

2.1、传统的JDBC


2.1.1、代码


public void findStudent() {
    Connection conn = null;
    Statement stmt = null;
    ResultSet rs = null;
try {
    //注册 mysql 驱动
    Class.forName("com.mysql.jdbc.Driver");
    //连接数据的基本信息 url ,username,password
    String url = "jdbc:mysql://localhost:3306/springdb";
    String username = "root";
    String password = "123456";
    //创建连接对象
    conn = DriverManager.getConnection(url, username, password);
    //保存查询结果
    List<Student> stuList = new ArrayList<>();
    //创建 Statement, 用来执行 sql 语句
    stmt = conn.createStatement();
    //执行查询,创建记录集,
    rs = stmt.executeQuery("select * from student");
    while (rs.next()) {
        Student stu = new Student();
        stu.setId(rs.getInt("id"));
        stu.setName(rs.getString("name"));
        stu.setAge(rs.getInt("age"));
      //从数据库取出数据转为 Student 对象,封装到 List 集合
      stuList.add(stu);
}
    } catch (Exception e) {
    e.printStackTrace();
} finally {
  try {
    //关闭资源
    if (rs != null) ;
    {
      rs.close();
    }
    if (stmt != null) {
      stmt.close();
    }
    if (conn != null) {
      conn.close();
    }
  } catch (Exception e) {
      e.printStackTrace();
    }
  }
}
复制代码


2.1.2、存在的问题


我们在使用JDBC进行实际开发过程中存在的问题也是很明显的:


  1. 代码比较多,开发效率低。
  2. 需要关注 Connection ,Statement, ResultSet 对象创建和销毁。
  3. 对 ResultSet 查询的结果,需要自己封装为 List。
  4. 重复的代码比较多。
  5. 业务代码和数据库的操作混在一起,不利于现代的开发习惯。


2.2、MyBatis 历史


MyBatis 是 Apache 的一个开源项目 iBatis, 2010 年 6 月这个项目由 Apache Software Foundation 迁移到了 Google Code,随着开发团队转投 Google Code 旗下, iBatis3.x 正式更名为 MyBatis ,代码于 2013 年 11 月迁移到 Github。

iBatis 一词来源于“internet”和“abatis”的组合,是一个基于 Java 的持久层框架。 iBatis 提供的持久层框架包括 SQL Maps 和 Data Access Objects(DAO)。


2.3、MyBatis 简介


  1. MyBatis 是支持定制化 SQL、存储过程以及高级映射的优秀的持久层框架。
  2. MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集
  3. MyBatis 可以使用简单的XML 或注解用于配置和原始映射,将接口和JavaOld Java Objects,普通的 Java 。对象)映射成数据库中的记录。


2.4、现有持久化技术的对比


2.4.1、JDBC


  • SQL 夹在 Java 代码块里,耦合度高导致硬编码内伤。
  • 维护不易且实际开发需求中 sql 是有变化,频繁修改的情况多见。


2.4.2、Hibernate 和 JPA。


  • 长难复杂 SQL,对于 Hibernate 而言处理也不容易。
  • 内部自动生产的 SQL,不容易做特殊优化。
  • 基于全映射的全自动框架,大量字段的 POJO 进行部分映射时比较困难。导致数据库性能下降。


2.4.3、MyBatis


  • 对开发人员而言,核心 sql 还是需要自己优化。
  • sql 和 java 编码分开,功能边界清晰,一个专注业务、一个专注数据。


2.5、MyBatis解决的问题


  1. 减轻使用 JDBC 的复杂性,不用编写重复的创建 Connetion , Statement 。
  2. 不用编写关闭资源代码。
  3. 直接使用 java 对象,表示结果数据。让开发者专注 SQL 的处理。 其他分心的工作由 MyBatis 代劳。


2.6、下载 MyBatis


下载网址:github.com/mybatis/myb…

3.JPG

4.JPG

5.JPG


三、入门MyBatis


3.1、开发环境的准备


3.1.1、导入 jar包


一般的我们要导入三个jar包。


myBatis-3.4.1.jar
mysql-connector-java-5.1.37-bin.jar
log4j.jar
复制代码


3.1.2、导入 log4j 的配置文件


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
    <logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
复制代码


3.1.3、创建测试表


-- 创建库
CREATE DATABASE test_mybatis;
-- 使用库
USE test_mybatis;
-- 创建表
CREATE TABLE user(
id INT(11) PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(50),
pwd VARCHAR(50),
);
复制代码


3.1.4、创建 javaBean


package com.domain;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
 * @author Xiao_Lin
 * @date 2021/1/5 11:33
 */
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
  private Integer id;
  private String username;
  private String pwd;
}
复制代码


3.1.5、创建 MyBatis 的全局配置文件


<?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>
  <!--配置 mybatis 环境-->
  <environments default="mysql">
    <!--id:数据源的名称-->
    <environment id="mysql">
    <!--配置事务类型:使用 JDBC 事务(使用 Connection 的提交和回滚)-->
      <transactionManager type="JDBC"/>
      <!--数据源 dataSource:创建数据库 Connection 对象
      type: POOLED 使用数据库的连接池
      -->
                <dataSource type="POOLED">
                    <!--连接数据库的四个要素-->
                    <property name="driver" value="com.mysql.jdbc.Driver"/>
                    <property name="url" value="jdbc:mysql:///javaweb?characterEncoding=utf-8&amp;useSSL=false"/>
                    <property name="username" value="root"/>
                    <property name="password" value="1101121833"/>
                </dataSource>
    </environment>
  </environments>
  <mappers>
    <!--告诉 mybatis 要执行的 sql 语句的位置,写的路径是字节码输出路径-->
    <mapper resource="com/dao/StudentDao.xml"/>
  </mappers>
</configuration>
复制代码


3.1.6、编写UserDao接口


public interface UserDao {
  /*查询所有数据*/
  List<User> selectAll();
}
复制代码


3.1.7、创建 Mybatis 的 sql 映射文件


<?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" >
    <!--
      用来存储SQL语句的
      namespace属性里面必须写 用来书写当前的mapper是对哪个DAO接口的实现
      他的意思是表示该配置文件的唯一标识,意味着不同的XxxMapper.xml文件的namespace的值时不同的
      -->
    <!--
      select标签表示查询操作,
        id属性表示在mapper配置文件中是唯一标识,一般使用方法名作为其值。
        paraType属性表示传入参数的类型,可省略不写,底层使用了反射,根据传入参数得到对象的类型      标签体中编写sql语句,#{变量},#表示占位符,和jdbc的?一样。
          如果传入的参数是简单类型(包括String),那么该类型可以任意写
          如果传入的参数是对象类型,那么变量的名称必须使用对象对应的类中的属性
      resultType: 查询语句的返回结果数据类型,使用全限定类名
      -->
<mapper namespace="com.mapper.UserDao">
  <select id="selectAll" resultType="com.domain.User">
    select * from user
  </select>
</mapper>
复制代码


3.1.8、配日志


mybatis.xml 文件加入日志配置,可以在控制台输出执行的 sql 语句和参数。


<settings>
  <setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
复制代码


3.1.9、测试


public class test {
        /*
    * mybatis 入门
    */
  @Test
  public void testStart() throws IOException {
    //1.mybatis 主配置文件
    String config = "mybatis-config.xml";
    //2.读取配置文件
    InputStream in = Resources.getResourceAsStream(config);
    //3.创建 SqlSessionFactory 对象,目的是获取 SqlSession
    SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
    //4.获取 SqlSession,SqlSession 能执行 sql 语句
    SqlSession session = factory.openSession();
    //5.执行 SqlSession 的 selectList()
    List<User> users = session.selectList("com.dao.UserDao.selectAll");
    //6.循环输出查询结果
    studentList.forEach( u -> System.out.println(u));
    //7.关闭 SqlSession,释放资源
    session.close();
    }
}
复制代码


3.2、CRUD操作


3.2.1、insert


接口中新增方法

int insertUser(User user);
复制代码


xml中新增sql语句

<insert id="insertUser">
insert into user(id,username,pwd) values(#{id},#{username},#{pwd})
</insert>
复制代码


新增测试方法

@Test
public void testInsert() throws IOException {
  //1.mybatis 主配置文件
  String config = "mybatis-config.xml";
  //2.读取配置文件
  InputStream in = Resources.getResourceAsStream(config);
  //3.创建 SqlSessionFactory 对象
  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
  //4.获取 SqlSession
  SqlSession session = factory.openSession();
  //5.创建保存数据的对象
  User user = new User();
  user.setId(1005);
  user.setUsername("张三");
  user.setPwd("123456");
  //6.执行插入 insert
  int rows = session.insert("com.dao.UserDao.insertUser",student);
  //7.提交事务
  session.commit();
  System.out.println("增加记录的行数:"+rows);
  //8.关闭 SqlSession
  session.close();
}
复制代码


3.2.2、update


UserDao 接口中增加方法

int updateUser(User user);
复制代码


UserDao.xml 增加 sql 语句

<update id="updateUser">
  update user set username = #{username} where id = #{id}
</update>
复制代码


新增测试方法

@Test
public void testUpdate() throws IOException {
  //1.mybatis 主配置文件
  String config = "mybatis-config.xml";
  //2.读取配置文件
  InputStream in = Resources.getResourceAsStream(config);
  //3.创建 SqlSessionFactory 对象
  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
  //4.获取 SqlSession
  SqlSession session = factory.openSession();
  //5.创建保存数据的对象
  User user = new User();
  user.setId(1005);//要修改的 id
  user.setUsername("李四"); //要修改的年龄值
  //6.执行更新 update
  int rows = session.update("com.dao.UserDao.updateUser",user);
  //7.提交事务
  session.commit();
  System.out.println("修改记录的行数:"+rows);
  //8.关闭 SqlSession
  session.close();
}
复制代码


3.2.3、delete


UsertDao 接口中增加方法

int deleteUser(int id);
复制代码


UserDao.xml 增加 sql 语句

<delete id="deleteUser">
  delete from user where id=#{id}
</delete>
复制代码


增加测试方法

@Test
public void testUpdate() throws IOException {
  //1.mybatis 主配置文件
  String config = "mybatis-config.xml";
  //2.读取配置文件
  InputStream in = Resources.getResourceAsStream(config);
  //3.创建 SqlSessionFactory 对象
  SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
  //4.获取 SqlSession
  SqlSession session = factory.openSession();
  //5.删除的 id
  int id = 1001;
  //6.执行删除 delete
  int rows = session.delete("com.dao.UserDao.deleteStudent",id);
  //7.提交事务
  session.commit();
  System.out.println("修改记录的行数:"+rows);
  //8.关闭 SqlSession
  session.close();
}
复制代码


3.2.2、完成两个绑定


  1. Mapper 接口与 Mapper 映射文件的绑定在 Mppper 映射文件中的标签中的 namespace 中必须指定 Mapper 接口的全类名,包名加类名。
  2. Mapper 映射文件中的增删改查标签的 id 必须指定成 Mapper 接口中的方法,必须相同否则无法通过代理实现绑定。


3.3、Mybatis对象分析


3.3.1、Resources类


Resources 类,顾名思义就是资源,用于读取资源文件。其有很多方法通过加载并解析资源文件,返回不同类型的 IO 流对象。


3.3.2、SqlSessionFactoryBuilder 类


SqlSessionFactory 的 创 建 , 需 要 使 用 SqlSessionFactoryBuilder 对 象 的 build() 方 法 。 由 于 SqlSessionFactoryBuilder 对象在创建完工厂对象后,就完成了其历史使命,即可被销毁。所以,一般会将 该 SqlSessionFactoryBuilder 对象创建为一个方法内的局部对象,方法结束,对象销毁。


3.3.3、SqlSessionFactory类


SqlSessionFactory 接口对象是一个重量级对象(系统开销大的对象),是线程安全的,所以一个应用


只需要一个该对象即可。创建 SqlSession 需要使用 SqlSessionFactory 接口的的 openSession()方法。他有几个重载方法:


  1. openSession(true):创建一个有自动提交功能的 SqlSession
  2. openSession(false):创建一个非自动提交功能的 SqlSession,需手动提交
  3. openSession():同 openSession(false)


3.3.4、SqlSession 接口


SqlSession 接口对象用于执行持久化操作。一个 SqlSession 对应着一次数据库会话,一次会话以SqlSession 对象的创建开始,以 SqlSession 对象的关闭结束。


SqlSession 接口对象是线程不安全的,所以每次数据库会话结束前,需要马上调用其 close()方法,将其关闭。再次需要会话,再次创建。 SqlSession 在方法内部创建,使用完毕后关闭。


3.4、抽取工具类


public class MyBatisUtil {
  //定义 SqlSessionFactory
  private static SqlSessionFactory factory = null;
  static {
  //使用 静态块 创建一次 SqlSessionFactory
  try{
    String config = "mybatis-config.xml";
    //读取配置文件
    InputStream in = Resources.getResourceAsStream(config);
    //创建 SqlSessionFactory 对象
    factory = new SqlSessionFactoryBuilder().build(in);
  }catch (Exception e){
    factory = null;
  e.printStackTrace();
  }
}
  /* 获取 SqlSession 对象 */
  public static SqlSession getSqlSession(){
    SqlSession session = null;
    if( factory != null){
      session = factory.openSession();
    }
    return session;
  }
}
复制代码


四、MyBatis 全局配置文件


4.1、MyBatis 全局配置文件简介


The MyBatis configuration contains settings and properties that have a dramatic effecton how MyBatis behaves.

MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings )和属性(properties)信息。


4.2、文件结构


configuration 配置
  properties 属性
  settings 设置
  typeAliases 类型命名
  typeHandlers 类型处理器
  objectFactory 对象工厂
  plugins 插件
  environments 环境
    environment 环境变量
      transactionManager 事务管理器
      dataSource 数据源
  databaseIdProvider 数据库厂商标识
mappers 映射器
复制代码


4.2.1、properties 属性


properties属性是配置数据源相关属性,可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来配置


<properties>
  <!--驱动名(MySQL5 和MySQL8 不同)-->
  <property name="driver" value="com.mysql.jdbc.Driver" />
  <!--url名字(MySQL5 和MySQL8 不同)-->
  <property name="url"
    <value="jdbc:mysql://localhost:3306/javaweb" />
  <property name="username" value="root" />
  <property name="password" value="123456" />
</properties>
复制代码


然而 properties 的作用并不单单是这样,你可以创建一个资源文件,名为db.properties 的文件,将四个连接字符串的数据在资源文件中通过键值对(key=value)的方式放置,不要任何符号,一条占一行


jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/javaweb
jdbc.username=root
jdbc.password=123456
复制代码

引入方式是这样


<!--
properties: 引入外部的属性文件
resource: 从类路径下引入属性文件
url: 引入网络路径或者是磁盘路径下的属性文件
-->
<properties resource="db.properties" ></properties>
复制代码


在 environment 元素的 dataSource 元素中为其动态设置


<environments default="mysql">
  <environment id="mysql">
  <transactionManager type="JDBC" />
  <dataSource type="POOLED">
    <property name="driver" value="${jdbc.driver}" />
    <property name="url" value="${jdbc.url}" />
    <property name="username" value="${jdbc.username}" />
    <property name="password" value="${jdbc.password}" />
  </dataSource>
</environment>
复制代码


4.2.2、settings 属性


这是 MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为。一般设置数据库的懒加载和缓存之类是否开启


<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>
复制代码


4.2.3、typeAliases 别名


类型别名是为 Java 类型设置一个短的名字,可以方便我们引用某个类,引用的时候不需要再写全路径名字


<typeAliases>
  <typeAlias type="com.domain.User" alias="user"/>
</typeAliases>
复制代码


更简单的写法:类很多的情况下,可以批量设置别名这个包下的每一个类创建一个默认的别名,就是简 单类名小写


<typeAliases>
  <package name="com.domain.User"/>
</typeAliases>
复制代码


MyBatis 默认已经取好的别名,不需要我们人为去配置


6.JPG


4.2.4、typeHandlers 类型处理器


无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型,MyBatis 中默认提供的类型处理器


7.JPG


注意


  1. 日期和时间的处理,JDK1.8 以前一直是个头疼的问题。我们通常使用 JSR310 规范领导者 Stephen Colebourne 创建的 Joda-Time 来操作。1.8 已经实现全部的 JSR310 规范了
  2. 日期时间处理上,我们可以使用 MyBatis 基于 JSR310(Date and Time API)编写的各种日期时间类型处理器。
  3. MyBatis3.4 以前的版本需要我们手动注册这些处理器,以后的版本都是自动注册的,如需注册,需要下载 mybatistypehandlers-jsr310,并通过如下方式注册


8.JPG


4.2.5、plugins 插件机制


插件是 MyBatis 提供的一个非常强大的机制,我们可以通过插件来修改 MyBatis 的一些核心行为。插件通过动态代理机制,可以介入四大对象的任何一个方法的执行,四大对象如下:


  1. Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
  2. ParameterHandler (getParameterObject, setParameters)
  3. ResultSetHandler (handleResultSets, handleOutputParameters)
  4. StatementHandler (prepare, parameterize, batch, update, query)


4.2.6、 environments 环境配置


MyBatis 可以配置多种环境,比如开发、测试和生产环境需要有不同的配置, 每种环境使用一个 environment 标签进行配置并指定唯一标识符,可以通过environments 标签中的default 属性指定一个环境的标识符来快速的切换环境


  • environment:指定具体环境
  • id:指定当前环境的唯一标识
  • transactionManager、dataSource 都必须有


<environments default="mysql">
  <environment id="mysql">
    <transactionManager type="JDBC" />
    <dataSource type="POOLED">
      <property name="driver" value="${jdbc.driver}" />
      <property name="url" value="${jdbc.url}" />
      <property name="username" value="${jdbc.username}" />
      <property name="password" value="${jdbc.password}" />
    </dataSource>
  </environment>
  <environment id="oracle">
    <transactionManager type="JDBC"/>
    <dataSource type="POOLED">
      <property name="driver" value="${orcl.driver}" />
      <property name="url" value="${orcl.url}" />
      <property name="username" value="${orcl.username}" />
      <property name="password" value="${orcl.password}" />
    </dataSource>
  </environment>
   </environments>
复制代码


4.2.6.1、transactionManager


他有三种可选的类型:JDBC ,MANAGED ,自定义


  1. JDBC:使用了 JDBC 的提交和回滚设置,依赖于从数据源得到的连接来管理事务范围,JdbcTransactionFactory。
  2. MANAGED:不提交或回滚一个连接、让容器来管理事务的整个生命周期,比如JEE应用服务器上下文,ManagedTransactionFactory。
  3. 自定义:实现 TransactionFactory 接口,type=全类名/别名。


4.2.6.2、dataSource


他有四种可选的类型: UNPOOLED , POOLED . JNDI , 自定义


  1. UNPOOLED:不使用连接池, UnpooledDataSourceFactory。
  2. POOLED:使用连接池, PooledDataSourceFactory。
  3. JNDI: 在 EJB 或应用服务器这类容器中查找指定的数据源。
  4. 自定义:实现 DataSourceFactory 接口,定义数据源的获取方式。


4.2.6.3、总结


际开发中我们使用 Spring 管理数据源,并进行事务控制的配置来覆盖上述配置


4.2.7、databaseIdProvider 数据库厂商标识


MyBatis 可以根据不同的数据库厂商执行不同的语句


<databaseIdProvider type="DB_VENDOR">
  <property name="MySQL" value="mysql"/>
  <property name="Oracle" value="oracle"/>
</databaseIdProvider>
复制代码


Type: DB_VENDOR


使用 MyBatis 提供的 VendorDatabaseIdProvider 解析数据库厂商标识。也可以实现 DatabaseIdProvider 接口来自定义.会通过 DatabaseMetaData#getDatabaseProductName() 返回的字符串进行设置。由于通常情况下这个字符串都非常长而且相同产品的不同版本会返回不同的值,所以最好通过设置属性别名来使其变短.


Property-name:数据库厂商标识


Property-value:为标识起一个别名,方便 SQL 语句使用 databaseId 属性引用

配置了 databaseIdProvider 后,在 SQL 映射文件中的增删改查标签中使用 databaseId来指定数据库标识的别名


<select id="getEmployeeById" resultType="com.atguigu.mybatis.beans.Employee" databaseId="mysql">
  select * from tbl_employee where id = #{id}
</select>
复制代码


MyBatis 匹配规则如下:


  1. 如果没有配置 databaseIdProvider 标签,那么 databaseId=null
  2. 如果配置了 databaseIdProvider 标签,使用标签配置的 name 去匹配数据库信息,匹配上设置 databaseId=配置指定的值,否则依旧为 null
  3. 如果 databaseId 不为 null,他只会找到配置 databaseId 的 sql 语句
  4. MyBatis 会加载不带 databaseId 属性和带有匹配当前数据库 databaseId 属性的 所有语句。如果同时找到带有 databaseId 和不带 databaseId 的相同语句,则后者 会被舍弃。


4.2.8、mappers 映射器


用来在 mybatis 初始化的时候,告诉 mybatis 需要引入哪些 Mapper 映射文件

4.2.8.1、mapper 逐个注册 SQL 映射文件


  • resource : 引入类路径下的文件
  • url : 引入网络路径或者是磁盘路径下的文件
  • class : 引入 Mapper 接口.
  1. 有 SQL 映射文件 , 要求 Mapper 接口与 SQL 映射文件同名同位置
  2. 没有 SQL 映射文件 , 使用注解在接口的方法上写 SQL 语句.


<mappers>
  <mapper resource="EmployeeMapper.xml" />
  <mapper class="com.dao.EmployeeMapper"/>
  <package name="com.dao.mybatis.dao"/>
</mappers>
复制代码


4.2.8.2、使用批量注册


这种方式要求 SQL 映射文件名必须和接口名相同并且在同一目录下


<mappers>
  <package name="com.dao"/>
</mappers>
复制代码


五、MyBatis 映射文件


MyBatis 的真正强大在于它的映射语句,也是它的魔力所在。由于它的异常强大,映射器的 XML 文件就显得相对简单。如果拿它跟具有相同功能的 JDBC 代码进行对比,你会立即发现省掉了将近 95% 的代码。MyBatis 就是针对 SQL 构建的,并且比普通的方法做的更好。


SQL 映射文件有很少的几个顶级元素(按照它们应该被定义的顺序):


cache – 给定命名空间的缓存配置。
cache-ref – 其他命名空间缓存配置的引用。
resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
parameterMap – 已废弃!
sql – 可被其他语句引用的可重用语句块。
insert – 映射插入语句
update – 映射更新语句
delete – 映射删除语句
select – 映射查询语
相关实践学习
如何在云端创建MySQL数据库
开始实验后,系统会自动创建一台自建MySQL的 源数据库 ECS 实例和一台 目标数据库 RDS。
全面了解阿里云能为你做什么
阿里云在全球各地部署高效节能的绿色数据中心,利用清洁计算为万物互联的新世界提供源源不断的能源动力,目前开服的区域包括中国(华北、华东、华南、香港)、新加坡、美国(美东、美西)、欧洲、中东、澳大利亚、日本。目前阿里云的产品涵盖弹性计算、数据库、存储与CDN、分析与搜索、云通信、网络、管理与监控、应用服务、互联网中间件、移动服务、视频服务等。通过本课程,来了解阿里云能够为你的业务带来哪些帮助 &nbsp; &nbsp; 相关的阿里云产品:云服务器ECS 云服务器 ECS(Elastic Compute Service)是一种弹性可伸缩的计算服务,助您降低 IT 成本,提升运维效率,使您更专注于核心业务创新。产品详情: https://www.aliyun.com/product/ecs
相关文章
|
5月前
|
SQL Java 数据库连接
MyBatis第三课
MyBatis第三课
|
6月前
|
SQL Java 数据库连接
还在为学MyBatis发愁?史上最全,一篇文章带你学习MyBatis
还在为学MyBatis发愁?史上最全,一篇文章带你学习MyBatis
128 1
|
6月前
|
设计模式 缓存 Java
干翻Mybatis源码系列之第七篇:Mybatis提供的集成缓存方案
干翻Mybatis源码系列之第七篇:Mybatis提供的集成缓存方案
|
XML SQL Java
学习笔记如此详细的mybatis,你不来看看吗?
学习笔记如此详细的mybatis,你不来看看吗?
164 0
学习笔记如此详细的mybatis,你不来看看吗?
|
XML SQL Java
MyBatis配置与使用-初入篇
MyBatis配置与使用
217 0
|
SQL XML 存储
图文讲解带你拿捏MyBatis(一)——MyBatis入门
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。在本文中,我们会学习一些mybatis的相关概念,以及搭建其开发环境以便快速入门。
185 0
|
SQL Java 数据库连接
Mybatis第三篇| Mybatis配置,有点小个性!
Mybatis第三篇| Mybatis配置,有点小个性!
646 1
Mybatis第三篇| Mybatis配置,有点小个性!
|
SQL 存储 XML
MyBatis从前世到今生一网打尽(下)
框架(Framework)是整个或部分系统的可重用设计,表现为一组抽象构件及构件实例间交互的方法;另一种认为,框架是可被应用开发者定制的应用骨架、模板。​ 简单的说,框架其实是半成品软件,就是一组组件,供你使用完成你自己的系统。从另一个角度来说框架一个舞台,你在舞台上做表演。在框架基础上加入你要完成的功能。
211 0
MyBatis从前世到今生一网打尽(下)
|
Java 数据库连接 数据库
【SSM直击大厂】第十五章:Mybatis 注解开发
📋📋 精彩摘要:注解开发是在企业中较为常见的一种开发技术,Mybatis注解开发方式可以减少编写Mapper 映射文件,使程序结构更加简洁,便于维护和更新。本章将通过基础CRUD操作介绍Mybatis注解开发。
112 0