mybatis入门(一)

来源:互联网 发布:数据结构搜索算法 编辑:程序博客网 时间:2024/04/26 18:37

入门

安装

要使用MyBatis,只需要 在类路径中包含 mybatis-xxxjar文件即可。

如果您正在使用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配置文件或配置类的自定义准备实例中构建一个SqlSessionFactory实例。

从XML文件构建SqlSessionFactory实例非常简单。建议您为此配置使用类路径资源,但可以使用任何InputStream实例,包括从文本文件路径或file:// URL创建的实例。MyBatis包含一个名为Resources的实用程序类,其中包含许多方法,可以更简单地从类路径和其他位置加载资源。

String resource = "org/mybatis/example/mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resource);SqlSessionFactory sqlSessionFactory =  new SqlSessionFactoryBuilder().build(inputStream);

配置XML文件包含MyBatis系统核心的设置,包括用于获取数据库连接实例的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标头。环境元素的主体包含事务管理和连接池的环境配置。映射器元素包含映射器列表 - 包含SQL代码和映射定义的XML文件和/或带注释的Java接口类。

不使用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);

注意在这种情况下,配置是添加一个映射器类。映射器类是包含SQL映射批注的Java类,可以避免使用XML。但是,由于Java注释的某些限制以及某些MyBatis映射的复杂性,对于最高级的映射(例如嵌套连接映射),仍然需要XML映射。因此,如果MyBatis存在,MyBatis将自动查找并加载对等XML文件(在这种情况下,将根据BlogMapper.class的类路径和名称加载BlogMapper.xml)。稍后再说。

从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();}

现在让我们来探讨一下这里正在执行什么。

探索映射的SQL语句

此时,您可能会想知道SqlSession或Mapper类正在执行什么操作。映射SQL语句的主题是一个很大的话题,这个主题可能会占据这个文档的大部分。但为了让你知道究竟是什么运行,这里有几个例子。

在上面的任何一个例子中,这些语句都可以由XML或Annotations定义。先来看看XML。MyBatis提供的全套功能可以通过使用MyBatis多年来流行的基于XML的映射语言来实现。如果以前使用过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>

虽然这个简单的例子看起来像是一个很大的开销,但它实际上很轻。您可以在一个映射器XML文件中定义多个映射语句,所以您可以从XML头文件和doctype声明中获得很多里程碑。该文件的其余部分是相当自我解释。它在命名空间“org.mybatis.example.BlogMapper”中为映射语句“selectBlog”定义了一个名称,它允许您通过指定完全限定名称“org.mybatis.example.BlogMapper.selectBlog” ,正如我们在下面的例子中所做的那样:

Blog blog = session.selectOne(  "org.mybatis.example.BlogMapper.selectBlog", 101);

注意这与在完全限定的Java类上调用方法有多相似,这是有原因的。该名称可以直接映射到名称空间相同名称的Mapper类,并使用与映射的select语句匹配的名称,参数和返回类型。这可以让你非常简单地调用Mapper接口的方法,就像你在上面看到的一样,但是在下面的例子中也是这样:

BlogMapper mapper = session.getMapper(BlogMapper.class);Blog blog = mapper.selectBlog(101);

第二种方法有很多优点。首先,它不依赖于字符串,所以它更安全。其次,如果您的IDE具有代码完成功能,则可以在浏览映射的SQL语句时利用该功能。


 注意关于命名空间的注释

以前版本的MyBatis 命名空间是可选的,这是令人困惑和无益的。命名空间现在是必需的,除了简单地用更长的完全限定的名称隔离语句之外,还有一个目的。

命名空间可以像你在这里看到的那样启用接口绑定,即使你今天不认为你会使用它们,你也应该按照这里列出的这些实践来改变你的想法。使用命名空间一次,并将其放入适当的Java包名称空间将清理您的代码,并长期提高MyBatis的可用性。

