MyBatis的功能架构
API接口层
参见下方API
数据处理层
参数映射:指的是对于java 数据类型和jdbc数据类型之间的转换
SQL解析:SQL语句配置、解析、动态生成
SQL执行:Executor
结果映射处理:
基础支撑层
连接管理
事务管理
配置加载
缓存机制
SQL语句的配置方式
- 基于注解
- 基于XML文件
MyBatis Java API
SqlSessionFactoryBuilder
- 创建SqlSessionFactory实例
- build()方法从不同的资源中创建:InputStream或Configuration
- InputStream可选的参数是 environment 和 properties
- mybatis提供Resources 工具帮助加载资源文件
Reader getResourceAsReader(String resource)
Properties getResourceAsProperties(String resource)
InputStream getResourceAsStream(ClassLoader loader, String resource)
SqlSessionFactory
- 调用openSession()创建SqlSession实例
- 可选参数有:自动提交、事务隔离级别、预处理、自定义连接、执行器类型
SqlSession
语句执行方法
T selectOne(String statement)
List selectList(String statement)
Map selectMap(String statement, String mapKey)
int insert(String statement)
int update(String statement)
int delete(String statement)
事务控制方法
void commit()
void commit(boolean force)
void rollback()
void rollback(boolean force)
清理 Session 级的缓存
void clearCache()
关闭SqlSession
void close()
使用映射器
T getMapper(Class type)
动态 SQL
MyBatis 通过传入的参数值,使用 Ognl 来动态地构造SQL语句
- if
- choose (when, otherwise)
- trim (where, set)
- foreach
Select执行过程分析
1.创建SqlSession对象
2.为SqlSession传递参数:Statement Id和params
- Statement Id对应xml配置文件里的sql语句
- params 是传递的查询参数
分析源码可知
1.根据Statement Id,在mybatis 配置对象Configuration中查找和配置文件相对应的MappedStatement
2. 将查询任务委托给MyBatis 的执行器 Executor
3.执行器Executor根据SqlSession传递的参数执行query()方法
1.根据具体传入的参数,动态地生成需要执行的SQL语句,用BoundSql对象表示
2.为当前的查询创建一个缓存Key
3.缓存中没有值,直接从数据库中读取数据
4. 执行查询,返回结果,然后将查询的结果放入缓存之中
5. 根据既有的参数,创建StatementHandler对象来执行查询操作
6. 创建jStatement对象,传递给StatementHandler对象
7. 调用StatementHandler.query()方法,返回结果集
Executor.query()方法创建一个StatementHandler对象,然后将必要的参数传递给StatementHandler,使用StatementHandler来完成对数据库的查询,最终返回结果集
客户端如何调用接口?
1.MyBatis提供的API
如后面的例子
2.调用getMapper:面向接口编程
MyBatis 会根据相应的接口声明的方法信息,通过动态代理机制生成一个Mapper 实例,我们使用Mapper 接口的某一个方法时,MyBatis 会根据这个方法的方法名和参数类型,确定Statement Id
MyBatis的优缺点
优点
- 解除sql与程序代码的耦合:通过提供DAL层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
- 提供映射标签,支持对象与数据库的orm字段关系映射
- 提供对象关系映射标签,支持对象关系组建维护
- 提供xml标签,支持编写动态sql。
缺点
- 编写SQL语句时工作量很大。
- SQL语句依赖于数据库,导致数据库移植性差,不能更换数据库。
配置
1.XML 映射配置文件
- properties
这些属性都是可外部配置且可动态替换的,既可以在典型的 Java 属性文件中配置,亦可通过 properties 元素的子元素来传递。 - settings
MyBatis 中极为重要的调整设置,它们会改变 MyBatis 的运行时行为 - typeAliases
存在的意义仅在于用来减少类完全限定名的冗余
<?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>
<settings>
<!-- 该配置影响的所有映射器中配置的缓存的全局开关 -->
<setting name="cacheEnabled" value="false" />
<!-- 允许 JDBC 支持自动生成主键,需要驱动兼容 -->
<setting name="useGeneratedKeys" value="true" />
<!-- 配置默认的执行器 :REUSE 执行器会重用预处理语句 -->
<setting name="defaultExecutorType" value="REUSE" />
</settings>
<!-- 别名 -->
<typeAliases>
<typeAlias alias="User" type="com.moni.mybatis.models.User" />
</typeAliases>
<!-- 配置环境 -->
<environments default="development">
<environment id="development">
<!-- 事务管理器的配置 -->
<transactionManager type="JDBC" />
<!-- 数据源的配置 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/hibernate?&useSSL=true" />
<property name="username" value="moni" />
<property name="password" value="520610" />
</dataSource>
</environment>
</environments>
<!-- 映射器用来定位映射文件 -->
<mappers>
<mapper resource="com/moni/mybatis/models/User.xml" />
</mappers>
</configuration>
2.MyBatis XML映射文件
- cache – 给定命名空间的缓存配置。
- cache-ref – 其他命名空间缓存配置的引用。
- resultMap – 是最复杂也是最强大的元素,用来描述如何从数据库结果集中来加载对象。
- sql – 可被其他语句引用的可重用语句块。
- insert – 映射插入语句
- update – 映射更新语句
- delete – 映射删除语句
- select – 映射查询语句
<?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.moni.mybatis.models.IUser">
<resultMap id="BaseResultMap" type="User">
<result column="user_username" property="username" />
<result column="user_password" property="password" />
</resultMap>
<!-- 外部 resultMap 的命名引用 -->
<select id="Query" resultMap="BaseResultMap"
parameterType="String" resultType="User">
select * from user_info where user_username = #{username}
</select>
<insert id="Insert" parameterType="User">
insert into user_info (user_username,user_password)
values (#{username},#{password})
</insert>
</mapper>
接口
package com.moni.mybatis.models;
import java.util.List;
public interface IUser {
public List<User> getUserList();
public void Insert(User user);
public void updateUser(User user);
public void deleteUser(String username);
public String Query(String username);
}
测试
private static SqlSessionFactory sqlSessionFactory;
private static Reader reader;
private static SqlSession sqlsession;
//初始化
static {
try {
reader = Resources.getResourceAsReader("Configure.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void Query() throws IOException {
sqlsession = sqlSessionFactory.openSession();
List<User> userList = sqlsession.selectList("com.moni.mybatis.models.IUser.Query","moni10");
for (User p : userList){
System.out.println(p);
}
sqlsession.close();
}
@Test
public void Insert() throws IOException {
sqlsession = sqlSessionFactory.openSession();
// 获取Mapper
IUser userMapper = sqlsession.getMapper(IUser.class);
User user = new User();
user.setUsername("moni10");
user.setPassword("10");
userMapper.Insert(user);
sqlsession.commit();
sqlsession.close();
}