## MyBatis
MyBatis 是一个可以自定义 SQL、存储过程和高级映射的持久层框架。 MyBatis 摒除了大部分的 JDBC代码、手工设置参数和结果集获取。 MyBatis 只使用简单的 XML 和注解来配置和映射基本数据类型、Map 接口和 POJO 到数据库记录。
每一个 MyBatis 应该都是以一个 SqlSessionFactory 实例为中心。一个 SqlSessionFactory 实例可以使用SqlSessionFactoryBuilder 来创造。 从配置类中创造的定制 SqlSessionFactoryBuilder 实例, 可以使用 XML配置文件来生成一个 SqlSessionFactory 实例,当然也可以通过Java API获取。
### 使用XML获取SqlSessionFactory
```java
//mybatis配置文件路径
String resource = "mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
//获取SqlSessionFactory
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
```
上述`mybatis-config.xml`配置文件如下:
```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="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<!-- Mapper -->
<mapper resource="com/zys/hello/mybatis/UserMapper.xml"/>
</mappers>
</configuration>
```
### 使用Java API获取SqlSessionFactory
```java
//获取数据源(从自定义工厂获取)
DataSource dataSource = UserDataSourceFactory.getDataSource();
//创建事务工厂
TransactionFactory transactionFactory = new JdbcTransactionFactory();
//创建环境
Environment environment =
new Environment("development", transactionFactory, dataSource);
//配置环境
Configuration configuration = new Configuration(environment);
//配置Mapper
configuration.addMapper(UserMapper.class);
//获取SqlSessionFactory
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(configuration);
```
## 获取SQLSession
上面演示了如何获取SqlSessionFactory,但我们要真正执行SQL的话需要通过SqlSession中的方法。SqlSession对象可以通过SqlSessionFactory获取。
方式一:
```java
SqlSession session = sqlSessionFactory.openSession();
try {
User user = (User) session.select(
"com.zys.hello.mybatis.UserMapper.selectUser", 1);
} finally {
session.close();
}
```
方式二(更安全):
```java
SqlSession session = sqlSessionFactory.openSession();
try {
//获取Mapper
UserMapper mapper = session.getMapper(UserMapper.class);
User user = mapper.selectUser(1);
} finally {
session.close();
}
```
## Mapper
上面没有任何SQL语句,为什么能访问数据库呢,答案是SQL语句写在Mapper XML文件中,前面演示用到的UserMpper.xml文件内容如下:
```xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zys.hello.mybatis.UserMapper">
<select id="selectUser" parameterType="int" resultType="User">
select * from user where id = #{id}
</select>
</mapper>
```
映射文件详情:[MyBatis映射文件](https://zysite.top/2020/12/19/mybatis-mapper/)
前面获取SqlSession并调用的方法二中,还出现了`UserMapper`类,其实UserMapper是我们定义的接口,内容如下:
```java
package com.zys.hello.mybatis;
public interface UserMapper {
User selectUser(int id);
}
```
它和Mapper配置文件很多地方是对应的,如:包名+类型 = 配置文件中namespace,方法定义 = select标签。
其实除了使用XML配置文件,也可以直接在接口方法上使用注解。
使用注解的UserMapper接口:
```java
package com.zys.hello.mybatis;
public interface UserMapper {
@Select("select * from user where id = #{id}")
User selectUser(int id);
}
```
注解虽然简洁,但不适合复杂的SQL。
## 作用域生命周期
理解了如何使用上述类或配置文件访问数据库,还需要知道这些类的生命周期,以更好的使用它们。
### 1. SqlSessionFactoryBuilder
SqlSessionFactory构造器,创建好SqlSessionFactory就可以丢弃了,通常作为局部变量就行。
### 2. SqlSessionFactory
一旦创建, SqlSessionFactory 就会在整个应用过程中始终存在。所以没有理由去销毁和再创建它,一个应用运行中也不建议多次创建 SqlSessionFactory,最好最为应用的单例存在。
### 3. SqlSession
每个线程都有自己的 SqlSession 实例, SqlSession 实例是不能被共享,也是非线程安全的。因此最好使用 Request 作用域或者方法体作用域。不要使用类的静态变量来引用一个 SqlSession 实例,甚至不要使用类的一个实例变更来引用。永远不要在一个被管理域中引用 SqlSession,比如说在 Servlet 中的HttpSession 中。如果你正在使用 WEB 框架,应该让SqlSession 跟随 HTTP 请求的相似作用域。也就是说,在收到一个 HTTP 请求过后,打开 SqlSession,等返回一个回应以后,立马关掉这个 SqlSession。 关闭 SqlSession 是非常重要的。
### 4. Mapper
Mapper 是一种用于绑定映射语句的接口。 Mapper 接口的实例是用 SqlSession 来获得的。 同样最好使用请求作用域。在使用后会自动销毁。

MyBatis入门