Mybatis简介及其核心概念

千寻铁锁沉江底,一片降幡出石头。——刘禹锡《西塞山怀古》



Mybatis简介
Mybatis是什么?
MyBatis(3.x以前的版本叫ibatis)是一款一流的支持自定义SQL、存储过程和高级映射的持久化框架。MyBatis几 乎消除了所有的JDBC 代码,也基本不需要手工去设置参数和获取检索结果。 MyBatis 能够使用简单的XML格式或 者注解进行来配置,能够映射基本数据元素、 Map 接口和POJOs(普通java对象)到数据库中的记录。
Mybatis vs JDBC SQL

对比 Mybatis JDBC SQL
连接 托管 编码
SQL 隔离/集中 混合/分散
缓存 两级缓存 不支持
结果映射 自动映射 硬编码
维护性

构建SqlSessionFactory
XML构建(重点) :
每个基于MyBatis的应用都是以一个SqlSessionFactory的实例为中心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从XML配置文件或一个预先定制的 Configuration的实例构建出 SqlSessionFactory 的实例。

<?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="dev">
<environment id="dev">
<transactionManager type="JDBC">
</transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/memo"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
<environment id="prod">
<transactionManager type="JDBC">
</transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/memo"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/MemoGroupMapper.xml"/>
</mappers>
</configuration>

从 XML 文件中构建 SqlSessionFactory 的实例非常简单,建议使用类路径下的资源文件进行配置。但是也可以使 用任意的输入流(InputStream)实例,包括字符串形式的文件路径或者 file:// 的 URL 形式的文件路径来配置。 MyBatis 包含一个名叫 Resources 的工具类,它包含一些实用方法,可以非常容易从classpath 或其他位置加载资 源文件。

