从昨天开始对mybatis突然有了很深的兴趣,主要原因在于这几天的项目采用的是smm,以后使用mybatis的概率也是非常大,抱着一劳永逸的想法,选了这几天的黄道吉日就把mybatis给办了吧。笔记主要参考mybatis的官网,在此给出链接,以防忘记:http://www.mybatis.org/mybatis-3/zh/getting-started.html.
一、maven依赖
maven中使用mybatis十分简单,只需要指定依赖即可,可以省去很多麻烦。maven是十分方便且简单的代码管理工具,可以省去很多找资源的时间,想起之前为了搭建ssh框架四处找依赖包,心疼自己一秒。比学习更重要的是眼界,使用一些有用的工具可以是开发效率事半功倍,以此为戒;
1 <dependency> 2 <groupId>org.mybatis</groupId> 3 <artifactId>mybatis</artifactId> 4 <version>x.x.x</version> 5 </dependency>
二、构造SqlSessionFactory
每个基于mybatis的应用都是以一个SqlSessionFactory的实例为中心的。通过SqlSessionFactory可以构造出Session,通过Session可以与后端数据库进行交互,因此SqlSessionFactory是业务逻辑与后端数据库进行沟通的关键桥梁。Session的生命周期较短,并且不安全,因此每个线程都应该有自己的SqlSession实例。SqlSssion的最佳作用域是请求或方法作用域。而SqlSessionFactory对于每次请求都要建立一个Sqlsession,因此SqlSessionFactory的生命周期应为应用的生命周期。SqlSessionFactory贯穿这个应用,因此构造SqlSessionFactory是一个关键所在。mybatis提供了两种构造途径。
1、通过xml构造SqlSessionFactory(推荐)
对于SqlSessionFactory的相关配置可以定义在mybatis-config.xml中,通过输入流(inputStream)可以读取文件中的内容。SqlSessionFactoryBuilder拥有一个静态方法build,接收一个输入流,并返回SqlSessionFactory。至此,SqlSessionFactoryBuilder完成任务,一般情况下SqlSessionFactoryBuilder只出现少数几次。
//mybatis-config.xml的一般配置
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configurationPUBLIC "-//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>
1 String resource = "org/mybatis/example/mybatis-config.xml"; 2 InputStream inputStream = Resources.getResourceAsStream(resource); 3 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
2、通过Java代码构建SqlSessionFactory(较少使用)
对于上面mybatis-config.xml文件中的配置,java都提供了相对于的类用于SqlSessionFactory的配置。很容易可以猜到,一个标签对应一个类,标签的包含关系对应于类的依赖关系。因此使用到的类主要有Configuration,Environment,TransactionFactory,Mapper以及DataSource。代码如下
1 DataSource dataSource = BlogDataSourceFactory.getBlogDataSource(); 2 TransactionFactory transactionFactory = new JdbcTransactionFactory(); 3 Environment environment = new Environment("development", transactionFactory, dataSource); 4 Configuration configuration = new Configuration(environment); 5 configuration.addMapper(BlogMapper.class); 6 SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);
三、SqlSession与Mapper
1、获取SqlSession。Sqlsession可以通过前面构建的SqlSessionFactory获得,调用openSession返回一个SqlSession类
SqlSession session = sqlSessionFactory.openSession(); try {Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101); } finally {session.close(); }
2、Mapper是Service层调用Dao层的接口,Mapper只是定义了一系列Service提供服务需要使用的接口,不参与接口的实现,Mapper接口的实现主要使用了mybatis的SQL功能,在mapper.xml中动态定义一些需要使用的SQL语句并执行。Mapper类有SqlSession获得,并完成对数据库的一次操作,具体如下:
SqlSession session = sqlSessionFactory.openSession(); try {BlogMapper mapper = session.getMapper(BlogMapper.class);Blog blog = mapper.selectBlog(101); } finally {session.close(); }
下面附上一个Mapper的简单例子,BlogMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapperPUBLIC "-//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>
3、作用域及生命周期
类的作用域与生命周期取决于类在应用的发挥的作用
3.1、SqlSessionFactoryBuilder,这个类可以被实例化,主要是为了通过配置构造SqlSessionFactory类,之后便没有什么作用。故生命周期应为方法作用域,只调用一次或少数几次,方法完成后自动销毁。
3.2、SqlSessionFactory,这个类在应用运行期间为每次请求分配一个Sqlsession进行处理,因为客户端请求在应用运行周期内都可能发生,故该类的生命周期应为应用的生命周期。一般来说,一个应用中值含有一个SqlSessionFactory。
3.3、SqlSession,这个类主要在一次请求中构造各个相关的Mapper来为请求服务,因此该类的生命周期为一次请求或者方法作用域。并且该类线程不安全,因此不能被共享,当请求完成响应,该类的一次实例的任务也便完成,故而应该关闭,减少数据库的开销。
3.4、Mapper,该类从SqlSession类中获得,为SqlSession类服务,故该类的生命周期不应大于SqlSession类的生命周期,一般Mapper放在方法作用域中,在调用它的方法中执行,方法结束便自动销毁。
四、XML映射配置文件
mybatis使用配置管理应用,是的配置信息与代码分开,便于修改以及扩展,十分方便。虽然现在注解越来越盛行,但xml配置的简单性,全局性的优点也是注解无法取代的。
mybatis-config.xml是mybatis的主要配置文件,配置项很多,但真正用到的却不多。官网下列出的配置项主要有如下几个
1、configuration 配置
1.1 properties
1.2 settings
1.3 typeAliases
1.4 typeHandlers
1.5 objectFactory
1.6 plugins
1.7 environments
1.8 databaseIdProvider
1.9 mappers
2、properties
定义了一些可外部配置且动态替换的属性,可以通过子元素的方式配置,也可以引入外部的properties文件。这些属性在整个配置文件中可被用来替换需要动态配置的属性值,类似于C语言中的宏,主要是为了方便修改以及统一配置。
<properties resource="org/mybatis/example/config.properties"><property name="username" value="dev_user"/><property name="password" value="F2Fa3!33TYyg"/> </properties>
<dataSource type="POOLED"><property name="driver" value="${driver}"/><property name="url" value="${url}"/><property name="username" value="${username}"/><property name="password" value="${password}"/> </dataSource>
值得注意的是,properties元素中指定的属性优先级最低。Mybatis中properties的加载顺序如下:
- 在 properties 元素体内指定的属性首先被读取。
- 然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
- 最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。
同时,在属性没有找到想要的属性值时,可以指定一个默认的属性值(默认冒号:后面为默认值),需要打开一个属性值并可以使用该特征
<properties resource="org/mybatis/example/config.properties"><!-- ... --><property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/> <!-- Enable this feature -->
</properties>
3、settings
该表现在的设置为mybatis的全局设置,可以改变mybatis的运行时行为,下面粘上经常使用的配置项,其他可以根据需要到官网查找
<settings><setting name="cacheEnabled" value="true"/><setting name="lazyLoadingEnabled" value="true"/><setting name="multipleResultSetsEnabled" value="true"/><setting name="useColumnLabel" value="true"/><setting name="useGeneratedKeys" value="false"/><setting name="autoMappingBehavior" value="PARTIAL"/><setting name="autoMappingUnknownColumnBehavior" value="WARNING"/><setting name="defaultExecutorType" value="SIMPLE"/><setting name="defaultStatementTimeout" value="25"/><setting name="defaultFetchSize" value="100"/><setting name="safeRowBoundsEnabled" value="false"/><setting name="mapUnderscoreToCamelCase" value="false"/><setting name="localCacheScope" value="SESSION"/><setting name="jdbcTypeForNull" value="OTHER"/><setting name="lazyLoadTriggerMethods" value="equals,clone,hashCode,toString"/> </settings>
4、typeAliases
从名字可以知道,该标签配置的是Java类型别名,主要作用是减少类完全限定名的冗余,对于常用的类名进行配置,可以带来很多方便,特别是在mapper.xml中时。下面附上一个使用的实例
<typeAliases><typeAlias alias="Author" type="domain.blog.Author"/><typeAlias alias="Blog" type="domain.blog.Blog"/><typeAlias alias="Comment" type="domain.blog.Comment"/><typeAlias alias="Post" type="domain.blog.Post"/><typeAlias alias="Section" type="domain.blog.Section"/><typeAlias alias="Tag" type="domain.blog.Tag"/>
<package name="domain.blog"/> </typeAliases>
配置上包名时,可以在类的上方使用@Alias(“别名”)注解添加别名,否则,会使用类的首字母小写的非限定类名作为别名,eg:
@Alias("author") public class Author {... }
5、mappers
该标签主要用于告诉mybatis去哪里寻找匹配的sql语句,通常使用类路径的资源引用,或者完全限定资源定位符,或者类名,及包名等。下面附上两种常用的方式:
<mappers><mapper resource="org/mybatis/builder/AuthorMapper.xml"/><mapper resource="org/mybatis/builder/BlogMapper.xml"/><mapper resource="org/mybatis/builder/PostMapper.xml"/> </mappers>
<!-- 将包内的映射器接口实现全部注册为映射器 -->
<mappers><package name="org.mybatis.builder"/>
</mappers>
6.environment
mybatis可以配置多种环境,有助于将SQL映射应用于多种数据库中。在mybatis-config.xml中可以配置多个environment,但是构造SqlSessionFactory时只能指定一种环境,可以通过SqlSessionFactory的构造函数传入使用的environment,否则使用默认的environment
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, properties); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader); SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, properties);
下面附上environments的一个实例
<environments default="development"><environment id="development"><transactionManager type="JDBC"><property name="..." value="..."/></transactionManager><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>