MyBatis的核心配置

Posted shi_zi_183

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了MyBatis的核心配置相关的知识,希望对你有一定的参考价值。

MyBatis的核心配置

MyBatis的核心对象

SqlSessionFactory

SqlSeesionFactory是MyBatis框架中十分重要的对象,它是单个数据库映射关系经过编译后的内存镜像,其主要作用是创建SqlSession。SqlSessionFactory对象的实例可以通过SqlSessionFactoryBuilder对象来构建,而SqlSessionFactoryBuilder则可以通过XML配置文件或一个预先定义好的Configuration实例构建出SqlSessionFactory的实例。

InputStream inputStream=Resources.getResourceAsStream("配置文件位置");
SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);

SqlSessionFactory对象是线程安全的,它一旦被创建,在整个应用执行期间都会参在。如果多次地创建同一个数据库地SqlSessionFactory,那么此数据库地资源将很容易被耗尽。为了解决此问题,通常每一个数据库都会只对应一个SqlSessionFactory,所以在构建SqlSessionFactory时,建议使用单列模式。

SqlSession

SqlSession是MaBatis框架中另一个重要地对象,它是应用程序与持久层之间执行交互操作的一个单线程对象,其主要作用是执行持久化操作。SqlSession对象包含了数据库中所有执行SQL操作地方法,由于其底层封装了JDBC连接,所以可以直接使用其实例来执行已映射地SQL语句。
每一个线程都应该有一个自己的SqlSession实例,并且该实例是不能被共享的。同时,SqlSession实例也是线程不安全的,因此其使用范围最好在一次请求或一个方法中,绝不能将其放在一个类的静态字段、实例字段或任何类型的管理范围(如Servlet的HttpSession)中使用。使用完SqlSession对象之后,要及时地关闭它,通常可以将其放在finally块中关闭

SqlSession sqlSession = sqlSessionFactory.openSession();
try{
	//此处执行持久化操作
}finally{
	sqlSession.close();
}

SqlSession对象中包含了很多方法

方法描述
<T> T selectOne(String statement)参数statement是在配置文件中定义的<select>元素的id。使用该方法后,会返回执行SQL语句查询结果的一条泛型对象
<T> T selectOne(String statement,Object parameter)参数statement是在配置文件中定义的<select>元素的id,parameter是查询所需的参数。使用该方法后,会返回执行SQL语句查询结果的一条泛型对象
<E> List selectList(String statement)参数statement是在配置文件中定义的<select>元素的id。使用该方法后,会返回执行SQL语句查询结果的泛型对象的集合
<E> List selectList(String statement,Object parameter)参数statement是在配置文件中定义的<select>元素的id,parameter是查询所需的参数。使用该方法后,会返回执行SQL语句查询结果的泛型对象的集合
<E> List selectList(String statement,Object parameter,RowBounds rowDounds)参数statement是在配置文件中定义的<select>元素的id,parameter是查询所需的参数,rowBounds是用于分页的参数对象。使用该方法后,会返回执行SQL语句查询结果的泛型对象的集合
void select(String statement,Object parameter,ResultHandler handler)参数statement是在配置文件中定义的<select>元素的id,parameter是查询所需的参数,参数ResultHandler对象用于处理查询返回的复杂结果集,通常用于多表查询。
int insert(String statement)参数statement是在配置文件中定义的<insert>元素的id,使用该方法后,会返回执行SQL语句所影响的行数
int insert(String statement,Object parameter)参数statement是在配置文件中定义的<insert>元素的id,parameter是更新所需的参数。使用该方法后,会返回执行SQL语句所影响的行数。
int delete(String statement)删除方法,参数statement是在配置文件中定义的<insert>元素的id,使用该方法后,会返回执行SQL语句所影响的行数
int delete(String statement,Object parameter)删除方法,参数statement是在配置文件中定义的<insert>元素的id,parameter是更新所需的参数。使用该方法后,会返回执行SQL语句所影响的行数。
void commit()提交事务的方法
void rollback()回滚事务的方法
void close()关闭SqlSession对象
<T> T getMapper(Class<T>type)该方法会返回Mapper接口的代理对象,该对象关联了SqlSession对象,开发人员可以使用该对象直接调用方法操作数据库。参数type是Mapper的接口类型。MyBatis官方推荐通过Mapper对象访问MyBatis
Connection getConnection()获取JDBC数据库连接对象的方法