名称解析:为了减少键入的数量,MyBatis对所有命名的配置元素使用以下名称解析规则,包括语句,结果映射,缓存等。

  • 如果找到完全限定名称(例如“com.mypackage.MyMapper.selectAllThings”),则直接查找并使用。
  • 短名称(例如“selectAllThings”)可用于引用任何明确的条目。但是,如果有两个或更多(例如“com.foo.selectAllThings和com.bar.selectAllThings”),那么您将收到一个错误报告,短名称是不明确的,因此必须是完全限定的。

像BlogMapper这样的Mapper类有更多的技巧。它们的映射语句根本不需要映射到XML。相反,他们可以使用Java注释。例如,上面的XML可以被删除并替换为:

package org.mybatis.example;public interface BlogMapper {  @Select("SELECT * FROM blog WHERE id = #{id}")  Blog selectBlog(int id);}

对于简单的语句来说,注释是非常干净的,但是,对于更复杂的语句,Java Annotations是有限的和混乱的。因此,如果你必须做任何复杂的事情,最好用XML映射语句。

这将取决于你和你的项目团队,以确定哪一个适合你,对你来说,对你的映射语句以一致的方式定义是多么重要。这就是说,你永远不会被锁定在一个单一的方法。您可以非常容易地将基于Annotation的映射语句迁移到XML,反之亦然。

范围和生命周期

了解到目前为止我们讨论的各种范围和生命周期类是非常重要的。错误地使用它们会导致严重的并发问题。


注意 对象生命周期和依赖注入框架

依赖注入框架可以创建线程安全的,事务性的SqlSession和映射器,并将它们直接注入到bean中,这样就可以忘记它们的生命周期。您可能想看看MyBatis-Spring或MyBatis-Guice子项目,以了解更多关于在DI框架中使用MyBatis的信息。


SqlSessionFactoryBuilder对象

这个类可以被实例化,使用和抛弃。一旦你创建了SqlSessionFactory,就不需要保留它。因此,SqlSessionFactoryBuilder实例的最佳范围是方法范围(即本地方法变量)。您可以重新使用SqlSessionFactoryBuilder来构建多个SqlSessionFactory实例,但最好不要保留它,以确保所有的XML解析资源都被释放出来以用于更重要的事情。

的SqlSessionFactory

一旦创建,SqlSessionFactory应该在应用程序执行期间存在。应该很少或根本没有理由去处理它或重新创建它。最好不要在应用程序运行中多次重建SqlSessionFactory。这样做应该被认为是“难闻的气味”。因此SqlSessionFactory的最佳范围是应用程序范围。这可以通过多种方式实现。最简单的是使用单例模式或静态单例模式。

SqlSession的

Each thread should have its own instance of SqlSession. Instances of SqlSession are not to be shared and are not thread safe. Therefore the best scope is request or method scope. Never keep references to a SqlSession instance in a static field or even an instance field of a class. Never keep references to a SqlSession in any sort of managed scope, such as HttpSession of the Servlet framework. If you're using a web framework of any sort, consider the SqlSession to follow a similar scope to that of an HTTP request. In other words, upon receiving an HTTP request, you can open a SqlSession, then upon returning the response, you can close it. Closing the session is very important. You should always ensure that it's closed within a finally block. The following is the standard pattern for ensuring that SqlSessions are closed:

SqlSession session = sqlSessionFactory.openSession();try {  // do work} finally {  session.close();}

在整个代码中始终使用此模式将确保所有数据库资源都正确关闭。

映射器实例

映射器是您创建的绑定到映射语句的接口。映射器接口的实例是从SqlSession中获取的。因此,从技术上来说,任何映射器实例的最广泛的范围与它们被请求的SqlSession相同。但是,映射器实例的最佳范围是方法范围。也就是说,他们应该在他们使用的方法中被请求,然后被丢弃。他们不需要明确关闭。虽然在整个请求中保留它们并不是一个问题,类似于SqlSession,但是您可能会发现管理这个级别的太多资源将很快失去控制。保持简单,将Mappers保留在方法范围内。

SqlSession session = sqlSessionFactory.openSession();try {  BlogMapper mapper = session.getMapper(BlogMapper.class);  // do work} finally {  session.close();}

原创粉丝点击