可参考ibatis\doc\MyBatis-3-User-Guide-zh_CN.pdf
1.ibatis->mybatis介绍
MyBatis 是支持普通 SQL查询,存储过程等一个轻量级的ORM中间件。与传统的 JDBC 开发相比, MyBatis 消除了几乎所有的代码和参数的手工设置;MyBatis 使用简单的 XML 或注解方式,用于配置和原始映射,将接口和 Java 的POJOs(Plan Old Java Objects,普通的 Java对象)映射成数据库中的记录;
mybatis 与 hibernate 比较:
Hibernate基本上可以自动生成,其对数据库结构提供了较为完整的封装 ;开发效率上, 如果使用纯面向对象方式Hibernate 比较快,但如果以HQL其他方式相差不多;可维护性方面, mybatis框架是以sql的开发方式,可以进行细粒度的优化 ;Hibernate自动生成的sql效果不理想;MyBatis 是一个可以自定义SQL、存储过程和高级映射的持久层框架。MyBatis 摒除了大部分的JDBC代码、手工设置参数和结果集重获。MyBatis 只使用简单的XML 和注解来配置和映射基本数据类型、Map 接口和POJO 到数据库记录。相对Hibernate和Apache OJB等“一站式”ORM解决方案而言,Mybatis 是一种“半自动化”的ORM实现。
MyBatis的前身就是iBatis,iBatis本是apache的一个开源项目,2010年这个项目由apahce sofeware foundation 迁移到了google code,并且改名为MyBatis;
MyBatis是把实体类和sql语句之间建立了映射关系,而Hibernate在实体类和数据库之间建立了映射关系。
2.几个基本概念-
Model:java中一般叫entity POJO 里边主要是实体类 也就是对应数据库表中的类 每个表对应一个实体类 每个字段对应实体类中的一个属性
DAO:数据访问层 Mvc 结构编程中访问数据库的dao层提供数据持久化接口
3.mybatis-3.xjar(mybatis核心包)
mybatis-spring-1.x.jar(与Spring结合包)
总体来说 MyBatis 主要完成两件事情:
根据 JDBC 规范建立与数据库的连接;
通过Annotaion/XML+JAVA反射技术,实现 Java 对象与关系数据库之间相互转化
5.所有的MyBatis 应用都以SqlSessionFactory 实例为中心。SqlSessionFactory 实例通过SqlSessionFactoryBuilder 来获得,SqlSessionFactoryBuilder 能够从XML 配置文件或者通过自定义编写的配置类(Configuration class),来创建一个SqlSessionFactory 实例。
1.从XML 中创建SqlSessionFactory 实例
建议您使用类资源路径(classpathresource)来加载配置文件,但是您也能够使用任何方式,包括文本文件路径或者以file:// 开头URL 的方式。MyBatis 包括一个叫做Resources 的工具类(utility class),其中包含了一系列方法,使之能简单地从classpath 或其它地方加载配置文件。
String resource = "org/mybatis/example/Configuration.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlMapper = new SqlSessionFactoryBuilder().build(reader);
XML 配置文件包含MyBatis 框架的核心设置,包括获取数据库连接的DataSource 实例,和包括决定事务作用域范围和控制的事务管理等。
1<?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE configuration
3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-config.dtd">
5 <configuration>
6 <environments default="development">
7 <environment id="development">
8 <transactionManager type="JDBC"/>
9 <dataSource type="POOLED">
10 <property name="driver" value="${driver}"/>
11 <property name="url" value="${url}"/>
12 <property name="username" value="${username}"/>
13 <property name="password" value="${password}"/>
14 </dataSource>
15 </environment>
16 </environments>
17 <mappers>
18 <mapper resource="org/mybatis/example/BlogMapper.xml"/>
19 </mappers>
20 </configuration>
21
2.
MyBatis 提供了一个完整的配置类(Configuration class),它提供了与XML 文件相同的配置选项。
1TransactionFactory transactionFactory = new JdbcTransactionFactory();
2 Environment environment = new Environment("development", transactionFactory, dataSource);
3 Configuration configuration = new Configuration(environment);
4 configuration.addMapper(BlogMapper.class);
5 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
这种方式下的配置添加一个映射类(mapper class)。映射类是包含SQL 映射注解的Java 类,从而避免了使用XML。
3.
现在您已经创建了一个SqlSessionFactory(指上面的sqlMapper),正如它名字暗示那样,您可以通过它来创建一个SqlSession
实例。SqlSession 包含了所有执行数据库SQL 语句的方法。您能够直接地通过SqlSession 实例执行映射SQL 语句。例如:
1SqlSession session = sqlMapper.openSession();
2 try {
3 Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
4 }
5 finally
6 {
7 session.close();
8 }
现在有一个更简便的方式,那就是对给定的映射语句,使用一个正确描述参数与返回值的接口(如BlogMapper.class),您就能更清晰地执行类型安全的代码,从而避免错误和异常。
1 SqlSession session = sqlSessionFactory.openSession();
2 try {
3 BlogMapper mapper = session.getMapper(BlogMapper.class);
4 Blog blog = mapper.selectBlog(101);
5 } finally
6 {
7 session.close();
8 }
4.探索映射SQL 语句
上面的例子中,映射语句已经在XML 配置文件或注解中定义;,所有MyBatis 提供的功能特性都可以通过基于XML 映射配置文件 配置来实现
1<?xml version="1.0" encoding="UTF-8" ?>
2 <!DOCTYPE mapper
3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
5 <mapper namespace="org.mybatis.example.BlogMapper">
6 <select id="selectBlog" parameterType="int" resultType="Blog">//哈哈,参数类型,返回类型,就是一个方法
7 select * from Blog where id = #{id}
8 </select>
9 </mapper>
10
它定义了映射语句的名称“selectBlog”,在命名空间“org.mybatis.example.BlogMapper”,允许您通过指定完整类名“org.mybatis.example.BlogMapper”来访问上面的例子:
Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
这非常类似java 中通过完整类名来调用方法;这个名称可以直接映射到一个具在相同命名空间的映射类,这个映射类有一个方法的名称、参数及返回类型都与select映射语句相匹配。
BlogMapper mapper = session.getMapper(BlogMapper.class);
Blog blog = mapper.selectBlog(101);
第二种方法有很多好处。第一,它不依赖于字符串,所以更安全。第二,如果您的IDE 有自动完成功能,您可以利用这功能很快导航到您的映射SQL 语句。第三,您不需要关注返回类型,不需要进行强制转换,因为使用BlogMapper 接口已经限定了返回 类型,它会安全地返回;
对映射类还有一个更好的方法,就像前面的BlogMapper。它们的映射语句不需要完全在XML中配置。相反,它们可以使用Java 注解。例如上面的XML 配置可以替换为:
1 package org.mybatis.example;
2 public interface BlogMapper
3 {
4 @Select("SELECT * FROM blog WHERE id = #{id}")
5 Blog selectBlog(int id);
6 }
对简单的映射语句,使用注解可以显得非常地清晰。但是java 注解本身的局限难于应付更复杂的语句。如果您准备要做某些复杂的事情,最好使用XML 文件来配置映射语句。
5.作用域和生命周期
SqlSessionFactoryBuilder-一旦您创造了SqlSessionFactory 就不需要再保留它了。所以SqlSessionFactoryBuilder 实例的最好的作
用域是方法体内(即一个本地方法变量)SqlSessionFactory-一旦创建,SqlSessionFactory 将会存在于您的应用程序整个运行生命周期中;SqlSessionFactory 最好的作用
域范围是一个应用的生命周期范围;最简单的方式是使用Singleton 模式或静态Singleton 模式;,相反,您可能更愿意使用像Google Guice 或Spring 的依赖注入方式。这些框架允许您创造一个管理器,用于管理SqlSessionFactory 的生命周期SqlSession-每个线程都有一个SqlSession 实例,SqlSession 实例是不被共享的,并且不是线程安全的;因此最好的作用域是request 或者method。决不要用一个静态字段或者一个类的实例字段来保存SqlSession 实例引用
1SqlSession session = sqlSessionFactory.openSession();
2 try {
3 // do work
4 } finally
5 {
6 session.close();
7 }
使用这一模式将保证所有的数据库资源被正确地关闭
Mappers- 创建来绑定映射语句的接口,该Mapper 实例是从SqlSession 得到的。因此,所有mapper 实例的作用域跟创建它的SqlSession 一样。但是,mapper 实例最好的作用域是method,也就是它们应该在方法内被调用,使用完即被销毁;
1SqlSession session = sqlSessionFactory.openSession();
2 try {
3 BlogMapper mapper = session.getMapper(BlogMapper.class);
4 // do work
5 } finally
6 {session.close();}
6.Mapper XML 配置
MyBatis 的XML 配置文件包含了设置和影响MyBatis 行为的属性;下面为层次结构-
• configuration
o properties
o settings
o typeAliases
o typeHandlers
o objectFactory
o plugins
o environments
environment
• transactionManager
• dataSource
o mappers
1.properties 元素-可以配置在一个典型的Java 属性文件中,或者通过properties 元素的子元素进行配置;最优先的属性是通过方
法参数来传递的属性,然后是通过resource/url 配置的属性,最后是在MyBatis 的Mapper 配置文件中,properties 元素主体中
指定的属性。
2.Settings 元素-设置和改变MyBatis 运行中的行为,一个Settings 元素完整的配置例子如下:
1<settings>
2 <setting name="cacheEnabled" value="true"/>
3 <setting name="lazyLoadingEnabled" value="true"/>
4 <setting name="multipleResultSetsEnabled" value="true"/>
5 <setting name="useColumnLabel" value="true"/>
6 <setting name="useGeneratedKeys" value="false"/>
7 <setting name="enhancementEnabled" value="false"/>
8 <setting name="defaultExecutorType" value="SIMPLE"/>
9 <setting name="defaultStatementTimeout" value="25000"/>
10 </settings>
11
3.typeAliases 元素-别名是一个较短的Java 类型的名称。这只是与XML 配置文件相关联,减少输入多余的完整类
名;
1<typeAliases>
2 <typeAlias alias="Author" type="domain.blog.Author"/>
3 <typeAlias alias="Blog" type="domain.blog.Blog"/>
4 <typeAlias alias="Comment" type="domain.blog.Comment"/>
5 <typeAlias alias="Post" type="domain.blog.Post"/>
6 <typeAlias alias="Section" type="domain.blog.Section"/>
7 <typeAlias alias="Tag" type="domain.blog.Tag"/>
8 </typeAliases>
9
可以在想要使用"domain.blog.Blog"的地方使用别名“Blog”了;对常用的java 类型,已经内置了一些别名支持。这些别名都
是不区分大小写的。注意java的基本数据类型,它们进行了特别处理,加了“_”前缀。
4.typeHandlers 元素-当MyBatis 设置参数到PreparedStatement 或者从ResultSet 结果集中取得值时,就会使用TypeHandler 来处理
数据库类型与java 类型之间转;能够重写类型处理器(type handlers),或者创建您自己的类型处理器去处理没有被支持
的或非标准的类型。要做到这一点,只要实现TypeHandler 接口(org.mybatis.type),并且将您的TypeHandler 类映射到java 类型和可选的
JDBC 类型即可。
5.objectFactory 元素-MyBatis 每次创建一个结果对象实例都会使用ObjectFactory 实例。使用默认的ObjectFactory 与使用默认的
构造函数(或含参数的构造函数)来实例化目标类没什么差别。如果您想重写ObjectFactory 来改变其默认行为,那您能通
过创造您自己的ObjectFactory 来做到.->extends DefaultObjectFactory
6.Plugins 元素-MyBatis 允许您在映射语句执行的某些点拦截方法调用->implements Interceptor
7.Environments 元素-MyBatis 能够配置多套运行环境,这有助于将您的SQL 映射到多个数据库上;虽然您可以配置多个运行环
境,但是每个SqlSessionFactory 实例只能选择一个运行环境->每个数据库对应一个SqlSessionFactory 实例
1<environments default="development">
2 <environment id="development">
3 <transactionManager type="JDBC">//事务管理器
4 <property name="" value=""/>
5 </transactionManager>
6 <dataSource type="POOLED">//数据源
7 <property name="driver" value="${driver}"/>
8 <property name="url" value="${url}"/>
9 <property name="username" value="${username}"/>
10 <property name="password" value="${password}"/>
11 </dataSource>
12 </environment>
13 </environments>
7.1事务管理器-MyBatis 有两种事务管理类型(即type=”[JDBC|MANAGED]”);JDBC – 这个配置直接使用JDBC 的提交和 回滚功能。它依赖于从数据源获得连接来管理事务的生命周期;MANAGED – 这个配置基本上什么都不做。它从不提交或者回滚一个连接的事务。而是让容器(例如:Spring 或者J2EE 应用服务器)来管理事务的生命周期。
7.2dataSource 元素-dataSource 元素使用标准的JDBC 数据源接口来配置JDBC 连接对象源。
8.Mappers 元素-
现在,MyBatis 的行为属性都已经在上面的配置元素中配置好了,接下来开始定义映射SQL语句;首先,我们需要告诉MyBatis 在哪里能够找到我们定义的映射SQL 语句-可以使用类资源路径或者URL(包括file:/// URLs)
// Using classpath relative resources
1<mappers>
2 <mapper resource="org/mybatis/builder/AuthorMapper.xml"/>
3 <mapper resource="org/mybatis/builder/BlogMapper.xml"/>
4 </mappers>
5 // Using url fully qualified paths
6 <mappers>
7 <mapper url="file:///var/sqlmaps/AuthorMapper.xml"/>
8 <mapper url="file:///var/sqlmaps/BlogMapper.xml"/>
9 </mappers>
这些配置告诉MyBatis 在哪里找到SQL 映射文件。而其它的更详细的信息配置在每一个SQL映射文件里。
7.SQL 映射XML 文件
MyBatis 真正强大之处就在这些映射语句,也就是它的魔力所在。对于它的强大功能,SQL 映射文件的配置却非常简单。
如果您比较SQL 映射文件配置与JDBC 代码,您很快可以发现,使用SQL 映射文件配置可以节省95%的代码量。MyBatis 被创建来专注于SQL,但又给您自己的实现极大的空间。SQL 映射XML 文件只有一些基本的元素需要配置,并且要按照下面的顺序来定义:
• cache –在特定的命名空间配置缓存。
• cache-ref – 引用另外一个命名空间配置的缓存.
• resultMap – 最复杂也是最强大的元素,用来描述如何从数据库结果集里加载对象。
• sql – 能够被其它语句重用的SQL 块。
• insert –INSERT 映射语句
• update –UPDATE 映射语句
• delete –DELEETE 映射语句
• select –SELECT 映射语句
7.1Select 元素-
对简单的查询,select 元素的配置是相当简单的:
1<select id=”selectPerson” parameterType=”int” resultType=”hashmap”>
2 SELECT * FROM PERSON WHERE ID = #{id}
3 </select>
这条语句叫做selectPerson,以int 型(或者Integer 型)作为参数,并返回一个以数据库列名作为键值的HashMap。
#{id}-它告诉MyBatis 生成PreparedStatement 参数。对于JDBC,像这个参数会被标识为“?”;select 语句有很多的属性允许您详细配置每一条语句;如id,resultType,resultMap,statementType等。
7.2Insert、update、delete 元素
数据修改语句insert、update 和delete 的配置使用都非常相似:
useGeneratedKeys-仅限insert 语句时使用)告诉MyBatis 使用JDBC 的getGeneratedKeys 方法来获取数据库自动生成主键如:MySQL、SQLSERVER 等关系型数据库会有自增的字段)。默认:false
MyBatis 还有另外一种方式为不支持自动生成主键的数据库及JDBC 驱动来生成键值-><selectKey语句
7.3Sql 元素-这个元素用来定义能够被其它语句引用的可重用SQL 语句块
7.4参数(Parameters)使用#{}语法会促使MyBatis 生成PreparedStatement并且安全地设置PreparedStatement 参数(=?)值-
7.5resultMap 元素-resultMap元素是MyBatis中最重要最强大的元素;<resultMap
......详见文档
动态SQL-MyBatis 最强大的特性之一就是它的动态语句功能;
• if
• choose (when, otherwise)
• trim (where, set)
• foreach
if元素-动态SQL 最常做的事就是有条件地包括where 子句;
choose元素-有时候我们不想应用所有的条件,而是想从多个选项中选择一个。与java 中的switch 语句相似,MyBatis 提供了一个choose 元素。
trim, where, set 元素-here没有出现的时候,您可以自定一个。<where> where 元素知道插入“where”如果它包含的标签中有内容返回的话。此外,如果返回的内容以“AND” 或者“OR”开头,它会把“AND” 或者“OR”去掉。
<trim prefix="WHERE" prefixOverrides="AND |OR ">…</trim>;overrides属性使用了管道分隔的文本列表来覆写,而且它的空白也不能忽略的。这样的结果是移出了指定在overrides 属性里字符,而在开头插入prefix属性中指定的字符。
在动态update语句里相似的解决方式叫做set,这个set元素能够动态地更新列;set 元素将动态的配置SET 关键字,也用来剔除追加到条件末尾的任何不相关的逗号。等同
-<trim prefix="SET" suffixOverrides=",">…</trim>
Foreach 元素-另一个动态SQL 经常使用到的功能是集合迭代,通常用在IN 条件句
8.Java API
相比JDBC,MyBatis 极大地简化了您的代码,并使您的代码保持清晰、容易理解和维护。MyBatis3 推出了一系列重大的改进来使SQL 映射更好地工作。
mybatis典型应用目录结构-
/lib-MyBatis *.jar 文件存放在这里。
/src/...../data/..xml-MyBatis 物件放在这里。如: 映射器类(Mapper Classes), XML 配置文件, XML 映射文件。
/src/properties/- Properties 存放您自己的属性配置文件
1.SqlSessions-SqlSession 是与MyBatis 一起工作的基本java 接口。通过这个接口,您可以执行命令、获得映射和管理事;SqlSessions 是由SqlSessionFactory 实例创建的。SqlSessionFactory 包含从不同的方式创建SqlSessions 实例的方法。而SqlSessionFactory 又是SqlSessionFactoryBuilder 从XML 文件,注解或者手动编写java 配置代码中创建的。
1.1SqlSessionFactoryBuilder-SqlSessionFactoryBuilder 有五个build() 方法, 每个方法允许您从不同来源中创建SqlSession;
1SqlSessionFactory build(Reader reader)
2 SqlSessionFactory build(Reader reader, String environment)
3 SqlSessionFactory build(Reader reader, Properties properties)
4 SqlSessionFactory build(Reader reader, String env, Properties props)
5 SqlSessionFactory build(Configuration config)
6
前四个方法较为常用,它们使用一个引用XML 文件的Reader 实例,或者更具体地说是上面讨论的SqlMapConfig.xml 文件。
可选参数是environment 和properties。Environment 决定加载的环境(包括数据源和事务管理)。
如果您调用一个传递environment 参数的build 方法,MyBatis 将使用所传递的环境的配置。->default
如果您调用一个传递properties 实例的方法,MyBatis 将会加载传递进来的属性,并使这些属性在配置文件中生效。这些属
性能够应用于配置文件中使用${propName}语法的地方。
例子-
1String resource = "org/mybatis/builder/MapperConfig.xml";
2 Reader reader = Resources.getResourceAsReader(resource);
3 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
4 SqlSessionFactory factory = builder.build(reader);
注意,我们使用了Resources工具类,Resources工具类放在org.mybatis.io包中。Resources类,正如它的名字暗示,帮助我们
从类路径、文件系统或者WEB URL加载资源。
最后一个build 方法传递一个Configuration 的实例。Configuration 类包含您需要了解的关于SqlSessionFactory 实例的所有事
情。Configuration 类有您已经学过的所有配置开关,像java API 那样提供方法暴露出来。
DataSource/TransactionFactory/Environment/Configuration/Configuration.set...()....
1.2 SqlSessionFactory-SqlSessionFactory 有六个方法用来创建SqlSession 实例。在一般情况下,选择其中一个方法要考虑:
事务(Transaction)-您是否想为会话使用事务作用域,或者自动提交(通常是指数据库或者JDBC 驱动没有事务的情况下)
连接(Connection)-您想从配置数据源获得一个连接,还是想自己提供一个?
执行(Execution)-您想让MyBatis 重复使用用PreparedStatements 还是希望批量更新(包括插入和删除)?
1.3 SqlSession-正如前面提到的,SqlSession 实例是MyBatis 里最强大的类。SqlSession 实例里您会找到所有的执行语句、提交
或者回滚事务、获得mapper 实例的方法。
1.语句执行方法组(Statement Execution Methods)-这些方法用来执行定义在SQL 映射XML 文件中的select , insert,update
和delete 语句。它们都很好理解,执行时使用语句的ID 和并传入参数对象(基本类型,javaBean,POJO 或者Map)。
1Object selectOne(String statement, Object parameter)
2 List selectList(String statement, Object parameter)
3 int insert(String statement, Object parameter)
4 int update(String statement, Object parameter)
5 int delete(String statement, Object parameter)
6
2.事务控制方法组(Transaction Control Methods)-有四个控制事务作用域的方法,当然,如果您使用了自动提交或者正在使用的是外部事务管理器,那这四个方法就没什么作用。然而,如果您使用由Connection 实例管理的JDBC 的事务管理器,那这四个方法就非常管用:
1void commit()
2 void commit(boolean force)
3 void rollback()
4 void rollback(boolean force)
3.清除会话层缓存(Clearing the Session Level Cache)-void clearCache(),SqlSession 实例有一个本地缓存,这个缓存在每次提交,回滚和关闭时进行清除。如果不想在每次提交或者回滚时都清空缓存,可以明确地调用clearCache()方法来关闭
4.确保SqlSession 已经关闭(Ensuring that SqlSession is Closed)-void close();-try/finally
5.使用Mappers-<T> T getMapper(Class<T> type)-因此,一个最常用的方式是使用Mapper 接口来执行映射语句。一个Mapper 接口定义的方法要与SqlSession 执行的方法相匹配,即Mapper 接口方法名与映射SQL 文件中的映射语句ID 相同Mapper 注解-java 配置API 是基于XML 的MyBatis 配置的基础,同时也是基于注解的配置基础。注解提供了一个简单的方式来执行简单映射语句而不引入大量的开销。
注意: 很不幸,java 注解在表现力与灵活性上是有限的。尽管花了很多时间来研究,设计与试验,但是强大 的MyBatis 映射不能够建立在注解之上。C#属性则不会有这种限制。虽然如此,基于注解的配置并非没有好 处的。
2.SelectBuilder-Java 开发人员最讨厌的事情就是不得不在java 代码中嵌入SQL 语句。通常这样做的原因是SQL 必须动态生成,要 不然,您可以把SQL 定义在外部文件或者存储过程中。
SelectBuilder 使用一组静态导入方法和一个ThreadLocal 变量来启用一个能够很容易地组合条件并会注意所有SQL 格式的语法;概括地说,每一个SelectBuilder 方法都要以BEGIN()开头,以SQL()结束,这也是生成SQL 的范围。要像上面那样使用SelectBuilder 的方法,您简单地只要使用静态导入就可以了,如:
import static org.mybatis.jdbc.SelectBuilder.*;
一旦被导入,您就能够使用SelectBuilder 类的所有方法:BEGIN() / RESET()....SELECT(String)...WHERE(String)..SQL()
3.SqlBuilder-
与SelectBuilder类似,MyBatis 也包含了一个通用的SqlBuilder类,它包含了SelectBuilder的所有方法,同时也有一些针对inserts,
updates, 和deletes 的方法。这个类在DeleteProvider 、InsertProvider和UpdateProvider (以及SelectProvider )里生成SQL 语句
时非常有用。
import static org.mybatis.jdbc.SqlBuilder.*;
DELETE_FROM(String)....UPDATE(String)...
posted on 2011-12-26 22:38
landon 阅读(8046)
评论(0) 编辑 收藏 所属分类:
学习笔记