其中最难理解的是事务相关函数,commit()和rollback(),这里的函数并不等同于mysql中的commit命令和roolback命令,而是用于管理MyBatis缓存区的函数。在MyBatis中有一个缓存区,所有MyBatis并不会将表的改变直接映射到数据库中,而是先缓存在缓存区,在结束后再缓存。所以如果不执行commit()函数,那么通过MyBatis获取的表改变了,但是实际数据库并没有改变。同样rollback()函数可以清理MyBatis缓存,还原成开始的状态。

package test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.*;
import org.junit.Test;
import MyBatis.Customer;
import java.sql.*;


public class Test_commit {
	@Test
	public void commitTest() throws IOException, SQLException{
		String resource="mybatis-config.xml";
		InputStream inputStream=Resources.getResourceAsStream(resource);
		SqlSessionFactory sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
		SqlSession sqlSession=sqlSessionFactory.openSession();
		Customer customer=new Customer();
		customer.setUsername("abc");
		customer.setPhone("123412334");
		customer.setPhone("abc");
		int num=sqlSession.insert("addCustomer", customer);
		List<Customer> list=sqlSession.selectList("allCustomer");
		for(Customer one:list){
			System.out.println(one.toString());
		}
		selectAll();
		
		sqlSession.commit();
		
		list=sqlSession.selectList("allCustomer");
		for(Customer one:list){
			System.out.println(one.toString());
		}
		selectAll();
		sqlSession.close();
	}
	public void selectAll()throws SQLException{
		//1、注册数据库驱动
		DriverManager.registerDriver(new com.mysql.jdbc.Driver());
		//2、获取数据库连接
		String url="jdbc:mysql://localhost:3306/mybatis";
		String username="root";
		String password="123456";
		Connection conn=DriverManager.getConnection(url, username, password);
		//3、获取Statement对象
		Statement stmt=conn.createStatement();
		//4、执行sql
		String sql="select * from t_customer";
		ResultSet rs=stmt.executeQuery(sql);
		System.out.println("id|username|jobs|phone");
		while(rs.next()){
			int id=rs.getInt("id");
			String username1=rs.getString("username");
			String jobs=rs.getString("jobs");
			String phone=rs.getString("phone");
			System.out.println(id+"|"+username1+"|"+jobs+"|"+phone);
		}
	}
}


可以看到在commit()函数之前直接查询数据库没有将数据插入。

配置文件

MyBatis的核心配置文件中,包含了很多影响MyBatis行为的重要信息。这些信息通常在一个项目中只会在一个配置文件中编写,并且编写后也不会轻易更改。虽然在实际项目中需要开发人员编写或者修改的配置文件不多,但是熟悉配置文件中各个元素的功能还是十分重要的。

主要元素

在MyBatis框架的核心配置文件中,<configuration>元素是配置文件的根元素,其他元素都要在其内配置。

properties元素

<properties>是一个配置属性的元素。该元素通常用于将内部的配置外在化,即通过外部的配置来动态地替换内部定义地属性。例如,数据库地连接等属性,就可以通过典型地Java属性文件中地配置来替换
1)在项目地src目录下,添加一个全名为db.properties地配置文件

jdbc.driver=com.mysql.jbdc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis
jdbc.username=root
jdbc.password=root

2)在MyBatis配置文件mybatis-config.xml中配置<properties.../>元素

<properties resource="db.properties"/>

3)修改配置文件中数据库连接地信息

<dataSource type="POOLED">
	<property name="driver" value="${jdbc.driver}"/>
	<property name="url" value="${jdbc.url}"/>
	<property name="username" value="${jdbc.username}"/>
	<property name="password" value="${jdbc.password}"/>
</dataSource>

<settings>元素

<settings>元素主要用于改变MyBatis运行时地行为,例如开启二级缓存、开启延迟加载等,虽然不配置<settings>元素,也可以正常运行MyBatis,但是熟悉<settings>的配置内容以及它们的作用还是十分必要的。

