微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

Mybatis-3

一.MyBatis的工作原理

20200701_150322_516.png

(1)读取MyBatis配置文件mybatis-config.xml。mybatis-config.xml作为MyBatis的全局配置文件,配置了MyBatis的运行环境等信息,其中主要内容获取数据库连接。

(2)加载映射文件Mapper.xml。Mapper.xml文件sql映射文件,该文件中配置了操作数据库sql语句,需要在mybatis-config.xml中加载才能执行。mybatis-config.xml可以加载多个配置文件,每个配置文件对应数据库中的一张表。

(3)构建会话工厂。通过MyBatis的环境等配置信息构建会话工厂sqlSessionFactory。

(4)创建 sqlSession 对象。由会话工厂创建 sqlSession 对象,该对象中包含了执行 sql的所有方法

(5)MyBatis底层定义了一个Executor接口来操作数据库,它会根据sqlSession传递的参数动态地生成需要执行的sql语句,同时负责查询缓存的维护。

(6)在 Executor 接口的执行方法中,包含一个 MappedStatement 类型的参数,该参数是对映射信息的封装,用于存储要映射的sql语句的id、参数等。Mapper.xml文件一个sql对应一个MappedStatement对象,sql的id即是MappedStatement的id。

(7)输入参数映射。在执行方法时,MappedStatement 对象会对用户执行 sql 语句的输入参数进行定义(可以定义为Map、List类型、基本类型和POJO类型),Executor执行器会通过MappedStatement对象在执行sql前,将输入的Java对象映射到sql语句中。这里对输入参数的映射过程就类似于JDBC编程中对preparedStatement对象设置参数的过程。

(8)输出结果映射。在数据库中执行完sql语句后,MappedStatement对象会对sql执行输出的结果进行定义(可以定义为Map和List类型、基本类型、POJO类型),Executor执行器会通过MappedStatement对象在执行sql语句后,将输出结果映射至Java对象中。这种将输出结果映射到Java对象的过程就类似于JDBC编程中对结果的解析处理过程。

 

思考:同学问老师,之前JDBC操作为什么做很多的setxx,和getxx的工作

你所使用的开发语言是面向对象的,你所使用的数据库是面向关系的,这两种截然不同的模式不能互相匹配,所以要做如上工作

ORM--->MyBatis也是属于一个ORM的框架

二.MyBatis的核心对象

5.1 创建工具类MyBatisUtil

sqlSessionFactory对象一旦创建,就会在整个应用运行过程中始终存在,没有理由去销毁它或者再创建它,并且在应用运行中也不建议多次创建sqlSessionFactory。因此sqlSessionFactory的最佳作用域是Application,即随着应用的生命周期一同存在。那么这种“存在于整个应用运行期间,并且同时存在一个对象实例”的模式就是所谓的单例模式,下面优化sqlSessionFactory的代码,最简单的实现方式就放在静态代码块下,以保证sqlSessionFactory对象只被创建一次,实现步骤如下所示。

public class MyBatisUtil {

private static sqlSessionFactory factory;

static{

try {

InputStream is=Resources.getResourceAsstream("mybatis-config.xml");

factory=new sqlSessionFactoryBuilder().build(is);

} catch (IOException e) {

e.printstacktrace();

}

}

public static sqlSession createsqlSession(){

return factory.openSession(false);

}

public static void closesqlSession(sqlSession sqlSession){

if(sqlSession!=null){

sqlSession.close();

}

}

}

5.2 sqlSession的两种使用方式

  • 通过sqlSession实例来直接执行已映射的sql语句

  • 基于mapper接口方式操作数据

1) 定义绑定映射语句的接口

public interface UserMapper {

    public List<User> getUserList();

}

2)修改测试类

@Test

public void test() throws IOException {

       sqlSession sqlSession=MyBatisUtil.createsqlSession();

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

      List<User> users=userMapper.getUserList();

      for (User user : users) {

     System.out.println(user);

      }

     MyBatisUtil.closesqlSession(sqlSession);

}

注意:第一种方式是旧版本的MyBatis提供的操作方式,现在也可以正常工作;第二种方式是MyBatis官方推荐使用的,其表达方式也更加直白,代码更加清晰,类型更加安全,也不用担心易错的字符串字面值以及强制类型转换。

20200701_160600_065.png

 

三.MyBatis的核心配置文件

配置文件结构

Mybatis-config.xml配置文件的元素节点是有先后顺序的,文件结构如下所示

20200701_163904_204.png

下面重点介绍一下几个常用的元素节点

