- 首先下载和搭建MyBatis的开发环境,打开链接https://github.com/mybatis/mybatis-3/releases
下载mybatis
对于MyBatis的包和源码,我们建议将包和源码都下载下来,对于mybatis的包,我们需要在工程路径下配置引入它。对于源码,我们在分析MyBatis运行原理时会用到。
使用mybatis还可以阅读相关的参考手册,网址是http://www.mybatis.org/mybatis-3/zh/getting-started.html
-解压Mybatis的包,可以得到如下图
使用MyEclipse环境进行配置,也可以使用包括NetBeans等开发环境,无论什么环境都可以轻松搭建。
-
右键项目名->properities->add external AJR找到解压后的mybatis的lib包还有mybatis-3.4.1.jar,全部加入即可搭建好MyBatis的开发环境
image.png
MyBatis的核心组件
SqlSessionFactoryBuider(构造器):它会根据配置 或者代码来生成SqlSessionFactory,采用的是分步构建的Builder模式
SqlSessionFactory(工厂方法):依靠它来生成Sqlsession,使用的是工厂模式
SqlSession(会话):一个既可以发送sql执行返回结果,也可以获取Mapper的接口。在现有的技术中,一般我们会让其在业务逻辑代码中“消失”,而使用的是MyBatis的提供的SQL Mapper接口的编程技术,它能提高代码的可读性,和可维护性
SQL Mapper(映射器):MyBatis 新设计存在的组件,它由一个java接口和XML文件构成,需要给出对应的SQL和映射规则则,它负责发送SQL执行,并返回结果
使用XML构建SqlSessionFactory
首先,在MyBatis的XML分为两类,一类是基础配置文件,通常是有一个,主要是配置一些最基本的上下文参数和运行环境;另一类是映射文件,它可以配置映射关系,SQL,参数等信息。先看一份简易的基础配置文件,我们把它命名为mybatis-config.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>
<typeAliases>
<typeAlias alias="role" type="com.learn.ssm.chapter3.pojo.Role" />
</typeAliases>
<!-- 数据库环境 -->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/ssm"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
</configuration>
我们描述一下MyBatis的配置文件:
<typeAlias>元素定义了一个别名role。它代表着com.learn.ssm.chapter3.oiji.Role这个类。这样定义后mybatis的上下文都可以使用别名代表全限定名。
<enviroment>元素的定义,这里采用描述的是描述库,它里面的<transactionManager>元素是配置事务管理器,这里采用的是MyBatis的JDBC管理器的方式
然后dataSource元素配置事务管理器,这里采用的是type=“POOLED”代表采用MyBatis内部提供的连接池方式,最后定义一些关于JDBC的属性信息。mapper 元素代表引入的那些映射器,在谈到映射器时会详细讨论它。
通过XML构建SqlSessionFactory
package com.learn.ssm.chapter3.mapper;
import java.io.IOException;
import java.io.InputStream;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
public class demoFactory{
public static void main(String[] args) {
SqlSessionFactory sqlSessionFactory=null;
String resource="mybatis-conifg.xml";
InputStream inputstream;
try{
inputstream=Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputstream);
}catch(IOException e){
e.printStackTrace();
}
}
}
首先读取mybatis-config.xml,然后通过SqlSessionFactoryBuilder的builer方法去创建SqlSessionFactory。整个过程比较简单,而里面的步骤还是比较繁琐,只是MyBatis采用了Builder模式为开发者隐藏这些细节。
采用XML创建的形式,信息在配置文件中,有利于以后的代码维护和修改。
补充:
- Resources
Resources 类为从类路径中加载资源,提供了易于使用的方法。处理 ClassLoader 是一项
富于挑战的工作,尤其是应用服务器/容器的情况下。
加载一个资源有很多方式,包括:
1.对于简单的只读文本数据,加载为 Reader。
Reader getResourceAsReader(String resource);
- 对于简单的只读二进制或文本数据,加载为 Stream。
Stream getResourceAsStream(String resource);
3.对于可读写的二进制或文本文件,加载为 File。
File getResourceAsFile(String resource);
- 对于只读的配置属性文件,加载为 Properties。
Properties getResourceAsProperties(String resource);
- 对于只读的通用资源,加载为 URL。
按以上的顺序,Resources 类加载资源的方法如下:
Url getResourceAsUrl(String resource);
SqlSession
在MyBatis中,SqlSession是其核心接口,在MyBatis中有两个实现类,DefaultSqlSession和SqlSessionManager,前者是单线程使用,后者是多线程使用。
SqlSession的作用类似一个JDBC中的connection对象,代表着一个连接资源的启用。
- 获取Mapper接口
- 发送SQL给数据库
- 控制数据库事务
创建SqlSessionFactory创建的SqlSession就十分简单
SqlSession sqlsession=SqlSessionFactory.openSession();
注意,SqlSession只是一个门面,它有很多方法,可以直接发送SQL,它就好像一家软件公司的商务人员,是一个门面,而实际干活的是软件工程师,在MyBatis中,真正干活的是Executor,我们会在底层看到它。
- Sqlsesssion控制数据库事务的方法
// 定义SqlSession
SqlSession sqlsession=null;
try{
// 打开SqlSession会话
sqlsession=sqlSessionFactory.openSession();
// some code
sqlsession.commit();
// 提交事务
}catch(Exception e){
sqlsession.rollback();
// 回滚事务
}
finally{
// 在finally语句中确保资源被关闭
if(sqlsession!=null){
sqlsession.close();
}
}
这里使用commit方法提交事务,或者使用rollback方法回滚事务,因为它代表着一个数据库的连接资源,使用后要及时关闭它,如果不关闭,那么数据库的连接资源就会很快被耗费光,整个系统就会被陷入崩溃煮状态、所以用finally的语句关闭。
由于SqlSession的获取Mapper接口和发送SQL功能需要先实现映射器的功能,而映射器接口也可以实现发送SQL功能,那么我们应该采取何种方式会更好一些。
映射器:
映射器是MyBatis的最重要的,最复杂的组件,它由一个接口和对用的XML文件(或注解)组成,它可以配置一下内容:
- 描述映射规则
- 提供SQL语句,并可以配置SQL参数类型,返回类型,缓存刷新等信息
- 配置缓存
- 提供动态SQL
本节阐述两种实现映射器的方式,XML文件形式和注解形式。
不过在此之前先定义一个POJO(简单JavaBean类)
package com.learn.ssm.chapter3.pojo;
public class Role {
private Long id;
private String roleName;
private String note;
/** setter and getter **/
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getRoleName() {
return roleName;
}
public void setRoleName(String roleName) {
this.roleName = roleName;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
}
映射器的主要作用就是将sql查询的结果映射到为一个POJO,或者POJO的数据插入到数据库中,并定义一些关于缓存的重要内容、
注意:开发只是一个接口,而不是一个实现类,接口不能直接运行,mybatis运用了动态代理技术使得接口能运行起来。
用XML实现映射器
public interface RoleMapper {
public Role getRole(Long id);
}
在用XML方式创建SqlSession的配置文件中有这样一段代码:
<mappers>
<mapper resource="org/mybatis/example/BlogMapper.xml"/>
</mappers>
它的作用就是引入一个xml文件,用xml方式创建映射器
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.learn.ssm.chapter3.mapper.RoleMapper">
<select id="getRole" parameterType="long" resultType="role">
select id,role_name as roleName,note from t_role where id=#{id}
</select>
</mapper>
- <mapper>元素中的属性namespace所对应的是一个接口的权限定名,于是mybatis可以通过上下文找到对用的接口、
- select元素表明这是一条查询语句,而属性id标识了这条SQL,属性parameterType=“long” 说明传递给SQL的是一个long类型的参数,而resultType=“role‘表明返回的是一个role类型的返回值,而role是之前配置文件mybatisconfig.xml配置的别名,指代的是com.learn.ssm.chapter3.pojo.Role
- 这条sql#{id}表示的是传递的参数
注意,我们并没有配置SQL执行后和role的对应关系,它是如何映射的呢?其实这里用的是一种被称为自动映射的功能,这里SQL返回的是列名id和name是可以和之前定义的POJO的属性POJO对应起来即可,而表里的列role_name通过SQL别名的改写,使其成为roleName,也是和POJO对应起来。所以此时的MyBatis就可以把SQL查询的结果通过自动映射的功能映射成为一个POJO
注解实现映射器
不同于xml实现注射器,注解方式之需要一个接口就可以通过MyBatis的注解来注入SQL
package com.learn.ssm.chapter3.mapper;
import org.apache.ibatis.annotations.Select;
import com.learn.ssm.chapter3.pojo.Role;
public interface RoleMapper2 {
@Select("select id,role_name as roleName,note from t_role wherer id=#{id}")
public Role getRole(Long id);
}
这完全等同于XML方式创建映射器,也许你会觉得使用注解的方式比XML方式要简单的多,如果它和XML方式同时定义,XML方式将覆盖掉注解的方式,因此使用官方的xml方式比较好。
XML可以相互使用,而注解是不可以的,所以在一些复杂的环境下,使用XML方式会更加的灵活和方便。
这个注解接口可以在mybatis-config.xmlz中进行配置:
mappers>
<mapper resource="com/learn/ssm/chapter3/mapper/RoleMapper.xml"/>
<!--构建SqlsessionFactory -->
<mapper class="com.learn.ssm.chapter3.mapper.RoleMapper2"/>
<!-- 注解实现映射器 -->
</mappers>
SqlSession发送sql
有了映射器就可以通过SqlSession发送SQL了,我们以getRole这条SQL为例看看如何发送SQL
Role role=(Role)sqlSession.selectOne("com.learn.ssm.chapter3.mapper.RoleMapper.getRole",1L)
常量后面跟这个一般是指类型,1L表示1是长整型,如果是1f 表示是float型
selectOne方法标识使用查询并且只返回一个对象,而参数则是一个String对象和一个Object对象,这里是一个long参数,long参数是它的主键。
String 对象是由一个命名空间加上SQL id组合而成的,它完全定位一条SQL ,这样MyBatis就会找到对应的SQL,如果在MyBatis中只有一个id为getRole的SQL,那么也可以简写成
Role role=()sqlsession.selectOne("getRole" ,1L);
用Mapper接口发送SQL
SqlSession还可以获取Mapper接口,通过Mapper接口发送SQL。
RoleMapper roleMapper=sqlSession.getMapper(RoleMapper.class)
Role role=roleMapper.getRole(1L)
通过SqlSession的getMapper方法来获取一个Mapper接口,就可以调用它的方法了,因为XML文件或者接口注解定义的SQL都可以通过“类的权限定名+方法名”查找。所以MyBatis会启用对应的SQL进行运行,并返回结果、
对比两种发送SQL的方式;
- 一种用的是SqlSession直接发送,另外一种通过SqlSession获取Mapper接口再发送。
建议大家使用SqlSession获取Mapper的方式,理由如下: - 使用Mapper接口编程可以消除SqlSession带来的功能性代码,提高可读性。而sqlsession发送SQL需要一个SQLID去配对SQL。使用Mapper接口,类似roleMapper.getRole(1L)则是完全面向对象的语言。
- 使用Mapper.getRole(1L)语法,IDE会提示错误和校验,而使用sqlSession.selectOne('getRole',1L)语法,只有在运行中才能知道是否会产生错误。