当前位置:   article > 正文

MyBatis学习笔记(系统学习)_系统学习mybatis

系统学习mybatis

一、简介

1.MyBatis是什么

Mybatis的前身是Batis,他是一个持久层框架,或称为:ORM框架。

  • 总结:MyBatis就是用来访问数据库的!
  • 本质上对前面所学JDBC进行封装!

注意:所谓的框架就是别人已经写好的,对一些技术进行封装,比如:java框架一般会封装成为JAR;像其他的如JS,CSS等。而用了ORM框架,就不需要像之前操作JDBC数据库那样,一步一步进行编写,通过MyBatis可以快速的操作数据库!

2.持久层

DAO:Data Access Object 数据访问对象

用来对数据进行持久化操作,如将数据存入数据库、硬盘等,可以持久保存

3.ORM

Object Relation Mapping 对象关系映射,指的是java程序和数据库之间的映射关系

  • 类---->表
  • 对象—>一条数据或一条记录
  • 属性---->列

4.回顾JDBC

JDBC操作数据库的步骤:

  • Class.forName(DriverName)
  • DriverManager.getConnection(URL)
  • conn.prepareStatement()
  • ResultSet rs = ps.executeQuer()
  • while(rs.next()){} 通过这一步进行循环!
  • rs.close
  • statement.close
  • conneciton.close

在这数据库操作的一系列流程中,有些代码是不变的,有些代码是可变的

  • 数据库操作的可变部分:连接信息

DriverClassName,URL,user,password(也称这)

  • SQL语句
  • RM映射

二、正式使用MyBatis的准备工作

1. 需要在项目中添加JAR包

  • mymybatis-3.2.8.jar;版本话,3.0后面的版本都可以用!
  • mysql-connector-java;数据库驱动
  • log4j;日志包(可选)加入了这个包,可以看到日志的信息

这里的三个Jar包可以通过IDEA直接加载,也可以通过Maven或Gradle来进行加载

2. 相关的配置文件的准备工作

mybatis配置文件使用的是.xml文件,可以分为两大类:

  • config文件

主配置文件 ,在一个mybatis工程中有且只有一个,他是用来配置与整个工程配置相关的信息,如环境配置、插件配置、注册mapper文件等!

  • mapper文件

映射配置文件,在一个mybatis工程中可以有多个mapper文件,每一个mapper文件相当于原来的Dao的实现类。用来配置Dao功能的相关的SQL操作,如SQL语然啦,CRUD ,字段映射等!

注意:创建MyBatis的主配置文件时,如果一段代码需要重复利用的话,可以用模板来创建!

三、第一个MyBatis程序

1. 数据库的设计

在这里对一个数据库进行设计;

2. 创建主配置文件

