Contents
  1. 1. What is it?
  2. 2. Why we use it?
  3. 3. How to use it?

What is it?

MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis。是一个基于Java的持久层框架,无论是Mybatis、Hibernate都是ORM的一种实现框架,都是对JDBC的一种封装。

Why we use it?

对比一下我们在持久层学的几种技术

  • Hibernate:老旧的框架,不用涉及sql代码,但其缺点也比较明显,不能自己手动写sql语句,对于复杂业务处理时灵活度差,难理解
  • JDBC:数据获取映射存储几乎所有过程都需要开发人员去做。
  • Mybatis:半自动的ORM框架,开发人员既能接触sql语句,又不用手动处理处理实体与表的映射。

How to use it?

  1. 导入开发包

导入Mybatis开发包

  • mybatis-3.1.1.jar
  • commons-logging-1.1.1.jar
  • log4j-1.2.16.jar
  • cglib-2.2.2.jar
  • asm-3.3.1.jar

导入postgresql开发包

  • postgresql-9.3-1101.jdbc4.jar
  1. 创建数据表和对应实体

创建数据表

1
2
3
4
5
create table hospital(
id INT PRIMARY KEY,
name VARCHAR(10),
dataset int
);

创建实体

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
package job.offer.demo;

public class Hospital{
private int id;
private String name;
private int dataset;

public Hospital() {
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public int getDataset() {
return dataset;
}

public void setDataset(int dataset) {
this.dataset = dataset;
}
}
  1. Mybatis配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
<?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>

<!-- 加载类路径下的属性文件 -->
<properties resource="db.properties"/>

<!-- 设置一个默认的连接环境信息 -->
<environments default="mysql_developer">
<!-- 连接环境信息,取一个任意唯一的名字 -->
<environment id="mysql_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>

<!-- 连接环境信息,取一个任意唯一的名字 -->
<environment id="oracle_developer">
<!-- mybatis使用jdbc事务管理方式 -->
<transactionManager type="jdbc"/>
<!-- mybatis使用连接池方式来获取连接 -->
<dataSource type="pooled">
<!-- 配置与数据库交互的4个必要属性 -->
<property name="driver" value="${oracle.driver}"/>
<property name="url" value="${oracle.url}"/>
<property name="username" value="${oracle.username}"/>
<property name="password" value="${oracle.password}"/>
</dataSource>
</environment>
</environments>
</configuration>
  1. *测试是否获取到连接
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
package job.offer.demo;

import java.io.IOException;
import java.io.Reader;
import java.sql.Connection;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
* 工具类
* @author PatrickYoung
*/
public class MybatisUtil {
private static ThreadLocal<SqlSession> threadLocal = new ThreadLocal<SqlSession>();
private static SqlSessionFactory sqlSessionFactory;
/**
* 加载位于resources/mybatis-config.xml配置文件
*/
static{
try {
Reader reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 禁止外界通过new方法创建
*/
private MybatisUtil(){}
/**
* 获取SqlSession
*/
public static SqlSession getSqlSession(){
//从当前线程中获取SqlSession对象
SqlSession sqlSession = threadLocal.get();
//如果SqlSession对象为空
if(sqlSession == null){
//在SqlSessionFactory非空的情况下,获取SqlSession对象
sqlSession = sqlSessionFactory.openSession();
//将SqlSession对象与当前线程绑定在一起
threadLocal.set(sqlSession);
}
//返回SqlSession对象
return sqlSession;
}
/**
* 关闭SqlSession与当前线程分开
*/
public static void closeSqlSession(){
//从当前线程中获取SqlSession对象
SqlSession sqlSession = threadLocal.get();
//如果SqlSession对象非空
if(sqlSession != null){
//关闭SqlSession对象
sqlSession.close();
//分开当前线程与SqlSession对象的关系,目的是让GC尽早回收
threadLocal.remove();
}
}
/**
* 测试
*/
public static void main(String[] args) {
Connection conn = MybatisUtil.getSqlSession().getConnection();
System.out.println(conn!=null?"连接成功":"连接失败");
}
}
  1. 数据表与实体映射
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
<?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">

<!-- namespace属性是名称空间,必须唯一 -->
<mapper namespace="cn.javaee.mybatis.Student">

<!-- resultMap标签:映射实体与表
type属性:表示实体全路径名
id属性:为实体与表的映射取一个任意的唯一的名字
-->
<resultMap type="student" id="studentMap">
<!-- id标签:映射主键属性
result标签:映射非主键属性
property属性:实体的属性名
column属性:表的字段名
-->
<id property="id" column="id"/>
<result property="name" column="name"/>
<result property="dataset" column="dataset"/>
</resultMap>

</mapper>

在mybatis在配置文件中与映射文件关联起来

1
2
3
<mappers>
<mapper resource="job/offer/demo/HospitalMapper.xml"/>
</mappers>
  1. 编写DAO
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
public class HospitalDao {
public void selectList(){

//得到连接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
List<Hospital> list = sqlSession.selectList("hospitalList");
for (Hospital hospital:list){
System.out.println(hospital.getName());
}
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}
public void add(Hospital hospital){
//得到连接对象
SqlSession sqlSession = MybatisUtil.getSqlSession();
try{
//映射文件的命名空间.SQL片段的ID,就可以调用对应的映射文件中的SQL
sqlSession.insert("addHospital", hospital);
sqlSession.commit();
}catch(Exception e){
e.printStackTrace();
sqlSession.rollback();
throw e;
}finally{
MybatisUtil.closeSqlSession();
}
}

public static void main(String[] args) {
HospitalDao hospitalDao = new HospitalDao();
hospitalDao.selectList();
Hospital hospital = new Hospital(3, "上精卫", 2);
hospitalDao.add(hospital);
}
}

Mybatis中的事务是默认开启的,因此我们在完成操作以后,需要我们手动去提交事务!

1
2
3
4
5
6
<select id="hospitalList" resultType="job.offer.demo.Hospital">
select * from public.hospital;
</select>
<insert id="addHospital" parameterType="job.offer.demo.Hospital">
insert into public.hospital (id, name, dataset) values (#{id}, #{name}, #{dataset});
</insert>

在Mapper中配置对应sql语句,其他CURD类似操作即可。

7.MyBatis的工作流程

  • 通过Reader对象读取Mybatis映射文件
  • 通过SqlSessionFactoryBuilder对象创建SqlSessionFactory对象
  • 获取当前线程的SQLSession
  • 事务默认开启
  • 通过SQLSession读取映射文件中的操作编号,从而读取SQL语句
  • 提交事务
  • 关闭资源

关于Mybatis还有很多技术点,慢慢复习与总结。

Contents
  1. 1. What is it?
  2. 2. Why we use it?
  3. 3. How to use it?