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

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配置文件中的主要元素:
MyBatis总结(2)---配置文件的元素配置_第1张图片注:< 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 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>元素中的常见配置及其描述:
MyBatis总结(2)---配置文件的元素配置_第2张图片
使用方式:

<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总结(2)---配置文件的元素配置_第3张图片
注:上表所列举的别名可以在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总结(2)---配置文件的元素配置_第4张图片

当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>

你可能感兴趣的:(框架,数据库,mybatis,java)