# 配置文件
之前我们最开始的 Mybatis-config.xml
是这样的:
<?xml version="1.0" encoding="UTF-8" ?> | |
<!DOCTYPE configuration | |
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" | |
"http://mybatis.org/dtd/mybatis-3-config.dtd"> | |
<configuration> | |
<environments default="development"> | |
<environment id="development"> | |
<transactionManager type="JDBC"/> | |
<dataSource type="POOLED"> | |
<property name="driver" value="${驱动类(含包名)}"/> | |
<property name="url" value="${数据库连接URL}"/> | |
<property name="username" value="${用户名}"/> | |
<property name="password" value="${密码}"/> | |
</dataSource> | |
</environment> | |
</environments> | |
</configuration> |
# 环境
可以看到有这样的标签:
<environments default="development"> | |
<environment id="development"> | |
<!-- .... --> | |
</environment> | |
</environments> |
其实可以写很多个 <environment>
标签,表示连接不同的数据库,因为实际开发中不可能只使用一个数据库。例如:同时支持 Oracle 和 MySQL 数据库。也有可能是为了分别定义开发环境、测试环境和生产环境。
你可以配置多种环境(environment),但是每个 SqlSessionFactory 实例只能选择一个环境。
我们看一下之前为我们为了得到 SqlSession
做了些什么:
SqlSessionFactory factory = new | |
SqlSessionFactoryBuilder(). | |
build(Resources.getResourceAsReader("mybatis-config.xml")); |
其实 SqlSessionFactoryBuilder
的 build
可以接收配置环境的属性:
SqlSessionFactory factory = new | |
SqlSessionFactoryBuilder(). | |
build(Resources.getResourceAsReader("mybatis-config.xml"),"环境ID"); |
如果没有选择环境 ID,就使用默认的环境 ID,看最上面的 default = development
。
# typeAliases 标签
我们之前为了定义一个 mapper,需要关联到项目中的实体类,然而实体类需要使用全类限定名:
<mapper namespace="TestMapper"> | |
<select id="selectStudent" resultType="com.cyan.entity.Student"> | |
select * from student | |
</select> | |
</mapper> |
resultType
指定了 JavaBean 完全限定名,这个名称很长,每次都要完整的输入,很是麻烦。因此就出现了 <typeAliases>
标签,该标签用来将给定的实体定义别名。
<typeAliases> | |
<typeAlias alias="Student" type="com.cyan.entity.Student" /> | |
<!-- 还可以定义很多 --> | |
<!-- 如果觉得还是麻烦,直接让 Mybatis 去扫描一个包,并将包下的所有类自动起别名 --> | |
<package name="com.cyan.entity"/> | |
</typeAliases> |
你应该尽量避免不同包出现相同类名的类。
也可以指定实体类添加一个注解,指定别名:
@Alias("lbwnb") | |
public class Student { | |
private int sid; | |
private String name; | |
private String sex; | |
} |
# transactionManager 标签
翻译过来是事务管理器,我们先看一下之前是怎么写的:
<transactionManager type="JDBC"/> |
在 MyBatis 中有两种事务管理器类型:
- JDBC – 这个配置直接简单使用了 JDBC 的提交和回滚设置。它依赖于从数据源得到的连接来管理事务范围。
- MANAGED – 这个配置几乎没做什么。它从来不提交或回滚一个连接。而它会让容器来管理事务的整个生命周期(比如 Spring 或 JEE 应用服务器的上下文)。默认情况下它会关闭连接。然而一些容器并不希望这样,因此如果你需要从连接中停止它,将 closeConnection 属性设置为 false。
还可以自定义事务管理器,JDBC 实现了 TransacFacotry,MANAGED 实现了 Transaction,所以我们自定义事务管理器需要实现其中一个接口。
TransacFacotry 源码:
public interface TransactionFactory { | |
// 设置属性 | |
void setProperties(Properties props); | |
// 创建事务 | |
Transaction newTransaction(Connection conn); | |
Transaction newTransaction(DataSource dataSource, | |
TransactionIsolationLevel level, boolean autoCommit); | |
} |
Transaction 源码:
public interface Transaction { | |
// 获取数据库连接 | |
Connection getConnection() throws SQLException; | |
// 提交事务 | |
void commit() throws SQLException; | |
// 回滚事务 | |
void rollback() throws SQLException; | |
// 关闭数据库连接 | |
void close() throws SQLException; | |
} |
假设为我们要实现的自定义事务管理器叫做 MyTransaction
,全类限定名是 com.utils.MyTransaction
。
那么需要在别名中声明:
<typeAliases> | |
<typeAlia alias="my_transaction" type="com.utils.MyTransaction"/> | |
</typeAliases> |
Mybatis 会通过 resolveAlias 方法去解析别名:
protected Class<?> resolveClass(String alias) { | |
if(alias == null) return null; | |
try { | |
// 拿到类 | |
return resolveAlias(alias); | |
} catch (Exception e) { | |
throw new BuilderException("Error resolving class. Cause: " + e, e); | |
} | |
} |
现在看一下整个配置文件:
<?xml version="1.0" encoding="UTF-8" ?> | |
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" | |
"http://mybatis.org/dtd/mybatis-3-config.dtd"> | |
<configuration> | |
<typeAliases> | |
<typeAlia alias="my_transaction" type="com.utils.MyTransaction"/> | |
</typeAliases> | |
<environments default="development" > | |
<environment id="development" > | |
<transactionManager type="my_transaction" /> | |
<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> | |
</environment> | |
</environments> | |
<mappers> | |
<!-- 定义 mapper--> | |
</mappers> | |
</configuration> |
自定义事务工厂类:
public class MyTransactionFactory implements TransactionFactory { | |
private static final String NAME = MyTransactionFactory.class.getSimpleName(); | |
@Override | |
public void setProperties(Properties props) { | |
System.out.println(NAME + " setProperties()"); | |
} | |
@Override | |
public Transaction newTransaction(Connection conn) { | |
System.out.println(NAME + " newTransaction()"); | |
return new MyTransaction(conn); | |
} | |
@Override | |
public Transaction newTransaction(DataSource dataSource, T | |
ransactionIsolationLevel level, | |
boolean autoCommit) { | |
System.out.println(NAME + " newTransaction()"); | |
try { | |
return new MyTransaction(dataSource.getConnection()); | |
} catch (SQLException e) { | |
e.printStackTrace(); | |
} | |
return null; | |
} | |
} |
自定义事务类:
public class MyTransaction implements Transaction { | |
private static final String NAME = MyTransaction.class.getSimpleName(); | |
private Connection connection; | |
public MyTransaction(Connection connection) { | |
this.connection = connection; | |
} | |
@Override | |
public Connection getConnection() throws SQLException { | |
System.out.println(NAME + " getConnection()"); | |
return this.connection; | |
} | |
@Override | |
public void commit() throws SQLException { | |
System.out.println(NAME + " commit()"); | |
if(null != this.connection && !this.connection.getAutoCommit()) { | |
this.connection.commit(); | |
} | |
} | |
@Override | |
public void rollback() throws SQLException { | |
System.out.println(NAME + " rollback()"); | |
if(null != this.connection && !this.connection.getAutoCommit()) { | |
this.connection.rollback(); | |
} | |
} | |
@Override | |
public void close() throws SQLException { | |
System.out.println(NAME + " close()"); | |
if(null != this.connection) { | |
this.connection.close(); | |
} | |
} | |
} |
就可以使用了。
# dataSource 标签
先看一下之前 dataSource
是什么:
<dataSource type="POOLED"> | |
<property name="driver" value="${驱动类(含包名)}"/> | |
<property name="url" value="${数据库连接URL}"/> | |
<property name="username" value="${用户名}"/> | |
<property name="password" value="${密码}"/> | |
</dataSource> |
<dataSource>
标签使用基本的 JDBC 数据源接口来配置 JDBC 连接对象的资源。
type
可取的内置数据源有: UNPOOLED
, POOLED
, JNDI
。
第二个是 web 常用的,不同的数据库对这个的表现也是不一样的,所以对某些数据库来说配置数据源并不重要,这个配置也是闲置的。
# 参考
https://www.hxstrive.com/subject/mybatis/245.htm
https://www.hxstrive.com/subject/mybatis/241.htm
https://www.hxstrive.com/subject/mybatis/246.htm
https://www.hxstrive.com/subject/mybatis/247.htm
https://www.yuque.com/qingkongxiaguang/javaweb/gn0syt#a28726e1