设置参数描述有效值默认值
cacheEnable该配置影响所有映射器中配置的换成全局开关true/falsefalse
lazyLoadingEnable延迟加载的全局开关。开启时,所有关联对象都会延迟加载。特定关联关系中可以通过设置fetchType属性来覆盖该项的开关状态true/falsefalse
aggressiveLazyLoading关联对象属性的延迟加载开关。当启用时,对任意延迟属性的调用会使带有加载属性的对象完整加载;反之,每种属性都会按需加载true/falsetrue
multipleResultSetsEnabled是否允许单一语句返回多结果集(需要兼容驱动)true/falsetrue
useColumnLabel使用列标签代替列名。不同的驱动在这方面有不同的表现。具体可参考驱动文档或通过测试两种模式来观察所用驱动的行为true/falsetrue
useGeneratedKeys允许JDBC支持自动生成主键,需要驱动兼容。如果设置true,则这个设置强制使用自动生成主键,尽管一些驱动不兼容但仍可正常工作true/falsefalse
autoMappingBehavior指定MyBatis应如何自动映射到字段或属性。NONE表示取消自动映射;PARTIAL只会自动映射没有定义嵌套结果集映射的结果集;FULL会自动映射任意复杂的结果集(无论是否嵌套)NONE/PARTIAL/FULLPARTIAL
defaultExecutorType配置默认的执行器。SIMPLE就是普通的执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新SIMPLE/REUSE/BATCHSIMPLE
defaultStatementTimeout设置超过时间,他决定驱动等待数据库响应的秒数。当没有设置的时候,它取的就是驱动默认的时间任何正整数没有设置
mapUnderscoreToCamelCase是否开启自动驼峰命名规则(camel case)映射true/falsefalse
jdbcTypeForNull当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型。某些驱动需要指定列的JDBC类型,多数情况直接用一般类型即可,比如NULL、VARCHAR或OTHERNULL/VARCHAR/OTHEROTHER
<settings>
	<setting name="...." value="..."/>
	...
</settings>

<typeAliases>元素

<typeAliases>元素用于为配置文件中的Java类型设置一个简短的名字,即设置别名。别名的设置与XML配置相关,其使用的意义在于减少全限定类名的冗余。

<typeAliases>
	<typeAlias alias="user" type="com.ex.po.User"/>
</typeAliases>

上述示例中,<typeAliases>元素的子元素<typeAlias>中的type属性用于指定需要被定义别名的类的全限定名;alias属性的属性值user就是自定义的别名,它可以代替com.itheima.po.User使用在MyBatis文件的任何位置。如果省略alias属性,MyBatis会默认将类名首字母小写后的名称作为别名。
当POJO类过多时,还可以通过自动扫描包的形式自定义别名

<typeAliases>
	<package name="com.ex.po"/>
</typeAliases>

<typeAliases>元素的子元素<package>中的name属性用于指定要被定义别名的包,MyBatis会将所有com.itheima.po包中的POJO类以首字母小写的非限定类名来作为它的别名,比如com.itheima.po.User的user,com.itheima.po.Customer的别名为customer等。
需要注意上述方法的别名只适用于没有注解的情况。如果在程序中使用了注解则别名为其注解的值

@Alias(value="user")
public class User{
	//User的属性和方法
	...
}
别名映射的类型
_bytebyte
_longlong
_shortshort
_intint
_integerinteger
_doubledouble
_floatfloat
_booleanboolean
stringString
byteByte
longLong
shortShort
intInteger
integerInteger
doubleDouble
floatFloat
booleanBoolean
dataData
decimalBigDecimal
bigdecimalBigDecimal
objectObject
mapMap
hashmapHashMap
listList
arraylistArrayList
collectionCollection
iteratorIterator

<typeHandler>元素

MyBatis在预处理语句(PreparedStatement)中设置一个参数或者从结果集(ResultSet)中取出一个值时,都会其框架内部注册了的typeHandler(类型处理器)进行相关处理。typeHandler的作用就是预处理语句中传入的参数从javaType(Java类型)转换为jdbcType(JDBC类型),或者从数据库取出结果时将jdbcType转换为javaType。
类型处理器|Java类型|JDBC类型
BooleanTypeHandler|java.lang.Boolean,boolean|数据库兼容的BOOLEAN
ByteTypeHandler|java.lang.Byte,byte|数据库兼容的NUMERIC或BYTE
ShortTypeHandler|java.lang.Short,short|数据库兼容的NUMERIC或SHORT INTEGER
InterTypeHandler|java.lang.Integer,int|数据库兼容的NUMERIC或INTEGER
LongTypeHandler|java.lang.Long,long|数据库兼容的NUMERIC或LONG INTEGER
FloatTypeHandler|java.lang.Float,float|数据库兼容的NUMERIC或FLOAT
DoubleTypeHandler|java.lang.Double,bouble|数据库兼容的NUMERIC或DOUBLE
BigDecimalTypeHandler|java.math.BigDecimal|数据库兼容的NUMERIC或DECIMAL
StringTypeHandler|java.lang.String|CHAR,VARCHAR
ClobTypeHandler|java.lang.String|CLOB,LONGVARCHAR
ByteArrayTypeHandler|byte[]|数据库兼容的字节流类型
BlobTypeHandler|byte[]|BLOB,LONGVABINARY
DataTypeHandler|java.util.Data|TIMESTAMP
SqlTimestampTypeHandler|java.sql.Timestamp|TIMESTAMP
SqlDataTypeHandler|java.sql.Data|DATE
SqlTimeTypeHandler|java.sql.Time|TIME
当MyBatis框架所提供的这些类型处理器不能够满足需求时,还可以通过自定义的方法对类型处理器进行拓展(自定义类型处理器可以通过实现TypeHandler接口或者继承BaseTypeHandler类来定义)。<typeHandler>元素就是用于在配置文件中注册自定义的类型处理器的。
1、注册一个类的类型处理器

