Mybatis文档翻译
原创内容,转载请注明出处
介绍
什么是Mybatis?
Mybatis是一个优秀的持久化框架,支持自定义Sql,存储过程和高级映射。Mybatis消除了几乎所有的Jdbc代码和手工设置参数和返回的结果集。Mybatis可以对配置和原生Map使用简单的Xml或者注解,将接口和Java Pojo对象映射成数据库的记录。
帮助建立更好的文档
如果你发现这个文档任何地方的缺陷,或者缺少重要功能的文档,那么最好的方法是去学习它,并且自己去把它编写在文档上。
这个xdoc格式的文档的来源是在Git项目中,检出这版本库,更新他们并且发送一个pull request。
你是这个文档最好的作者,像你这样的人必须读它。
翻译
用户能够读取Mybatis以下翻译版本英语、日语、中文。
你想读自己母语版的Mybatis吗?那就提供你们母语的文档给我们吧。
新手入门
安装
使用Mybatis,你只需要在你的的类路径里包含mybatis-x.x.x.jar文件。
如果你是使用Maven,那么你只需要添加一下依赖在你的pom.xml文件中。
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency>
用Xml文件创建SqlSessionFactory
每个Mybatis应用程序都是以SqlSessionFactory实例为中心。一个SqlSessionFactory实例能够从SqlSessionFactoryBuilder类获得。SqlSessionFactoryBuilder可以从一个Xml文件或自定义的Configuration类的实例建立一个SqlSessionFactory实例。
从一个Xml文件去创建SqlSessionFactory实例是非常简单的,推荐你使用一个类路径资源去配置。但是你也可以使用InputStream实例,包含了一个字符文件路径或者fill://URL形式的路径。Mybatis有一个Resources的工具类,它包含一系列方法,使得从类路径或这其他位置加载资源变得更加简单。
String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
这个Xml配置文件包含了Mybatis系统的核心配置,包含了获取数据库连接(Connection)实例的数据源(DataSource)和决定事务范围和控制类(TransactionManager)。完整详细的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 resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>
当然还有很多可以在这xml文件配置,上面的例子指出了重要的配置部分。大家留意下xml文件的头,被用来校验xml文档使用。environment元素体包含事务管理和连接池的环境配置。mappers元素体包含了一系列mapper,这些mapper包含了xml文件或者其他Java接口类,它们包含了sql代码和映射定义。
不使用xml文件创建SqlSessionFactory
如果你宁愿直接使用Java代码,而不使用xml文件创建配置,或者创建你自己的配置构建器。Mybatis提供了一个完整的Configuration类,它提供了和xml文件相同的配置选项。
DataSource dataSource = BlogDataSourceFactory.getBlogDataSource(); TransactionFactory transactionFactory = new JdbcTransactionFactory(); Environment environment = new Environment("development", transactionFactory, dataSource); Configuration configuration = new Configuration(environment); configuration.addMapper(BlogMapper.class); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
注意这个例子,它的配置是添加一个mapper类。Mapper类是一个java类,它包含了sql映射注解,避免了使用xml文件配置。然而,由于Java注解的一些限制和一些复杂的Mybatis映射,对于一些高级映射(比如嵌套连接映射)xml映射依然是需要的。由于这个原因,Mybatis将自动查找和导入相同名字的xml文件的存在(在这个例子里,BlogMapper.xml文件将会被加载基于类路径和BlogMapper.class名称)。具体详细将在后面讲到。
从SqlSessionFactory获取SqlSession
现在你已经有了SqlSessionFactory实例,从它的名称上来看,你将可以从它那里获取SqlSession实例。SqlSession完全包含了数据库需要执行的sql命令的任何方法。你可以通过SqlSession直接执行已经映射的sql语句。如下例子
SqlSession session = sqlSessionFactory.openSession(); try { Blog blog = session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101); } finally { session.close(); }
虽然按这种方法处理,并且对于使用老版本Mybatis的用户来说,有一种更清晰的感觉。使用对于给定语句就可以正确描述参数和返回值的接口(例如BlogMapper.class),你将能执行清晰和类型安全的代码,没有错误的字符常量。
例子
SqlSession session = sqlSessionFactory.openSession(); try { BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = mapper.selectBlog(101); } finally { session.close(); }
现在让我们一起研究在这里是怎么正确执行的。
探索映射sql语句
到这里你可能会惊讶SqlSession或者Mapper类到底执行了什么。映射sql语句是一个很大的主题,它似乎占了文档的很大一部分。不过为了让你知道是怎么运行的,这里将给出两三个例子。
上面的任意例子,sql语句可以被定义在xml文件或者用注解来表示。让我们先来看看xml文件吧。Mybatis提供了一套基于xml文件的映射语言完整的功能,使得Mybatis流行了好长时间。如果你以前使用过Mybatis,那么你将会更加熟悉这些概念,然而在后来xml文档又有许多改进。这里使用一个基于映射语句的xml文件例子,将会满足上述SqlSession的调用。
<?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="org.mybatis.example.BlogMapper"> <select id="selectBlog" resultType="Blog"> select * from Blog where id = #{id} </select> </mapper>
虽然上面的例子看起来都非常简单,实际上它们是非常轻量级的。在一个mapper xml文件中,你想定义多少个映射语句都是可行的,这样xml头和文档声明就显得并不多。文件的剩余部分就更加明细了。在org.mybatis.example.BlogMapper命名空间下,定义了一个名为selectBlog的映射语句,这样就允许你叫它的完整名称org.mybatis.example.BlogMapper.selectBlog,就像我们下面例子做的一样。
Blog blog = session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
注意这可能和调用一个完整限定名Java类有些类似,这样做是有原因的。这名字可能被直接映射一个在命名空间中相同名字的Mapper类,方法将匹配名字,参数和返回类型在已映射的查询语句中。如上面,能够允许你非常简单的调用Mapper接口类的方法,不过这里我们将再来一个例子。
BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = mapper.selectBlog(101);
第二个方法将有一些优势。首先它不依赖字符变量,因此它更安全。其次如果你的IDE有代码补全功能,你将可以利用它在你的映射sql语句中。
提示:关于名称空间的提示
命名空间是可选的在旧版本的Mybatis,然而这些都会造成迷惑和无益的。现在的版本命名空间是要求必须的。
命名空间使得你看到的接口绑定,甚至尽管你今天不想这么做,但是你还是需要按规定约束来执行以防哪天你改变你的想法。使用命名空间,并将它放在你的合适的java包中,你的代码将会更加清晰整洁,并提高Mybatis的可用性。
名称解析:为了减少键盘频繁输入,Mybatis使用以下名称解析规则去解析所有的配置元素,包括语句,结果映射,缓存等等。
1.完整的限定名称(例如com.mypackage.MyMapper.selectAll)是可以直接查找和使用的。
2.简单名称(例如selectAll)可以被当作任何明确实体的引用,然而如果有两个或更多个该名称(例如com.foo.selectAll和com.bar.selectAll),那么你将会收到一个错误报告,说简单名称是不清晰,因此必须使用完整限定名称。
有一个或多个Mapper类像BlogMapper,它们的映射语句都不需要映射xml文件,它们将使用java注解,例如,上面的xml文件将被淘汰和替换。
package org.mybatis.example; public interface BlogMapper { @Select("SELECT * FROM blog WHERE id = #{id}") Blog selectBlog(int id); }
注解对于简单的语句来说是更加的简单清晰,然而Java注解对于复杂语句有限制并且会产生混乱。因此如果你需要一些负责的语句,你最好使用xml文件映射。
你的映射语句使用一致的的方法是非常重要的,并且它完全取决于你和你的团队。也就是说你不要局限于一种方法。你可以很简单的将注解的映射语句迁移到xml中。
范围和生命周期
去理解多种范围和生命周期类是非常重要的。使用它们错误可能会产生严重的并发问题。
提示:对象生命周期和依赖注入框架
依赖注入框架可以创建线程安全,事务处理SqlSessions ,直接映射和注入它们到你的bean中,因此你可以忘掉它们的声明周期。你可能需要看Mybatis-Spring 或者Mybatis-Guice子工程去了解更多关于Mybatis和依赖注入框架。
SqlSessionFactoryBuilder
该类会被实例化,使用和丢弃。一旦你创建了你的SqlSessionFactory,它将不需要保留下来。因此最好的范围是实例化SqlSessionFactoryBuilder的方法范围(比如一个本地方法变量)。你可以重复使用SqlSessionFactoryBuilder去建立多个SqlSessionFactory实例,但是最好是不需要保留下来,以确保所有的xml文件解析资源被释放并教给其他重要的事情。
SqlSessionFactory
一旦被创建,SqlSessionFactory就应该在你的应用程序执行期间存在。没有理由去清理或重建它。在一个应用程序运行期间不重建SqlSessionFactory多次是最好的做法。SqlSessionFactory的最好范围是应用程序范围。它可以从很多通过很多中方式来获得,最简单的是使用单例模式或者静态单例模式。
SqlSession
每个线程应该有他自己的SqlSession实例。SqlSession是不需要共享的并且是线程不安全的,因此最好的范围是请求范围或者方法范围。SqlSession实例的引用不能是一个静态的字段或者一个类的实例字段,SqlSession实例的引用不能放在任何管理范围中,像Servlet框架的HttpSession类。如果你是用一个web框架,应该考虑SqlSession在Http请求的相似范围中。换句话说,在接收一个Http请求,你可以打开一个SqlSession,然后返回一个响应,接着你将关掉SqlSession。关闭SqlSession是非常重要的,你应该一直确保它被关闭在finally代码块中。以下是确保SqlSession关闭的标准模式。
SqlSession session = sqlSessionFactory.openSession(); try { // do work } finally { session.close(); }在你的整个代码中使用一致的模式将能确保所有数据库资源被正确的关闭。
Mapper实例
Mappers是你创建去和你的映射语句绑定的接口类。mapper解耦的实例化是从SqlSession类获取。从技术上来看,任何mapper实例的最大范围是和SqlSession一样,因为他们都是都是被请求的。但是mapper实例最好的范围是方法范围,它们应该在被调用的方法中被请求,然后资源回收,他们不需要明确的去关闭。保持简单,最好包mapper放在方法范围,以下例子示范展示了这个实践。
SqlSession session = sqlSessionFactory.openSession(); try { BlogMapper mapper = session.getMapper(BlogMapper.class); // do work } finally { session.close(); }
突然发现官方已经有了中文文档,故而停止翻译
推荐阅读