Mybatis

89 阅读5分钟

MyBatis核心配置文件详解

传统的MyBatis配置文件 mybatis-config.xml 包含了数据库连接池、事务管理、类型别名、映射文件路径等配置。

这是一个mybatis核心配置文件的内容的解释:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<!--标签的约束,标签中该有什么属性,dtd-->
<!--在xml中的规范中,只能出现一个根-->
<configuration>

    <!--从绝对路径当中加载资源。绝对路径怎么写?file:///路径-->
    <!--<properties url="file:///d:/jdbc.properties" />-->
    <properties resource="mysql-config.properties"/>
<!--    可以配置多个environments,以下只是其中的一个环境-->
    <!--default表示默认使用的环境。-->
    <!--默认环境什么意思?当你使用mybatis创建SqlSessionFactory对象的时候,没有指定环境的话,默认使用哪个环境。-->
    <environments default="development">
        <!--一般一个数据库会对应一个SqlSessionFactory对象。-->
        <!--一个环境environment会对应一个SqlSessionFactory对象-->
        <!-- 一个环境就我理解的是告诉mysql你要操作哪个数据库,因为mysql不知道,所以你要告诉它 -->
        <environment id="development">
            <transactionManager type="JDBC"/>
            <!--
                transactionManager标签:
                    1.作用:配置事务管理器。指定mybatis具体使用什么方式去管理事务。
                    2.type属性有两个值:
                        第一个:JDBC: 使用原生的JDBC代码来管理事务。
                            conn.setAutoCommit(false);
                            ....
                            conn.commit();
                        第二个:MANAGED:mybatis不再负责事务的管理,将事务管理交给其它的JEE(JavaEE)容器来管理。例如:spring
                    3. 大小写无所谓。不缺分大小写。但是不能写其他值。只能是二选一:
                        jdbc、managed
                    4. 在mybatis中提供了一个事务管理器接口:Transaction
                        该接口下有两个实现类:
                            JdbcTransaction
                            ManagedTransaction
                        如果type="JDBC",那么底层会实例化JdbcTransaction对象。
                        如果type="MANAGED",那么底层会实例化ManagedTransaction
            -->
            <!--
                dataSource配置:
                    1.dataSource被称为数据源。
                    2.dataSource作用是什么?为程序提供Connection对象。(但凡是给程序提供Connection对象的,都叫做数据源。)
                    3.数据源实际上是一套规范。JDK中有这套规范:javax.sql.DataSource(这个数据源的规范,这套接口实际上是JDK规定的。)
                    4.我们自己也可以编写数据源组件,只要实现javax.sql.DataSource接口就行了。实现接口当中所有的方法。这样就有了自己的数据源。
                    比如你可以写一个属于自己的数据库连接池(数据库连接池是提供连接对象的,所以数据库连接池就是一个数据源)。
                    5.常见的数据源组件有哪些呢【常见的数据库连接池有哪些呢】?
                        阿里巴巴的德鲁伊连接池:druid
                        c3p0
                        dbcp
                        ....
                    6. type属性用来指定数据源的类型,就是指定具体使用什么方式来获取Connection对象:
                        type属性有三个值:必须是三选一。
                        type="[UNPOOLED|POOLED|JNDI]"
                        UNPOOLED:不使用数据库连接池技术。每一次请求过来之后,都是创建新的Connection对象。
                        POOLED:使用mybatis自己实现的数据库连接池。
                        JNDI:集成其它第三方的数据库连接池。

                        JNDI是一套规范。谁实现了这套规范呢?大部分的web容器都实现了JNDI规范:
                            例如:Tomcat、Jetty、WebLogic、WebSphere,这些服务器(容器)都实现了JNDI规范。
                        JNDI是:java命名目录接口。Tomcat服务器实现了这个规范。
            -->
            <dataSource type="POOLED">
                <property name="driver" value="${driver}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${username}"/>
                <property name="password" value="${password}"/>
                <!--提醒:正常使用连接池的话,池中有很多参数是需要设置的。设置好参数,可以让连接池发挥的更好。事半功倍的效果。-->
                <!--具体连接池当中的参数如何配置呢?需要反复的根据当前业务情况进行测试。-->
                <!--poolMaximumActiveConnections:连接池当中最多的正在使用的连接对象的数量上限。最多有多少个连接可以活动。默认值10-->
                <property name="poolMaximumActiveConnections" value="10"/>
                <!--每隔2秒打印日志,并且尝试获取连接对象-->
                <property name="poolTimeToWait" value="2000"/>
                <!--强行让某个连接空闲,超时时间的设置-->
                <property name="poolMaximumCheckoutTime" value="10000"/>
                <!--最多的空闲数量-->
                <property name="poolMaximumIdleConnections" value="5"/>
            </dataSource>
        </environment>
    </environments>
    <mappers>
    </mappers>
</configuration>

关于Mybatis工具类的编写

工具类名叫SqlSessionUtil



import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;


public class SqlSessionUtil {
    private static SqlSessionFactory sqlSessionFactory;

    //工具类的构造方法一般是私有化的
    //工具类中所有方法都是静态的,直接采用类名即可调用。不需要new对象
    //为了防止new对象,构造方法私有化
    private SqlSessionUtil() {}

    //类加载时执行
    //SqlSessionUtil工具类在进行第一次加载的时候,解析mybatis-config.xml文件,创建SqlSessionFactory对象
    static {
        try {
            //SqlSessionFactory对象:一个SqlSessionFactory对应一个environment。一个environment通常是一个数据库
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession openSession() {
        return sqlSessionFactory.openSession();
    }
}

使用ThreadLocal改写工具类

package com.lwq.bank.utils;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;

/**
 * @ClassName SqlSessionUtil
 * @Description TODO
 * @Author lwq15
 * @Date 2024-05-04 21:31
 * @Version 1.0
 */
public class SqlSessionUtil {
    private static SqlSessionFactory sqlSessionFactory;
    // 全局的,服务器级别的,一个服务器当中定义一个即可。
    // 为什么把SqlSession对象放到ThreadLocal当中呢?为了保证一个线程对应一个SqlSession。
    private static ThreadLocal<SqlSession> local = new ThreadLocal<>();

    //工具类的构造方法一般是私有化的
    //工具类中所有方法都是静态的,直接采用类名即可调用。不需要new对象
    //为了防止new对象,构造方法私有化
    private SqlSessionUtil() {}

    //类加载时执行
    //SqlSessionUtil工具类在进行第一次加载的时候,解析mybatis-config.xml文件,创建SqlSessionFactory对象
    static {
        try {
            //SqlSessionFactory对象:一个SqlSessionFactory对应一个environment。一个environment通常是一个数据库
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(Resources.getResourceAsStream("mybatis-config.xml"));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static SqlSession openSession() {
        SqlSession sqlSession = local.get();
        if (sqlSession == null) {
            sqlSession = sqlSessionFactory.openSession();
            // 将sqlSession对象绑定到当前线程上。
            local.set(sqlSession);
        }
        return sqlSession;
    }

    /**
     * 关闭SqlSession对象(从当前线程中移除SqlSession对象。)
     * @param sqlSession
     */
    public static void close(SqlSession sqlSession){
        if (sqlSession != null) {
            sqlSession.close();
            // 注意移除SqlSession对象和当前线程的绑定关系。
            // 因为Tomcat服务器支持线程池。也就是说:用过的线程对象t1,可能下一次还会使用这个t1线程。
            local.remove();
        }
    }
}



优秀的Mybatis博客链接