<typeHandlers>
	<typeHandler handler="com.ex.type.CustomtypeHandler" />
</typeHandlers>

上述代码中,子元素<typeHandler>的handler属性用于指定在程序中自定义的类型处理器类
2、注册一个包中所有的类型处理器

<typeHandlers>
	<package name="com.ex.type"/>
</typeHandler>

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

<objectFactory>元素

MyBatis框架每次创建结果对象的新实例时,都会使用一个对象工厂(ObjectFactory)的实例来完成。MyBatis中默认的ObjectFactory的作用就是实例化目标类,它既可以通过默认构造方法实例化,也可以通过参数映射存在的时候通过参数构造方法来实例化。
在通常情况下,我想使用默认ObjectFactory即可,MyBatis中默认的ObjectFactory是由org.apache.ibatis.reflection.factory.BefaultObjectFactory来提供服务的。大部分场景都不用配置和修改,但如果想覆盖ObjectFactory的默认行为,则可以通过自定义ObjectFactory来实现。
1)自定义一个对象工厂。自定义的对象工厂需要实现ObjectFactory接口,或者继承DefaultObjectFactory类。由于DefaultObjectFactory类已经实现了ObjectFactory接口,所以通过继承DefaultObjectFactory类实现即可

package MyBatis;
import java.util.Collection;
import java.util.List;
import java.util.Properties;

import org.apache.ibatis.reflection.factory.DefaultObjectFactory;
public class MyObjectFactory extends DefaultObjectFactory{
	private static final long serialVersionUID = 1L;
	public <T> T create(Class<T> type){
		return super.create(type);
	}
	public <T> T create(Class<T> type,List<Class<?>> constructorArgTypes,List<Object> constructorArgs){
		return super.create(type, constructorArgTypes, constructorArgs);
	}
	public void setProperties(Properties properties){
		super.setProperties(properties);
	}
	public <T> boolean isCollection(Class<T> type){
		return Collection.class.isAssignableFrom(type);
	}
}

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

<objectFactory>
	<property name="name" value="MyObjectFactory"/>
<objectFactory/>

自定义ObjectFactory在实际开发中不经常使用,这里只需要了解即可。

<plugins>元素

MyBatis允许在已映射语句执行过程中的某一点进行拦截调用,这种链接调用是通过插件来实现的。<plugins>元素的作用就是配置用户所开发的插件。如果用户想要进行插件开发,必须要先了解其内部的运行原理,因为在试图修改或重写已有方法的行为时,很可能会破坏MyBatis原有的核心模块。
可以自行了解,不做过多解读。

<environments>元素

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

<environments dfault="development">
	<environment id="development">
		<transactionManager type="JDBC"/>
		<dataSource type="POOLED">
			<property name="driver" value="${jdbc.driver}"/>
			<property name="url" value="${jdbc.url}"/>
			<property name="username" value="${jdbc.username}"/>
			<property name="password" value="${jdbc.password}"/>
		</dataSource>
	</enviroment>
</environments>

