MyBatis总结(2)---配置文件的元素配置

    科技2025-12-26  13

    MyBatis

    1.两个核心对象 ①SqlSessionFactory SqlSessionFactory是单个数据库映射关系经过编译后的内存镜像,其主要作用是创建SqlSession。SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来构建,而SqlSessionFactoryBuilder则可以通过XML配置文件或一个预先定义好的Configuration实例构建出SqlSessionFactory的实例。 通过XML配置文件构建出的SqlSessionFactory实例:

    // 1.读取配置文件 InputStream is = Resources.getResourceAsStream("配置文件位置"); // 2.构建工厂对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);

    SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用执行期间都会存在。通常每一个数据库都会只对应一个SqlSessionFactory,所以在构建SqlSessionFactory实例时,建议使用单例模式。

    在创建SqlSessionFactory 对象的过程中, 首先解析mybatis-config.xml 配置文件,读取配置文件中的mappers 配置后会读取全部的Mapper. xml 进行具体方法的解析,在这些解析完成后, SqlSessionFactory 就包含了所有的属性配置和执行SQL 的信息。

    ②SqlSession SqlSession是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作,它是MyBatis中最重要的内容。SqlSession对象包含了数据库中所有执行SQL操作的方法,由于其底层封装了JDBC连接,所以可以直接使用其实例来执行已映射的SQL语句。

    SqlSession实例是线程不安全的,因此其使用范围最好在一次请求或一个方法中,绝不能将其放在一个类的静态字段、实例字段或任何类型的管理范围(如Servlet的HttpSession)中使用。使用完SqlSession对象之后,要及时地关闭它。 一定不要忘记关闭SqlSession ,否则会因为连接没有关闭导致数据库连接数过多,造成系统崩溃。

    MyBatis有内建的SqlSession级别的缓存机制,用于缓存Select语句查询出来的结果,但此时必须是同一个SqlSession对象。

    获取SqlSession实例的代码:SqlSession sqlSession = SqlSessionFactory.openSession(); 注:为了简化开发,通常将创建SqlSessionFactory实例对象和创建SqlSession实例对象封装到一个工具类中,然后通过工具类来创建SqlSession。 例,

    package com.money.util; import java.io.IOException; import java.io.InputStream; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; public class MyBatisSqlSessionFactory { private static SqlSessionFactory factory; public static SqlSessionFactory getSqlSessionFactory() { try { // 1.读取配置文件 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); // 2.构建工厂对象 factory = new SqlSessionFactoryBuilder().build(is); } catch (IOException e) { e.printStackTrace(); } return factory; } /** * 获取SQLSession对象,手动提交事务 * * @return */ public static SqlSession openSession() { return openSession(false); } /** * 获取SQLSession对象,自动提交事务 * * @param flag * @return */ public static SqlSession openSession(boolean flag) { return getSqlSessionFactory().openSession(flag); } }

    2.配置文件主要元素 注:这里的配置文件指的是mybatis-config.xml文件。 ①< configuration>元素 在MyBatis框架的核心配置文件中,< configuration>元素是配置文件的根元素,其他元素都要在< configuration>元素内配置。MyBatis配置文件中的主要元素: 注:< configuration>的子元素必须按照上图中由上到下的顺序进行配置,否则MyBatis在解析XML配置文件的时候会报错。

    ②< properties>元素 < properties>是一个配置属性的元素,该元素通常用于将内部的配置外在化,即通过引用外部的配置文件来动态地替换内部定义的属性。例如,数据库的连接等属性,这样就更方便程序的运行和部署。 ~~创建db.properties的配置文件,文件内容如下:

    driver=oracle.jdbc.driver.OracleDriver url=jdbc:oracle:thin:@127.0.0.1:1521:XE username=money jdbc.password=money

    ~~在MyBatis配置文件mybatis-config.xml中配置<properties… />属性:

    <properties resource="db.properties">

    ~~修改配置文件中数据库连接的信息:

    <environments default="development"> <environment id="development"> <transactionManager type="JDBC" /> <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>

    完成上述配置后,dataSource中连接数据库的4个属性(driver、url、username和password)值将会由db.properties文件中对应的值来动态替换。 注:当使用外部引用时继续配置property数据库的用户名和密码,此时db.properties文件中的值优先级高,即外部配置文件优先级更高。 例,

    <properties resource="db.properties"> <property name="username" value="123" /> <property name="password" value="123" /> </properties>

    此时,使用的是db.properties文件中配置的信息。

    在< properties>元素定义的子元素在整个XML文件中都可以通过${name值}来获取其值。例,

    <properties> <property name="uesrname" value="123" /> </properties>

    此时在文件中就可以通过${username}来获取值。

    ③< settings>元素 < settings>元素主要用于改变MyBatis运行时的行为,例如开启二级缓存、开启延迟加载等。虽然不配置< settings>元素,也可以正常运行MyBatis。 < settings>元素中的常见配置及其描述: 使用方式:

    <settings> <setting name="cacheEnabled" value="true" /> </settings>

    ④< typeAliases>元素 < typeAliases>元素用于为配置文件中的Java类型设置一个别名。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余。别名的使用忽略大小写。 使用< typeAliases>元素配置别名:

    <typeAliases> <typeAlias type="com.money.bean.Book" alias="Book" /> </typeAliases>

    < typeAliases>元素的子元素< typeAlias>中的type属性用于指定需要被定义别名的类的全限定名;alias属性的属性值Book就是自定义的别名,它可以代替com.money.bean.Book在MyBatis文件的任何位置的使用。如果省略alias属性,MyBatis会默认将类名首字母小写后的名称作为别名。

    当POJO类过多时,还可以通过自动扫描包的形式自定义别名:

    <typeAliases> <package name="com.money.bean"/> </typeAliases>

    < typeAliases>元素的子元素< package>中的name属性用于指定要被定义别名的包,MyBatis会将所有com.money.bean包中的POJO类以首字母小写的非限定类名来作为它的别名。例,com.money.bean.Book的的别名是book。

    还可以在程序中使用注解,则别名为其注解的值:

    @Alias(value = "book") public class Book { }

    注:@Alias("book")也可以,@Alias注解将会覆盖配置文件中的< typeAliases>定义

    注:@Alias 要和< package name=""/>标签配合使用,Mybatis会自动查看指定包内的类别名注解,如果没有这个注解,那么默认的别名就是类的名字,不区分大小写。

    除了可以使用< typeAliases>元素自定义别名外,MyBatis框架还默认为许多常见的Java类型(如数值、字符串、日期和集合等)提供了相应的类型别名: 注:上表所列举的别名可以在MyBatis中直接使用,别名不区分大小写。

    ⑤< typeHandler>元素(类型处理器) 当MyBatis将一个Java对象作为输入参数执行INSERT语句操作时,它会创建一个PreparedStatement对象,并且使用setXXX()方法对?号占位符 设置相应的参数值 。这里,XXX可以是int,String,Date 等 Java对象属性类型的任意一个。例,

    <insert id="insertStudent" parameterType="Student"> INSERT INTO STUDENTS(STUD_ID,NAME,EMAIL) VALUES(#{studId},#{name},#{email}) </insert>

    当执行上面的语句时,MyBatis将采取以下操作: 创建一个有占位符的PreparedStatement接口,例:PreparedStatement ps = connection.prepareStatement ("INSERT INTO STUDENTS(STU_ID,NAME,EMAIL) VALUES(?,?,?)"); 接下来就像JDBC的操作一样,针对不同的?采用合适setXXX方法去设置参数值。例,stuId是Integer类型,所以会使用setInt()方法:ps.setInt(1,student.getStuId());

    但MyBatis是怎么知道对于Integer类型属性使用setInt()和String类型属性使用setString()方法呢?其实MyBatis是通过使用类型处理器typeHandlers来决定这样做的。typeHandler的作用就是将预处理语句中传入的参数从javaType(Java类型)转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。

    MyBatis对于以下的类型使用内置的类型处理器:所有的基本数据类型、基本类型的包装类型、 byte[]、java.util.Date、java.sql.Date、java,sql.Time、java.sql.Timestamp、java枚举类型等:

    当MyBatis框架所提供的这些类型处理器不能够满足需求时,还可以通过自定义的方式对类型处理器进行扩展(自定义类型处理器可以通过实现TypeHandler接口或者继承BaseTypeHandler类来定义)。< typeHandler>元素就是用于在配置文件中注册自定义的类型处理器的。使用方式: ~~注册一个类的类型处理器:

    <typeHandlers> <typeHandler handler="com.money.bean.Book" /> </typeHandlers>

    子元素< typeHandler>的handler属性用于指定在程序中自定义的类型处理器类。

    ~~注册一个包中所有的类型处理器:

    <typeHandlers> <package name="com.money.bean"/> </typeHandlers>

    子元素< package>的name属性用于指定类型处理器所在的包名,使用此种方式后,系统会在启动时自动地扫描com.money.bean包下所有的文件,并把它们作为类型处理器。

    继承BaseTypeHandler类需要实现它的方法:

    package com.money.bean; import java.sql.CallableStatement; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import org.apache.ibatis.type.BaseTypeHandler; import org.apache.ibatis.type.JdbcType; public class BookTypeHandler extends BaseTypeHandler<Book> { // 查询中遇到Book类型的应该如何封装(使用列名封装) @Override public Book getNullableResult(ResultSet rs, String columnName) throws SQLException { // TODO Auto-generated method stub return null; //此处通过结果集rs的getString方法获取对应的数据库列中的值,将它如何转换为需要的类型对象需要自己设置 } // 查询中遇到Book类型的应该如何封装(使用列的下标) @Override public Book getNullableResult(ResultSet rs, int columnIndex) throws SQLException { // TODO Auto-generated method stub return null; 此处通过结果集rs的getString方法获取对应的数据库列中的值,将它如何转换为需要的类型对象需要自己设置 } // CallableStatement使用中遇到了Book类型的应该如何封装 @Override public Book getNullableResult(CallableStatement cs, int columnIndex) throws SQLException { // TODO Auto-generated method stub return null; //此处的cs和rs类似 } // 遇到参数类型为Book的值的时候应该如何在ps中设置值 @Override public void setNonNullParameter(PreparedStatement ps, int arg1, Book book, JdbcType arg3) throws SQLException { // TODO Auto-generated method stub ps.setString(arg1, book.toString()); //在数据库中需要什么类型就用什么set方法,arg1是PreparedStatement的语句中需要设置该特殊类型的位置 } } ⑥< objectFactory>元素

    MyBatis框架每次创建结果对象的新实例时,都会使用一个对象工厂(ObjectFactory)的实例来完成。MyBatis中默认的ObjectFactory的作用就是实例化目标类,它既可以通过默认构造方法实例化,也可以在参数映射存在的时候通过参数构造方法来实例化。 MyBatis中默认的ObjectFactory是由org.apache.ibatis.reflection.factory.DefaultObjectFactory来提供服务,如果想覆盖ObjectFactory的默认行为,则可以通过自定义ObjectFactory来实现: ~~自定义一个对象工厂。自定义的对象工厂需要实现ObjectFactory接口,或者继承DefaultObjectFactory类:

    public class MyObjectFactory extends DefaultObjectFactory { }

    ~~在配置文件中使用< objectFactory>元素配置自定义的ObjectFactory:

    <objectFactory type="com.money.bean.MyObjectFactory"> <property name="" value="MyObjectFactory" /> </objectFactory>

    ⑦< plugins>元素 < plugins>元素的作用就是配置用户所开发的插件。

    ⑧< environments>元素 在配置文件中,< environments>元素用于对环境进行配置。MyBatis的环境配置实际上就是数据源的配置,我们可以通过< environments>元素配置多种数据源,即配置多种数据库:

    <!-- 配置数据库 --> <environments default="development"> <environment id="development"> <!-- 配置事务管理器 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据库(数据源)连接信息 --> <dataSource type="POOLED"> <property name="driver" value="oracle.jdbc.driver.OracleDriver" /> <property name="url" value="jdbc:oracle:thin:@127.0.0.1:1521:XE" /> <property name="username" value="123" /> <property name="password" value="123" /> </dataSource> </environment> </environments>

    < environments>元素是环境配置的根元素,它包含一个default属性,该属性用于指定默认的环境ID。< environment>是< environments>元素的子元素,它可以定义多个,其id属性用于表示所定义环境的ID值,当有多个environment数据库环境时,可以根据environments的default属性值为environment的id属性来指定哪个数据库环境起作用,也可以根据下面的代码改变数据库环境。 在< environment>元素内,包含事务管理和数据源的配置信息,其中< transactionManager>元素用于配置事务管理,它的type属性用于指定事务管理的方式,即使用哪种事务管理器;< dataSource>元素用于配置数据源,它的type属性用于指定使用哪种数据源,该元素至少要配置4要素:driver、url、username、password。

    在获取SqlSessionFactory对象时,如果没有指定用哪个数据库环境,则build方法的参数默认是environments的default属性值,如果想要更换数据库环境,可以将build方法的第二个参数改为要更换的数据库环境的environment的id值。例,

    // 1.读取配置文件 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); // 2.构建工厂对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is); //默认是environments的default属性值 // 1.读取配置文件 InputStream is = Resources.getResourceAsStream("mybatis-config.xml"); // 2.构建工厂对象 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is,"development"); //指定environment的id值

    在MyBatis中,可以配置两种类型的事务管理器,分别是JDBC和MANAGED:

    JDBC:此配置直接使用了JDBC的提交和回滚设置,它依赖于从数据源得到的连接来管理事务的作用域。MANAGED:此配置从来不提交或回滚一个连接,而是让容器来管理事务的整个生命周期。在默认情况下,它会关闭连接,但一些容器并不希望这样,可以将closeConnection属性设置为false来阻止它默认的关闭行为。

    注:如果项目中使用的是Spring+ MyBatis,则没有必要在MyBatis中配置事务管理器,因为实际开发中,会使用Spring自带的管理器来实现事务管理。

    ⑨ < mappers>元素 < mappers>元素用于指定MyBatis映射文件的位置,引入映射文件方法有4种: 使用xml文件来配置sql语句: ~~使用类路径引入:

    <mappers> <mapper resource="com/money/mappers/BookMapper.xml" /> </mappers>

    ~~使用本地文件路径引入:

    <mappers> <mapper url="" /> </mappers>

    使用注解来配置sql语句: ~~使用接口类引入:

    <mappers> <mapper class="com.money.mappers.BookMapper" /> </mappers>

    ~~使用包名引入:

    <mappers> <package name="com.money.mappers"/> </mappers>
    Processed: 0.036, SQL: 9