1.properties元素描述的都是外部化、可代替的属性。这些属性可以通过以下两种方式实现

1)可通过外部指定方式,即配置在典型的java属性配置文件中,并使用这些属性对配置项实现动态配置,关键代码如下所示

 database.properties

driver=com.MysqL.jdbc.Driver

url=jdbc:MysqL://localhost:3306/mybatis?useUnicode=true&characterEncoding=utf8

username=root

password=java

mybatis-config.xml

<properties resource="database.properties"></properties>

<environments default="development">

<environment id="development">

         <transactionManager type="JDBC"></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>

2)直接配置为XML,使用这些属性对配置项实现动态配置,关键代码如下

 mybatis-config.xml

<properties>

<property name="driver" value="com.MysqL.jdbc.Driver"/>

<property name="url" value="jdbc:MysqL://localhost:3306/mybatis"/>

<property name="username" value="root"/>

<property name="password" value="java"/>

</properties>

<environments default="development">

<environment id="development">

         <transactionManager type="JDBC"></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>

  注意:若两种方式同时使用时,resource属性值的优先级高于property子节点配置的值

 

2.settings元素

settings元素的作用是设置一些非常重要的选项,用于设置和改变MyBatis运行中的行为

日志是非常重要,在企业开发过程中,程序员是离不开日志的,维护人员也离不开日志

日志的分类

1.业务日志

2.错误日志

1)mybatis集成日志

这里以log4j为例来进行配置

第1步:在项目的resources目录下创建log4j.properties文件

# Global logging configuration

log4j.rootLogger=DEBUG, stdout,fileAppender

# Console output...

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

 

 

log4j.appender.fileAppender = org.apache.log4j.FileAppender

log4j.appender.fileAppender.File = g:/log.log

log4j.appender.fileAppender.Append = true

log4j.appender.fileAppender.Threshold = DEBUG

log4j.appender.fileAppender.layout = org.apache.log4j.PatternLayout

log4j.appender.fileAppender.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

第2步:在pom.xml文件添加log4j的起步依赖

<dependency>

   <groupId>log4j</groupId>

   <artifactId>log4j</artifactId>

   <version>1.2.16</version>

</dependency>

第3步:在mybatis-config.xml文件中进行设置

<settings>

   <setting name="logImpl" value="LOG4J"/>

</settings>

第4步:使用

public class AppTest

{

   private Logger logger= Logger.getLogger(AppTest.class);

   @Test

   public void test2(){

       sqlSession sqlSession= MyBatisUtil.createsqlSession();

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

       List<User> all=userMapper.getUserList();

       for (User user:all) {

           logger.info(user.getId()+" "+user.getName()+" "+user.getAge());

       }

   }

}

安装console grep插件,并且设置,设置如下

20200701_174539_934.png

20200701_174851_742.png

3.typeAliases元素

typeAliases元素的作用是配置类型别名

<typeAliases>

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

</typeAliases>

如果一个项目中有多个POJO,需要一一进行配置,比较麻烦,可以通过package的name属性直接指定包名,MyBatis会自动扫描指定包下的JavaBean,名称为JavaBean的非限定类名

<typeAliases>

<package name="com.pojo" />

</typeAliases>

引用的时候,如下所示

<mapper namespace="com.dao.UserMapper">

<!-- 查询用户记录数 -->

<select id="getUserList" resultType="User">

         select * from users

</select>

</mapper>

4.连接池

1)连接池介绍

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个

2)mybatis的连接池的分类

在mybatis中,我们将它的数据源dataSource分为以下三种

20200701_163318_942.png

type的取值

pooled:使用连接池的数据源

unpooled:不使用连接池的数据源

JNDI:使用JNDI实现的数据源

使用unpooled与pooled日志对比

相应的,mybatis内部定义了实现javax.sql.DataSource接口的UnpooledDataSource、PooledDataSource类来定义UNPOOLED、POOLED类型的数据源

3)mybatis中使用unpooled配置连接池的原理分析

通过CRLT+N调出如下对话框来进行搜索

20200701_163424_262.png

4)mybatis中使用pooled配置连接的原理分析

使用pooled方式要保证线程安全

20200701_163441_958.png

如果空闲池有连接就直接拿出来使用

如果空闲池没有可用的连接,会查看活动池中的连接,是否已经达到最大数量

20200701_163451_631.png

如果 活动池中的连接 没有 达到最大数量, 会创建一个新的连接

如果活动池中的连接已经达到最大数量, 会判断活动池中哪个是最先进来的(Oldest), 然后对该链接进行处理并返回

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。