在上述示例代码中,<environments>元素是环境配置的根元素,它包含一个default属性,该属性用于指定默认的环境ID。<environment><environment>元素内子元素,它可以定义多个,其id用于表示所定义环境的ID值。在<environment>元素内,包含事务管理和数据源的配置信息,其中<transactionManager>元素用于配置事务管理,它的type属性用于指定事务管理的方式,即使用那种事务管理器;<dataSource>元素用于配置数据源,它的type属性用于指定使用哪种数据源。
在MyBatis中,可以配置两种类型的事务管理器,分别是JDBC和MANAGED。
1、JDBC:此配置直接使用了JDBC的提交和回滚设置,它依赖于数据源得到的链接来管理事务的作用域。
2、MANAGED:此配置从来不提交或回滚一个链接,而是让容器来管理事务的整个生命周期。在默认情况下,它会关闭连接,但一些容器并不希望这样,为此可以将closeConnection属性设置为false来阻止它默认的关闭行为。
注意:如果项目中使用的是Spring+MyBatis,则没有必要在MyBatis中配置事务管理器,因为实际开发中,会使用Spring自带的管理器来事务管理。
对于数据源的配置,MyBatis框架提供了UNPOOLED、POOLED和JNDI三种数据源类型
1、UNPOOLED
配置此数据源类型后,在每次被请求时会打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。

属性说明
driverJDBC驱动的Java类的完全限定名(并不是JDBC驱动中可能包含的数据源类)
url数据库的URL地址
username登录数据库的用户名
password登录数据库的密码
defaultTransactionIsolationLevel默认的连接事务隔离级别

2、POOLED
此数据源利用"池"的概念将JDBC连接对象组织起来,避免在创建新的连接实例时所需要初始化和认证的时间。这种方式使得并发Web应用可以快速地响应请求,是当前流行的处理方式

属性说明
poolMaximumActiveConnections在任意时间可以存在的活动(也就是正在使用)连接数量,默认,10
poolMaximumIdleConnections任意时间可能存在的空闲连接数
poolMaximumCheckoutTime在被强制返回之前,池中连接被检出(checked out)时间,默认值,20000毫秒,即20秒
poolTimeToWait如果获取连接花费的时间较长,他会给连接池打印状态日志并重新尝试获取一个连接(避免在误配置的情况下一直处于无提示的失败),默认值:20000毫秒,即20秒
poolPingQuery发送到数据库的侦测查询,用于检验连接是否处在正常工作秩序中。默认是"NO PING QUERY SET",这会导致多数数据库驱动失败时带有一定的错误消息
poolPingEnabled是否启用侦测查询。若开启,必须使用一个可执行的SQL语句设置poolPingQuery属性(最好是一个非常快的SQL),默认值:false
poolPingConnectionsNotUsedFor配置poolPingQuery的使用频度。可以被设置成匹配具体的数据库连接超时时间,来避免不必要的侦测,默认值:0(表示所有连接每一时刻都被侦测,只有poolPingEnable的属性值为true时适用)

3、JNDI
此数据库可以在EJB或应用服务器等容器中使用。容器可以集中或在外部配置数据源,然后放置在一个JNDI上下文的 引用。

属性说明
initial_context此属性主要用于在InitialContext中寻找上下文(即initialContext.lookup(initial_context))。该属性为可选属性,在忽略时,data_source属性会直接从InitialContext中寻找。
data_source此属性表示引用数据源实例位置的上下文的路径。如果提供了initial_context配置,那么程序会在其返回的上下文中进行查找;如果没有提供,则直接在InitialContext中查找。

<mappers>元素

在配置文件中,<mappers>元素用于指定MyBatis映射的文件,一般可以使用以下4种方法引入映射器文件,
1、使用类路径引入

<mappers>
	<mapper resource="com/ex/mapper/UserMapper.xml"/>
</mappers>

2、使用本地文件路径引入

<mappers>
	<mapper url="file:///D:/com/ex/mapper/UserMapper.xml"/>
</mappers>

3、使用接口类引入

<mappers>
	<mapper class="com.ex.mapper.UserMapper"/>
</mappers>

4、使用包名引入

<mappers>
	<mapper name="com.ex.mapper"/>
</mappers>

映射文件

主要元素

在映射文件中,<mapper>元素是映射文件的根元素,其他元素都是它的子元素。

<select>元素

<select>元素用于映射查询语句,它可以帮助我们从数据库读取出数据,并组装数据给业务开发人员。
使用<select>元素执行查询操作非常简单

<select id=以上是关于MyBatis的核心配置的主要内容,如果未能解决你的问题,请参考以下文章

Mybatis-应用分析和最佳实践-核心配置

Mybatis学习之核心原理代码详解

MyBatis框架UserMapperTest类的改进及核心配置文件

MyBatis高级特性

MyBatis框架—动态 SQL配置文件事务

03-Mybatis 核心组件