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/false | false |
lazyLoadingEnable | 延迟加载的全局开关。开启时,所有关联对象都会延迟加载。特定关联关系中可以通过设置fetchType属性来覆盖该项的开关状态 | true/false | false |
aggressiveLazyLoading | 关联对象属性的延迟加载开关。当启用时,对任意延迟属性的调用会使带有加载属性的对象完整加载;反之,每种属性都会按需加载 | true/false | true |
multipleResultSetsEnabled | 是否允许单一语句返回多结果集(需要兼容驱动) | true/false | true |
useColumnLabel | 使用列标签代替列名。不同的驱动在这方面有不同的表现。具体可参考驱动文档或通过测试两种模式来观察所用驱动的行为 | true/false | true |
useGeneratedKeys | 允许JDBC支持自动生成主键,需要驱动兼容。如果设置true,则这个设置强制使用自动生成主键,尽管一些驱动不兼容但仍可正常工作 | true/false | false |
autoMappingBehavior | 指定MyBatis应如何自动映射到字段或属性。NONE表示取消自动映射;PARTIAL只会自动映射没有定义嵌套结果集映射的结果集;FULL会自动映射任意复杂的结果集(无论是否嵌套) | NONE/PARTIAL/FULL | PARTIAL |
defaultExecutorType | 配置默认的执行器。SIMPLE就是普通的执行器;REUSE执行器会重用预处理语句(prepared statements);BATCH执行器将重用语句并执行批量更新 | SIMPLE/REUSE/BATCH | SIMPLE |
defaultStatementTimeout | 设置超过时间,他决定驱动等待数据库响应的秒数。当没有设置的时候,它取的就是驱动默认的时间 | 任何正整数 | 没有设置 |
mapUnderscoreToCamelCase | 是否开启自动驼峰命名规则(camel case)映射 | true/false | false |
jdbcTypeForNull | 当没有为参数提供特定的JDBC类型时,为空值指定JDBC类型。某些驱动需要指定列的JDBC类型,多数情况直接用一般类型即可,比如NULL、VARCHAR或OTHER | NULL/VARCHAR/OTHER | OTHER |
<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的属性和方法
...
}
别名 | 映射的类型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | integer |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
data | Data |
decimal | BigDecimal |
bigdecimal | BigDecimal |
object | Object |
map | Map |
hashmap | HashMap |
list | List |
arraylist | ArrayList |
collection | Collection |
iterator | Iterator |
<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
配置此数据源类型后,在每次被请求时会打开和关闭连接。它对没有性能要求的简单应用程序是一个很好的选择。
属性 | 说明 |
---|---|
driver | JDBC驱动的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的核心配置的主要内容,如果未能解决你的问题,请参考以下文章