核心配置文件,该文件一般位于src目录下,一般命名为:mybatis-config.xml(这是习惯问题,其他文件名也可以

  • mybatis中的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>
  
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 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>
       <!-- TODO:配置当前项目中可能用到的所有环境!
            default:默认使用的环境是哪个?值指向里面的某一个-->
           <environments default="hello">
               <!-- TODO:配置某一个具体数据库的环境,环境可以有多个!
                id:该环境的标识符!-->
               <environment id="hello">
                   <!-- TODO:事务管理器,他的作用是配置事务管理器
                    type:事务管理器的类型,取值有两种:jdbc( 简单的jdbc事务操作),JDBC默认是关闭提交事务的!conn.setAutoCommit(false)
                    managed:将事务交给其他的框架或容器操作,如Spring-->
                   <transactionManager type="jdbc"></transactionManager>
                   <!-- TODO:配置数据库的连接信息
                    type:配置数据源。他有三个类型
                       UNPOOLED:使用的简单的JDBC配置,没有使用连接池技术。只有简单的连接配置
                       POOLED:使用了连接池技术
                       JNDI:通过外部容器来获取连接-->
                   <dataSource type="POOLED">
                       <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
                       <property name="url" value="jdbc:mysql://localhost:3306/newdb?useSSL=false&amp;serverTimezone=UTC"/>
                       <property name="username" value="root"/>
                       <property name="password" value="123456"/>
                   </dataSource>
               </environment>
           </environments>
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • SqlSession(持久化管理器),他是Mybatis的核心,他的创建方法是由工厂来创建的,即:SqlSessionFactoryBuilder,具体代码示例如下:
@Bean
public Connection connection(){
    // TODO: 2021/7/26 创建一个工厂
    SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream resourceAsStream = SqlSessionFactoryBuilder.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory build = builder.build(resourceAsStream);
    // TODO: 2021/7/26 创建了持久化管理器 ,所谓工厂模式,是将配置信息放入工厂,最终将创建一个持久化管理器
    SqlSession sqlSession = build.openSession();
    Connection connection = sqlSession.getConnection();
    return connection;
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

3.创建映射文件

在数据库中有一个表,那么根据ORM,那么在JAVA中就会有一个对应的类,因此,在创建映射文件的时候,首先得在Java中创建一个类;

  • 创建对应数据库表的对类

用来配置DAO的SQL语句,每个数据库表和对应的类之间都有一个映射文件(xml文件)

  • 创建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 namespace="abc">
    <!-- TODO:
     insert:表示执行添加方法!
     id:表示执行添加操作的方法名,该方法名类似类中的方法名,是一个命名标识
        如果是纯配置文件,没接口,方法名可以随便写,但必须唯一;
        如果配置文件+接口的形式,id方法名的值必须与接口中一致!
		这里所说的接口:是指
     parameterType:表示方法的参数类型
                   如果是参数对象,可以使用类的全名
                   如果参数是变通的数据,可以使用mybatis中的别名
       标签体:使用缩写的SQL语句!
              使用#{XXX}表示点位符
              如果参数是对象,那位占位符XXX用自定义对象中的属性名
              如果参数是普通数据类型,那么占位符XXX名也就是参数名,用的是参数名这个标识指向的数据-->
    <insert id="insertUser" parameterType="com.dream.seeker.entity.impl.GradleUser">
        insert into customer(name,salary) values (#{name},#{salary})
    </insert>
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

我们自定义一个映射文件,映射文件名可以自定义,那么如何告诉应用程序我们定义的映射文件呢?

  • 注册映射文件

Mybatis中的主配置文件m中有一个和environments平行的标签mapper。示例如下:

<mappers>
    <!-- TODO:在主配置文件中,注册一个映射文件,可以有多个
              resource:映射文件的路径,写的是src中的路径-->
    <mapper resource="mapper/mybatis-mapper.xml"/>
</mappers>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 测试映射文件

映射文件是和主配置文件一体的文件,自定义好的映射文件(Mapper)需要在主配置文件中进行注册,映射文件有SQL语句,每个SQL语句都有类似于方法名一样的标识,我们在MyBatis中也可以称之为方法名;他还存在方法参数,该参数是Java中的一个数据对象或者普通的数据,这些对象中的属性值和普通数据就是要传入到数据库中的内容。

@Test
public void insertDate() {
    gradleUser.setName("hellojava");
    gradleUser.setSalary(3000);
    // TODO: 2021/7/27:方式一:纯配置文件,没有接口,直接读取Mapper文件中的SQL语句!
    sqlSession.insert("abc.insertUser",gradleUser);
    // TODO: 2021/7/27 由于在主配置文件中,自动事务提交管理是关闭的,因此,需要手动对事务进行提交 
    sqlSession.commit();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

4.MyBatis中数据库日志:log4j

在MyBatis中,如果需要对数据库的操作进行日志输出,则需要加载数据库日志输出依赖,并配置属性文件,具体代码如下:

  • 添加log4j依赖文件
<dependency>
    <groupId>log4j</groupId>
    <artifactId>log4j</artifactId>
    <version>1.2.17</version>
</dependency>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 配置log4j属性文件

log4j属性文件必须在类路径src下,且文件名必须命名为:log4j.properties,属性文件的具体内容可以设置如下

log4j.rootLogger=INFO,console,dailyFile
# TODO 发布到阿里云记得添加,另外控制台不输出(只输出warn或者error信息)

# log4j.logger.org.mybatis = INFO
log4j.logger.com.imooc.mapper=INFO

log4j.appender.console=org.apache.log4j.ConsoleAppender
log4j.appender.console.encoding=UTF-8
log4j.appender.console.layout=org.apache.log4j.PatternLayout
log4j.appender.console.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%l] - [%p] %m%n

# 定期滚动日志文件,每天都会生成日志
log4j.appender.dailyFile=org.apache.log4j.DailyRollingFileAppender
log4j.appender.dailyFile.encoding=UTF-8
log4j.appender.dailyFile.Threshold=INFO
# TODO 本地日志地址,正式环境请务必切换为阿里云地址
log4j.appender.dailyFile.File=C:/logs/maven-ssm-alipay/log.log4j
log4j.appender.dailyFile.DatePattern='.'yyyy-MM-dd
log4j.appender.dailyFile.layout=org.apache.log4j.PatternLayout
log4j.appender.dailyFile.layout.ConversionPattern=%-d{yyyy-MM-dd HH:mm:ss,SSS} [%t] [%l] - [%p] %m%n
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 详细log4j配置文件案例:
log4j.rootLogger=INFO,consoleAppender,logfile,MAIL
log4j.addivity.org.apache=true
#ConsoleAppender,控制台输出
#FileAppender,文件日志输出
#SMTPAppender,发邮件输出日志
#SocketAppender,Socket 日志
#NTEventLogAppender,Window NT 日志
#SyslogAppender,
#JMSAppender,
#AsyncAppender,
#NullAppender
#文件输出:RollingFileAppender
#log4j.rootLogger = INFO,logfile
log4j.appender.logfile = org.apache.log4j.RollingFileAppender
log4j.appender.logfile.Threshold = INFO
# 输出以上的 INFO 信息
log4j.appender.logfile.File = INFO_log.html
#保存 log 文件路径
Log4j 从入门到详解
10
log4j.appender.logfile.Append = true
# 默认为 true,添加到末尾,false 在每次启动时进行覆盖
log4j.appender.logfile.MaxFileSize = 1MB
# 一个 log 文件的大小,超过这个大小就又会生成 1 个日志 # KB ,MB,GB
log4j.appender.logfile.MaxBackupIndex = 3
# 最多保存 3 个文件备份
log4j.appender.logfile.layout = org.apache.log4j.HTMLLayout
# 输出文件的格式
log4j.appender.logfile.layout.LocationInfo = true
#是否显示类名和行数
log4j.appender.logfile.layout.Title
=title:\u63d0\u9192\u60a8\uff1a\u7cfb\u7edf\u53d1\u751f\u4e86\u4e25\u91cd\u9519\u8b
ef
#html 页面的 < title >
############################## SampleLayout ####################################
# log4j.appender.logfile.layout = org.apache.log4j.SampleLayout
############################## PatternLayout ###################################
# log4j.appender.logfile.layout = org.apache.log4j.PatternLayout
# log4j.appender.logfile.layout.ConversionPattern =% d % p [ % c] - % m % n % d
############################## XMLLayout #######################################
# log4j.appender.logfile.layout = org.apache.log4j.XMLLayout
# log4j.appender.logfile.layout.LocationInfo = true #是否显示类名和行数
############################## TTCCLayout ######################################
# log4j.appender.logfile.layout = org.apache.log4j.TTCCLayout
# log4j.appender.logfile.layout.DateFormat = ISO8601
#NULL, RELATIVE, ABSOLUTE, DATE or ISO8601.
# log4j.appender.logfile.layout.TimeZoneID = GMT - 8 : 00
# log4j.appender.logfile.layout.CategoryPrefixing = false ##默认为 true 打印类别名
# log4j.appender.logfile.layout.ContextPrinting = false ##默认为 true 打印上下文信息
# log4j.appender.logfile.layout.ThreadPrinting = false ##默认为 true 打印线程名
# 打印信息如下:
#2007 - 09 - 13 14 : 45 : 39 , 765 [http - 8080 - 1 ] ERROR com.poxool.test.test -
error 成功关闭链接
###############################################################################
#每天文件的输出:DailyRollingFileAppender
#log4j.rootLogger = INFO,errorlogfile
log4j.appender.errorlogfile = org.apache.log4j.DailyRollingFileAppender
log4j.appender.errorlogfile.Threshold = ERROR
log4j.appender.errorlogfile.File = ../logs/ERROR_log
log4j.appender.errorlogfile.Append = true
#默认为 true,添加到末尾,false 在每次启动时进行覆盖
log4j.appender.errorlogfile.ImmediateFlush = true
#直接输出,不进行缓存
# ' . ' yyyy - MM: 每个月更新一个 log 日志
# ' . ' yyyy - ww: 每个星期更新一个 log 日志
# ' . ' yyyy - MM - dd: 每天更新一个 log 日志
# ' . ' yyyy - MM - dd - a: 每天的午夜和正午更新一个 log 日志
# ' . ' yyyy - MM - dd - HH: 每小时更新一个 log 日志
# ' . ' yyyy - MM - dd - HH - mm: 每分钟更新一个 log 日志
Log4j 从入门到详解
11
log4j.appender.errorlogfile.DatePattern = ' . ' yyyy - MM - dd ' .log '
#文件名称的格式
log4j.appender.errorlogfile.layout = org.apache.log4j.PatternLayout
log4j.appender.errorlogfile.layout.ConversionPattern =%d %p [ %c] - %m %n %d
#控制台输出:
#log4j.rootLogger = INFO,consoleAppender
log4j.appender.consoleAppender = org.apache.log4j.ConsoleAppender
log4j.appender.consoleAppender.Threshold = ERROR
log4j.appender.consoleAppender.layout = org.apache.log4j.PatternLayout
log4j.appender.consoleAppender.layout.ConversionPattern =%d %-5p %m %n
log4j.appender.consoleAppender.ImmediateFlush = true
# 直接输出,不进行缓存
log4j.appender.consoleAppender.Target = System.err
# 默认是 System.out 方式输出
#发送邮件:SMTPAppender
#log4j.rootLogger = INFO,MAIL
log4j.appender.MAIL = org.apache.log4j.net.SMTPAppender
log4j.appender.MAIL.Threshold = INFO
log4j.appender.MAIL.BufferSize = 10
log4j.appender.MAIL.From = yourmail@gmail.com
log4j.appender.MAIL.SMTPHost = smtp.gmail.com
log4j.appender.MAIL.Subject = Log4J Message
log4j.appender.MAIL.To = yourmail@gmail.com
log4j.appender.MAIL.layout = org.apache.log4j.PatternLayout
log4j.appender.MAIL.layout.ConversionPattern =%d - %c -%-4r [%t] %-5p %c %x - %m %n
#数据库:JDBCAppender
log4j.appender.DATABASE = org.apache.log4j.jdbc.JDBCAppender
log4j.appender.DATABASE.URL = jdbc:oracle:thin:@ 210.51 . 173.94 : 1521 :YDB
log4j.appender.DATABASE.driver = oracle.jdbc.driver.OracleDriver
log4j.appender.DATABASE.user = ydbuser
log4j.appender.DATABASE.password = ydbuser
log4j.appender.DATABASE.sql = INSERT INTO A1 (TITLE3) VALUES ( ' %d - %c %-5p %c %x - %m%n
' )
log4j.appender.DATABASE.layout = org.apache.log4j.PatternLayout
log4j.appender.DATABASE.layout.ConversionPattern =% d - % c -%- 4r [ % t] %- 5p % c %
x - % m % n
#数据库的链接会有问题,可以重写 org.apache.log4j.jdbc.JDBCAppender 的 getConnection() 使用数
据库链接池去得链接,可以避免 insert 一条就链接一次数据库

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110

5.如何在IDEA中快速的使用数据库中的字段等信息来确定SQL语句

通过IDEA可以连接MySQL数据库,连接数据库后,在编写mapper文件的时候可以有提示信息,可以防止错误的发生。在IDEA连接数据库时,一定要注意设置serverTimezone=UTC,才能正确的连接

  • 连接数据库后,一般情况下也不会有提示信息,此时,需要对IDEA进行设置

File->Setting->Languages&Frameworks->SQL Dialects 将全局和项目的SQL Dialects都设置为:MySQL

四、基于接口的MyBatis映射文件

基于接口的映射文件,他和纯配置文件的主要区别在于:

  • 纯配置文件是通过持久性管理器sqlSession来调用映射文件中的SQL语句对数据库进行操作;
  • 而 接口 + 配置文件 的方式是通过接口生成的实现类(代理类)来执行接口中现有的方法来执行SQL语句,接口中的方法名 和 映射配置文件中的方法名必须一致,因此,通过调用接口实现类(由字节码操作工具类动态生成的代理对象)中的方法来驱动映射配置文件中的方法,从而执行SQL语句,达到操作数据库的目的!

具体案例代码:

  • 自定义一个操作数据库的接口
package com.dream.seeker.dao;

import com.dream.seeker.entity.impl.GradleUser;

public interface InsertUser {
    public void insertUser(GradleUser user);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 配置MyBatis映射配置文件
<?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.dream.seeker.dao.InsertUser">
    <!-- TODO:
     insert:表示执行添加方法!
     id:表示执行添加操作的方法名,该方法名类似人类中的方法名,是一个命名标识
        如果是纯配置文件,没接口,方法名可以随便写,但必须唯一;
        如果配置文件+接口,id方法名的值必须与接口中一致!
     parameterType:表示方法的参数类型
                   如果是参数对象,可以使用类的全名
                   如果参数是变通的数据,可以使用mybatis中的别名
       标签体:使用缩写的SQL语句!
              使用#{XXX}表示点位符
              如果参数是对象,那位占位符XXX用自定义对象中的属性名
              如果参数是普通数据类型,那么占位符XXX名也就是参数名,用的是参数名这个标识指向的数据-->
    <insert id="insertUser" parameterType="com.dream.seeker.entity.impl.GradleUser">
        insert into
            gradle(name, salary) values (#{name},#{salary})
    </insert>
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 通过测试类来执行SQL语句
@Test
public void test97() {
    gradleUser.setName("hello");
    gradleUser.setSalary(200);
    // TODO: 2021/7/27 通过getMapper()方法,在方法中传入接口的结构信息,可以动态创建一个代理类对象 
    InsertUser mapper = sqlSession.getMapper(InsertUser.class);
    // TODO: 2021/7/27 通过动态生成的代理类对象调用其中方法来驱动映射配置文件中的SQL语句,或者可以说:SQL语句已经动态生成到接口实现类中的方法当中
    mapper.insertUser(gradleUser);
    // TODO: 2021/7/27 由于在MyBatis主配置文件中,事务管理属性JDBC,因此,需要手动提交事务
    sqlSession.commit();
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

知识点:通过接口 + 配置文件 的方式来操作数据库,他基本原理是:通过接口的结构信息 + 配置文件中与接口方法名相同的SQL语句,动态生成(由字节码操作工具)一个接口的实现类及实现类对象,通过这个实现类对象(代理类对象)调用对象中的方法来执行SQL语句,从而操作数据库。其主要优点是:接口动态生成的实例对象每一个方法都对应映射文件中的一个SQL语句!

五、MyBatis工具类

  • 下面的代码,如果每次都要写,那就比较麻烦。
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
    InputStream resourceAsStream = SqlSessionFactoryBuilder.class.getClassLoader().getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory build = builder.build(resourceAsStream);
    // TODO: 2021/7/26 创建了持久化管理器 ,所谓工厂模式,是将配置信息放入工厂,最终将创建一个持久化管理器
    SqlSession sqlSession = build.openSession();
  • 1
  • 2
  • 3
  • 4
  • 5

因此,在这种情况下,我们可以创建一个工具类,返回一个持久化管理器SqlSession ,同时,需要注意的是:在工具类中,SqlSession对象必须是单例唯一的。具体示例代码如下:

public class GradleMyBatisUtils {

    private static SqlSessionFactory factory;
    // TODO: 2021/7/28 可以把ThreadLocal<>看成是一个容器,这个容器有判断hash值的方法,确定在里面的实例是否是唯一(即单例)
    private static ThreadLocal<SqlSession> local = new ThreadLocal<>();

    static {
        try {
            factory = new SqlSessionFactoryBuilder().build(
                GradleMyBatisUtils.class.getClassLoader().getResourceAsStream("classpath:mybatis-config.xml")
            );
        } catch (Exception e) {
            throw new ExceptionInInitializerError("MyBatis初始化失败" + e.getMessage());
        }
    }

    // TODO: 2021/7/28 获取一个持久化管理器,管理器里包数据库连接池,事务和数据库连接的相关信息,具体内容和配置文件中有关
    public static SqlSession getSession(){
        // TODO: 2021/7/28 从容器中获得对象, 由于是单例的,所以,会依据类型进行匹配
        SqlSession sqlSession = local.get();
        if (sqlSession == null) {
            sqlSession = factory.openSession();
            local.set(sqlSession);
        }
        return sqlSession;
    }

    // TODO: 2021/7/28 关闭持久化管理对象,关闭此对象,会同时关闭数据库连接池中相关对象,如connection,statement等! 
    public static void close(){
        SqlSession sqlSession = local.get();
        if (sqlSession!=null) {
            sqlSession.close();
            local.remove();
        }
    }
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37

新增知识点:在工具类中,我们可以用ThreadLocal类实例来管理工具类中对象是否为单例,ThreadLocal实例具有存储和管理工具类中指定对象类型的功能,可以用来判断工具类中主对象是否为空,如果不为空的话,可以通过get()方法直接获得相应的对象。

  • 对MyBatis工具类进行测试
@Test
public void test110() {
    SqlSession sqlSession = null;
    try {
        // TODO: 2021/7/28 从工具类中获得持欠化管理器 
        sqlSession = MyBatisUtils.getSession();

        // TODO: 2021/7/28 下面几段代码是具体对数据库进行操作的代码  
        GradleUser gradleUser = new GradleUser();
        gradleUser.setName("hellojava");
        gradleUser.setSalary(5000);
        InsertUser mapper = sqlSession.getMapper(InsertUser.class);
        mapper.insertUser(gradleUser);

        // TODO: 2021/7/28 由于事务采取的方式是JDBC方式,他自动提交是关闭的,因此,需要手动关闭 
        sqlSession.commit();
    } catch (Exception e) {
        e.printStackTrace();
        // TODO: 2021/7/28 如果发生异常,事务没有执行完,地么需要回滚操作 
        sqlSession.rollback();
    } finally {
        MyBatisUtils.close();
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

六、MyBatis主配置文件的扩展:配置别名,引用属性文件

  • typeAliases给自定义数据信息类设置别名

在主配置文件中,添加标签选项:typeAliases,可以为java类对象设置别名(这个JAVA类对象是存储数据库信息的Bean,使用此类对象设置数据,再将此类对象中的数据传入到数据库),这个java类对象是执行SQL方法中的参数,这个参数他位于MyBatis映射文件中。设置别名主要是在MyBatis主配置文件中,使用标签typeAliases,具体示例如下:

 <!-- TODO:设置别名 -->
<typeAliases>
    <!-- TODO:为某一个类去配置别名 -->
    <!--        <typeAlias type="com.dream.seeker.entity.impl.GradleUser" alias="GradleUser"/>-->
    <!-- TODO:package:为包下面的所有类取别名
                  name:指定包名,该包下所有类的别名,就是其自身的类名,原则上不区分大小上,但建设采用首字母大写-->
    <package name="com.dream.seeker.entity.impl"/>
</typeAliases>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

设置好别名后,那么就可以在MyBatis映射文件中使用别名了,下面的代码是基于接口 + 配置文件的方式定义的mapper(映射)文件,其中namesapce是接口名,id指的是接口的抽象方法名,而parameterType这个地方通过在主配置文件中定义的别名,可以简化许多代码。

<?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.dream.seeker.dao.InsertUser">
    <!-- TODO:
     insert:表示执行添加方法!
     id:表示执行添加操作的方法名,该方法名类似人类中的方法名,是一个命名标识
        如果是纯配置文件,没接口,方法名可以随便写,但必须唯一;
        如果配置文件+接口,id方法名的值必须与接口中一致!
     parameterType:表示方法的参数类型
                   如果是参数对象,可以使用类的全名
                   如果参数是变通的数据,可以使用mybatis中的别名
       标签体:使用缩写的SQL语句!
              使用#{XXX}表示点位符
              如果参数是对象,那位占位符XXX用自定义对象中的属性名
              如果参数是普通数据类型,那么占位符XXX名也就是参数名,用的是参数名这个标识指向的数据-->
    <insert id="insertUser" parameterType="GradleUser">
        insert into
        gradle(name, salary) values (#{name},#{salary})
    </insert>
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 在属性文件中写数据库的连接信息:

在属性文件中写连接信息,首先得定义一个属性文件xxxx.properties,将相关的连接信息写入到里面,案例如下:

jdbc.driverClassName=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/newdb?serverTimezone=UTC&useSSL=false
jdbc.username=root
jdbc.password=123456
  • 1
  • 2
  • 3
  • 4

在定义完属性文件后,需要在MyBatis的主配置文件中将自定义的属性文件添加到主配置文件中,在主配置文件中,用到了标签:properties,具体代码案例如下:

<properties resource="dbcp.properties"/>
  • 1

在MyBatis主配置文件中定义好了属性文件后,则可以改写主配置文件中的连接信息,改写的内容采用 表 达 式 , 连 接 信 息 也 是 通 过 属 性 后 置 处 理 器 的 结 {}表达式,连接信息也是通过属性后置处理器的结 {}表达式进行转换,具体代码案例如下:

<dataSource type="POOLED">
    <property name="driver" value="${jdbc.driverClassName}"/>
    <property name="url" value="${jdbc.url}"/>
    <property name="username" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
</dataSource>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

七、MyBatis对数据库表的基本操作

1.在插入操作中返回主键值

基于接口 + 配置文件 的方式对数据库进行插入操作SQL时,一般情况下是不返回主键的,如果需要返回主键,那么需要在mapper文件中添加属性:userGeneratedKey。此属性的作用是保留进行插入SQL操作时的主键,此主键的值保存在哪个位置呢?答案是:保存到方法参数对象的属性中,然而,自定义的参数对象有许多属性,他又会保存到哪个属性当中呢,这时,在mapper文件中,又需要用到一个属性名为

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小小林熬夜学编程/article/detail/710298
推荐阅读
相关标签