1.安装
1)安装需要的jar包(mybatis-x.x.x.jar)
2)maven安装只需要添加以下依赖到你的pom.xml文件种即可
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency>
2.创建SqlsessionFactory用xml的方式
每一个mybatis应用中心都是围绕一个SqlsessionFactory实例的。SqlsessionFactory的实例是由SqlsessionFactoryBuilder获得的。SqlsessionFactoryBuilder可以用xml配置文件的方式来获取SqlsessionFactory实例,也可以用自定义配置类来获取SqlsessionFactory实例。
用xml配置文件的方式来获取SqlsessionFactory是非常简单的。推荐的一种方式是:在classpath resources下配置,然后用InputStream实例去读取到配置文件。mybatis有一个公用的类Resources,用它可以很简单的去加载资源文件(基本上就是配置文件)。
具体的例子如下:
String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
xml配置文件里面核心的配置包括:关于连接数据库的数据源,还有事务管理,以及事务如何去控制。具体详细的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 resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>
xml文件配置还有很多,以上例子只是给出了最关键的部分。值得注意的是,需要用xml头去说明是xml文档。
environment元素里面包含了事务管理以及连接池配置。mappers元素里面是mapper的列表,包含sql代码和mapping定义的列表
3.不用xml的方式创建SqlsessionFactory
mybatis提供直接用实现配置类去创建SqlsessionFactory,如下:
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类是包含sql映射注解的java类,可以避免用xml文件。然而,考虑到java注解的局限性和一些比较复杂的mybatis映射,一些高级映射还是需要xml映射(比如,嵌套映射)。由于这个原因,如果xml文件存在的话,mybatis会自动加载相应的xml文件。详细的后续再讲。
4.从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(); }
虽然,对于那些熟悉以前版本的用户来说这个方法是可以执行的,但是,现在有更加简洁的方式。使用一个已有的正确声明参数和返回值的接口,可以去执行更简洁,更安全地代码,而不用去关心容易出错的字符串类型转换错误。举个例子:
SqlSession session = sqlSessionFactory.openSession(); try { BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = mapper.selectBlog(101); } finally { session.close(); }
让我们来看下执行完成之后会有什么结果。
5.探索映射的sql语句
此时,你可能想知道sqlsession或者mapper类到底执行了什么。映射sql语句是一个很重要的主题,在文档中我们也会着重介绍。为了让你知道到底执行了什么,可以参考下一下几个例子。
在上面的例子中,mapper定义可以通过xml或者java注解的方式定义。首先看下xml方式,过去几年xml方式去实现mybatis非常流行,几乎所有的mybatis功能都可以通过基于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="org.mybatis.example.BlogMapper"> <select id="selectBlog" resultType="Blog"> select * from Blog where id = #{id} </select> </mapper>
虽然这个例子看起来有很多开销,但是实际上它是非常轻量级的。你可以在一个消灭了文件中定义很多个映射语句,从而你可以从xml文件头和doctype声明中获得很多好处。文件剩下的部分还是很好理解的。它定义了一个名字叫"selectBlog"的映射语句,命名空间为"
org.mybatis.example.BlogMapper",这将允许你通过完全限定名称"org.mybatis.example.BlogMapper"去调用,正如下面的例子一样:
Blog blog = session.selectOne( "org.mybatis.example.BlogMapper.selectBlog", 101);
注意,这个跟java调用方法的方式是一模一样的,这个是有原因的。mybatis会直接映射到对应命名空间的Mapper类中的这个方法,以及映射对应方法的参数和返回值。这样允许你非常简单的去调用Mapper接口提供的方法,还有一种调用方法如下所示:
BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = mapper.selectBlog(101);
上面的这个例子具有很多优点。首先,你不需要拼接字符串,所以是更加安全的;其次,如果你的ide有代码补全功能,你可以在寻找你的映射sql时利用它。
说明:关于命名空间的说明
命名空间:在之前的mybatis版本中,命名空间时可选的,这即混乱有没有意义。mybatis现在规定需要命名空间,需要提供更长的,更加完整的命名空间。
命名空间可以去绑定对应的接口,即使你现在不打算使用,为了以后可能用到,你也应该遵循这个习惯。一旦你使用了命名空间,并且将其放入你的java包中,这样可以使你的代码更见简洁,可用性更高。
名称解析:为了减少类型,mybatis在所有的配置元素中使用了名称解析规则,包括sql语句,result map,caches等。
-全名称(比如:"com.mypackage.MyMapper.selectAllThings")如果找到的话,会直接使用。
-短名称(比如:"selectAllThings")可以用来引用任何明确的条目。然而,如果项目中有两个或者更多(比如:"com.foo.selectAllThings和com.bar.selectAllThings"),这样的话mybatis会报错:the short name is ambiguous and therefore must be fully qualified
像BlogMapper这样的映射类还有一个技巧。映射语句不需要任何xml,取而代之的时java注解。举个例子,上面的xml可以抛弃掉,用以下代码取代:
package org.mybatis.example; public interface BlogMapper { @Select("SELECT * FROM blog WHERE id = #{id}") Blog selectBlog(int id); }
注解对于简单的映射语句来说更简单,然而,对于复杂的映射语句来说,java注解既有局限性并且很混乱。因此,如果要用复杂的映射语句的话,你最好还是选择xml映射语句。
用那种方式去映射取决于你和你的团队,还有一致的映射语句对你来说有多重要。也就是说,你不能局限于一种映射方式,你要做到的是两种方式切换自如。
6.作用域和生命周期
了解到目前为止我们讨论过的类的作用于和生命周期是非常重要的。如果使用不当,会造成严重的并发问题。
1)注意:对象的声明周期和依赖注入框架
依赖注入框架可以帮你创建一个线程安全,事务管理的sqlsession以及mapper,并且将他们注入javabean中,所以你可以完全不用管他们的生命周期。你可以看看Mybatis-Spring或者Mybatis-Guice的子项目去了解更多依赖注入框架使用Mybatis的信息。
2)SqlsessionFactoryBuilder
这个类可以被实例化,使用和丢弃。一旦你创建了SqlsessionFactory就不需要保留它了。因此,SqlSessionFactoryBuilder最佳的作用域就是方法作用域(即局部方法变量)。你当然可以重复使用它创建多个SqlSessionFactory实例,但是最好不要保留它,以确保为更重要的使用释放所有的xml资源
3)SqlSessionFactory
一旦创建,SqlSessionFactory应该存在于你的程序执行所有时间。没有必要去重复创建或者销毁。在程序运行期间,最好不要多次去创建SqlSessionFactory,这种使用方式是一种不好的习惯。因此,SqlSessionFactory的作用域应该是应用程序作用域。可以通过很多方式去实现,最简单的方式就是,单例模式或者是静态单例模式。
4)SqlSession
每一个线程都应该有一个属于他自己的Sqlsession。Sqlsession是不能被很多线程使用的,是线程不安全的。因此,最佳的作用域就是Request或者方法作用域。永远不要在静态字段或者类实例字段中保留对Sqlsession实例的引用。不要在任何托管范围内保留对Sqlsession的保留,比如Servle框架中的Httpsession。如果你正在使用任何类型的web框架,请参考使用http请求类似的Sqlsession作用域。换句话说,在接收到HTTP请求时,可以打开Sqlsession,然后在返回响应时,关闭它。关闭Sqlsession是非常重要的。你必须经常检查以确保它在finally块中关闭。如下就是正确关闭sqlsession的标准方式:
SqlSession session = sqlSessionFactory.openSession(); try { // do work } finally { session.close(); }
在整个代码中,用这种一致的模式去确保所有数据库资源都被正确关闭。
5)Mapper实例
Mappers是你所有创建去绑定你映射语句的接口。这个实例是要通过sqlsession获取。因此,任何mapper实例的作用域与请求它们的Sqlsession相同。so,mapper实例的作用最好是方法作用域。也就是说,他们应该在被使用的方法内请求,然后被丢弃。不需要显示的去关闭。虽然在整个请求过程中保留他们(就像sqlsession)并不是问题,但是你可能会发现在这个级别管理太多的资源很快会失控。简单起见,mappers作用域定义为方法作用域。参考下面的例子:
SqlSession session = sqlSessionFactory.openSession(); try { BlogMapper mapper = session.getMapper(BlogMapper.class); // do work } finally { session.close(); }