public static void main(String[] args) {
try {
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(
Resources.getResourceAsReader("mybatis-config.xml")
);
System.out.println(sqlSessionFactory);
} catch (IOException e) {
e.printStackTrace();

使用sqlSession
既然有了 SqlSessionFactory ,顾名思义,我们就可以从中获得 SqlSession 的实例了。SqlSession 完全包含了面 向数据库执行 SQL 命令所需的所有方法。你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。例如:

SqlSession session = sqlSessionFactory.openSession();
//SqlSession session = sqlSessionFactory.openSession(true);//自动提交
try {
MemoGroup memoGroup = (MemoGroup)
session.selectOne("com.bittech.mybatis.mapper.MemoGroupMapper.selectMemoGroup", 1);
} finally {
session.close();
}

诚然这种方式能够正常工作,并且对于使用旧版本 MyBatis 的用户来说也比较熟悉,不过现在有了一种更直白的方 式。使用对于给定语句能够合理描述参数和返回值的接口(比如说MemoGroupMapper.class),现在不但可以执 行更清晰和类型安全的代码,而且还不用担心易错的字符串字面值以及强制类型转换。例如:

SqlSession session = sqlSessionFactory.openSession();
//SqlSession session = sqlSessionFactory.openSession(true);//自动提
try {
MemoGroupMapper mapper = session.getMapper(MemoGroupMapper.class);
MemoGroup memoGroup = mapper.selectMemoGroup(1);
} finally {
session.close();
}

SQL映射文件内容

<?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.bittech.mybatis.mapper.MemoGroupMapper">
<resultMap id="memoGroup" type="com.bittech.mybatis.entity.MemoGroup">
<id property="id" column="id" jdbcType="INTEGER"/>
<result property="name" column="name" jdbcType="VARCHAR"/>
<result property="createdTime" column="created_time" jdbcType="TIMESTAMP"/>
<result property="modifyTime" column="modify_time" jdbcType="TIMESTAMP"/>
</resultMap>
<select id="selectMemoGroup" resultMap="memoGroup">
select id,name,created_time,modify_time from memo_group
where id =#{id}
</select>
</mapper>

Mybatis的核心概念
核心类型
SqlSessionFactoryBuilder :
sqlSessionFactoryBuilder 这个类可以在任何时候被实例化、使用和销毁。一旦您创造了SqlSessionFactory就不 需要再保留它了。所以SqlSessionFactoryBuilder实例的最好的作用域是方法体内(即一个本地方法变量)。您能 重用SqlSessionFactoryBuilder创建多个SqlSessionFactory实例,但最好不要把时间、资源放在解析XML文件上, 而是要从中解放出来做最重要事情。
SqlSessionFactory:
sqlSessionFactory 一旦创建, SqlSessionFactory将会存在于您的应用程序整个运行生命周期中。很少或根本没 有理由去销毁它或重新创建它。最佳实践是不要在一个应用中多次创SqlSessionFactory。这样做会被视为“没品味” ,SqlSessionFactory最好的作用域范围是一个应用的生命周期范围。这可以由多种方式来实现,最简单的方式是 使用Singleton模式或静态Singleton模式。但这不是被广泛接受的最佳做法,相反,您可能更愿意使用像 Google Guice 或 Spring 的依赖注入方式。这些框架允许您创造一个管理器,用于管理SqlSessionFactory的生命周期。 3.1.3 SqlSession
sqlSession 每个线程都有一个SqlSession实例, SqlSession实例是不被共享的,并且不是线程安全的。因此最好 的作用域是request或者method。决不要用一个静态字段或者一个类的实例字段来保存SqlSession实例引用。也不 要用任何一个管理作用域,如Servlet框架中的HttpSession,来保存SqlSession的引用。如果您正在用一个WEB框 架,可以把SqlSession的作用域看作类似于HTTP的请求范围。也就是说,在收到一个HTTP请求,您可以打开一个 SqlSession, 当您把response返回时,就可以把SqlSession关闭。关闭会话是非常重要的,您应该要确保会话在 一个finally块中被关闭。
Mapper interface :
mappers 是创建来绑定映射语句的接口,该Mapper实例是从SqlSession得到的。因此,所 有mapper实例的作用 域跟创建它的SqlSession一样。但是, mapper实例最好的作用域是 method,也就是它们应该在方法内被调用, 使用完即被销毁。并且mapper实例不用显式地被关 闭。虽然把mapper实例保持在一个request范围(与 SqlSession相似)不会产生太大的问题,但是您可能会发现,在这个层次上管理太多资源可能会失控。保持简单, 就是让Mappers保持在一个方法内。
核心类的实践总结 :

作用域
SqlSessionFactoryBuilder method
SqlSessionFactory application(单例)
SqlSession request,thread,method(非线程安全)
Mapper Interface request,thread,method

SQL的命名空间
SQL映射简述 :
Mybatis中关于SQL的部分重要集中在SQL映射,其支持SQL映射的方式有两种,一种是基于XML的方式,一种是基 于注解。
Mybatis的所有特性都是可以通过XML配置的方式进行定义,通常情况都是通过XML配置来使用Mybatis的SQL映 射,主要原因有以下几点:

  • XML配置支持Mybatis的所有特性
  • XML的维护性,阅读性
  • 开发工具对Mybatis的SQL映射XML配置具有良好的支持
  • 注解方式难以处理复杂SQL

SQL映射案例
下面通过定义一个 SQL映射文件来说明SQL的命名空间。

<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3mapper.dtd"> <mapper namespace="com.bittech.mybatis.mapper.MemoGroupMapper">    <resultMap id="memoGroup" type="com.bittech.mybatis.entity.MemoGroup">        <id property="id" column="id" jdbcType="INTEGER"/>        <result property="name" column="name" jdbcType="VARCHAR"/>        <result property="createdTime" column="created_time" jdbcType="TIMESTAMP"/>        <result property="modifyTime" column="modify_time" jdbcType="TIMESTAMP"/>    </resultMap>    <select id="selectMemoGroup" resultMap="memoGroup">        select id,name,created_time,modify_time from memo_group        where id =#{id}    </select> </mapper>

上面的SQL映射文件中的 com.bittech.mybatis.mapper.MemoGroupMapper 就是命名空间名称, selectMemoGroup 是SQL的名称,在同一个命名空间下,SQL名称是唯一的。
第一种查询

SqlSession session = factory.openSession(); MemoGroup memoGroup = session.selectOne("com.bittech.mybatis.mapper.MemoGroupMapper.selectMemoGroup", 1);

通过 命名空间+SQL名称 映射到具体的SQL。
第二种查询

MemoGroupMapper memoGroupMapper = session.getMapper(MemoGroupMapper.class); MemoGroup memoGroup = memoGroupMapper.selectMemoGroup(1);

通过接口类映射,相比第一种查询有以下几个优势:

  • 不依赖字符串,不容易出错,所以安全
  • 通过IDE的自动完成功能,可以快速通过映射类导航到具体的SQL语句
  • 不需要关注方法返回类型,不需要进行类型强转
展开阅读全文

没有更多推荐了,返回首页