目录
MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache软件基金会迁移到了google代码,并且改名为MyBatis。2013年11月迁移到Github。
iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架.iBATIS提供的持久层框架包括SQL地图和数据访问对象(DAO)。
MyBatis是支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBatis使用简单的XML或注解用于配置和原始映射,将接口和Java的POJO(普通Java对象,普通Java对象)映射成数据库中的记录。
PS:本文所有代码下载链接:http ://pan.baidu.com/s/1gf8CPQN密码:t2x9
①,创建MySQL的数据库:mybatisDemo和表:人
1
2
3
|
create database mybatisDemo;
use mybatisDemo;
create table person(pid
int
primary key AUTO_INCREMENT, pname varchar(
50
), page
int
);
|
②,建立一个Java的工程,并导入相应的JAR包
相应的jar包下载链接:http ://pan.baidu.com/s/1skZM09Z密码:nkt6
③,在MyBatisDemo工程中添加数据库配置文件mybatis-configuration.xml
1
2
3
4
五
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
|
④、定义表所对应的实体类
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
|
package
com.ys.bean;
public
class
Person {
private
int
pid;
private
String pname;
private
int
page;
public
int
getPid() {
return
pid;
}
public
void
setPid(
int
pid) {
this
.pid = pid;
}
public
String getPname() {
return
pname;
}
public
void
setPname(String pname) {
this
.pname = pname;
}
public
int
getPage() {
return
page;
}
public
void
setPage(
int
page) {
this
.page = page;
}
@Override
public
String toString() {
return
"Person [pid="
+ pid +
", pname="
+ pname +
", page="
+ page
+
"]"
;
}
}
|
⑤、定义操作 person 表的sql映射文件personMapper.xml
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
|
PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"
>
resultType=
"com.ys.bean.Person"
parameterType=
"int"
>
select * from person where pid = #{pid}
select * from person
update person set pname=#{pname},page=#{page} where pid = #{pid}
insert into person(pid,pname,page) values(#{pid},#{pname},#{page})
delete from person where pid=#{pid}
|
⑥、向 mybatis-configuration.xml 配置文件中注册 personMapper.xml 文件
1
2
3
4
5
|
|
如下图所示:
⑦、创建测试类
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
package
com.ys.test;
import
java.io.InputStream;
import
java.util.List;
import
org.apache.ibatis.session.SqlSession;
import
org.apache.ibatis.session.SqlSessionFactory;
import
org.apache.ibatis.session.SqlSessionFactoryBuilder;
import
org.junit.Before;
import
org.junit.Test;
import
com.ys.bean.Person;
public
class
MyBatisTest {
SqlSession session;
@Before
public
void
beforeLoadXML(){
//加载 mybatis 配置文件
InputStream inputStream = MyBatisTest.
class
.
getClassLoader().getResourceAsStream(
"mybatis-configuration.xml"
);
//构建sqlSession的工厂
SqlSessionFactory sqlSessionFactory =
new
SqlSessionFactoryBuilder().build(inputStream);
//根据 sqlSessionFactory 产生 session
session = sqlSessionFactory.openSession();
}
//根据 pid 查询 person 表中的数据
@Test
public
void
testSelectById(){
//这个字符串有 personMapper.xml 文件中 两个部分构成
//
//
String statement =
"com.ys.bean.personMapper"
+
".selectPersonById"
;
Person p = session.selectOne(statement,
1
);
System.out.println(p);
session.close();
}
//查询person 表所有数据
@Test
public
void
testGetAllPerson(){
String statement =
"com.ys.bean.personMapper.getAllPerson"
;
List
System.out.println(listPerson);
session.close();
}
//根据id更新数据
@Test
public
void
updateById(){
String statement =
"com.ys.bean.personMapper.updatePersonById"
;
Person p =
new
Person();
p.setPid(
1
);
p.setPname(
"aaa"
);
p.setPage(
11
);
session.update(statement, p);
session.commit();
session.close();
}
//向 person 表插入一条数据
@Test
public
void
addPerson(){
String statement =
"com.ys.bean.personMapper.addPerson"
;
Person p =
new
Person();
//由于我们设置了主键的自增长机制,故这里不需要手动设置 pid 的值
//p.setPid(1);
p.setPname(
"add"
);
p.setPage(
11
);
session.insert(statement, p);
session.commit();
session.close();
}
//根据 pid 删除person 表中的数据
@Test
public
void
deletePersonById(){
String statement =
"com.ys.bean.personMapper.deletePersonById"
;
session.delete(statement,
1
);
session.commit();
session.close();
}
}
|
①、上面的前面四步都是一样的,但是第五步不一样,我们不需要创建 personMapper.xml 文件,首先在 src 目录下创建 personMapper.java 文件
内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
|
package
com.ys.annocation;
import
org.apache.ibatis.annotations.Delete;
import
org.apache.ibatis.annotations.Insert;
import
org.apache.ibatis.annotations.Select;
import
org.apache.ibatis.annotations.Update;
import
com.ys.bean.Person;
public
interface
PersonMapper {
@Insert
(
"insert into person(pid,pname,page) values(#{pid},#{pname},#{page})"
)
public
int
add(Person person);
@Select
(
"select * from person where pid = #{pid}"
)
public
Person getPerson(
int
pid);
@Update
(
"update person set pname=#{pname},page=#{page} where pid = #{pid}"
)
public
int
updatePerson(Person preson);
@Delete
(
"delete from person where pid=#{pid}"
)
public
int
deletePerson(
int
pid);
}
|
②、向 mybatis-configuration.xml 配置文件中注册 personMapper.xml 文件
③、编写测试类
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
|
@Test
public
void
testAnnocation(){
PersonMapper mapper = session.getMapper(PersonMapper.
class
);
Person p =
new
Person();
p.setPid(
7
);
p.setPname(
"abc"
);
p.setPage(
11
);
//调用增加方法
mapper.add(p);
//调用查询方法
Person p1 = mapper.getPerson(
3
);
System.out.println(p1);
//调用更新方法
p.setPage(
100
);
mapper.updatePerson(p);
//调用删除方法
mapper.deletePerson(
7
);
session.commit();
session.close();
}
|
这里我们以老师和班级为例,假设一般班级只能拥有有一个老师,一个老师只能带一个班级。
①、创建实体类
Teacher.java
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
|
package
one.to.one;
public
class
Teacher {
private
int
tid;
private
String tname;
private
Classes classes;
public
int
getTid() {
return
tid;
}
public
void
setTid(
int
tid) {
this
.tid = tid;
}
public
String getTname() {
return
tname;
}
public
void
setTname(String tname) {
this
.tname = tname;
}
public
Classes getClasses() {
return
classes;
}
public
void
setClasses(Classes classes) {
this
.classes = classes;
}
@Override
public
String toString() {
return
"Teacher [tid="
+ tid +
", tname="
+ tname +
", classes="
+ classes +
"]"
;
}
}
|
Classes.java
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
|
package
one.to.one;
public
class
Classes {
private
int
cid;
private
String cname;
private
Teacher teacher;
public
int
getCid() {
return
cid;
}
public
void
setCid(
int
cid) {
this
.cid = cid;
}
public
String getCname() {
return
cname;
}
public
void
setCname(String cname) {
this
.cname = cname;
}
public
Teacher getTeacher() {
return
teacher;
}
public
void
setTeacher(Teacher teacher) {
this
.teacher = teacher;
}
@Override
public
String toString() {
return
"Classes [cid="
+ cid +
", cname="
+ cname +
", teacher="
+ teacher +
"]"
;
}
}
|
②、在数据库中根据实体类创建相应的数据表
③、定义操作 Classes 表的sql映射文件classesMapper.xml
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
|
PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"
>
select * from classes c ,teacher t
where c.tid=t.tid and c.tid=#{tid}
select * from teacher t,classes c
where t.cid = c.cid and t.cid=#{cid}
select * from classes c where c.cid = #{cid}
select tid tid,tname tname from teacher where tid=#{tid}
|
说明:我们这里一对一的关联操作,有两种方式:
1、使用嵌套结果映射来处理重复的联合结果的子集
2、通过执行另外一个SQL映射语句来返回预期的复杂类型
相关属性解释:
④、向 mybatis-configuration.xml 配置文件中注册 classesMapper.xml 文件
⑤、编写测试类
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
|
package
one.to.one;
import
java.io.InputStream;
import
org.apache.ibatis.session.SqlSession;
import
org.apache.ibatis.session.SqlSessionFactory;
import
org.apache.ibatis.session.SqlSessionFactoryBuilder;
import
org.junit.Before;
import
org.junit.Test;
import
com.ys.test.MyBatisTest;
public
class
OneToOneTest {
SqlSession session;
@Before
public
void
beforeLoadXML(){
//加载 mybatis 配置文件
InputStream inputStream = MyBatisTest.
class
.
getClassLoader().getResourceAsStream(
"mybatis-configuration.xml"
);
//构建sqlSession的工厂
SqlSessionFactory sqlSessionFactory =
new
SqlSessionFactoryBuilder().build(inputStream);
//根据 sqlSessionFactory 产生 session
session = sqlSessionFactory.openSession();
}
//一对一嵌套结果方式:根据教师id查询班级信息
@Test
public
void
testGetClasses(){
String statement =
"one.to.one.classesMapper.getClasses"
;
Classes c = session.selectOne(statement,
1
);
System.out.println(c);
}
//一对一嵌套结果方式:根据班级id查询教师信息
@Test
public
void
testGetTeacher(){
String statement =
"one.to.one.classesMapper.getTeacher"
;
Teacher t = session.selectOne(statement,
1
);
System.out.println(t);
}
//一对一嵌套查询方式:根据教师id查询班级信息
@Test
public
void
testGetClasses2(){
String statement =
"one.to.one.classesMapper.getClasses2"
;
Classes c = session.selectOne(statement,
1
);
System.out.println(c);
}
}
|
这里我们以班级和学生为例,一个班级里面对应多个学生,这是一对多;反过来,多个学生对应一个班级,这是多对一
①、建立学生和班级的实体类
Student.java
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
|
package
one.to.many;
public
class
Student {
private
int
sid;
private
String sname;
private
Classes classes;
public
int
getSid() {
return
sid;
}
public
void
setSid(
int
sid) {
this
.sid = sid;
}
public
String getSname() {
return
sname;
}
public
void
setSname(String sname) {
this
.sname = sname;
}
public
Classes getClasses() {
return
classes;
}
public
void
setClasses(Classes classes) {
this
.classes = classes;
}
@Override
public
String toString() {
return
"Student [sid="
+ sid +
", sname="
+ sname +
", classes="
+ classes +
"]"
;
}
}
|
Classes.java
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
|
package
one.to.many;
import
java.util.Set;
public
class
Classes {
private
int
cid;
private
String cname;
private
Set
public
int
getCid() {
return
cid;
}
public
void
setCid(
int
cid) {
this
.cid = cid;
}
public
String getCname() {
return
cname;
}
public
void
setCname(String cname) {
this
.cname = cname;
}
public
Set
return
students;
}
public
void
setStudents(Set
this
.students = students;
}
@Override
public
String toString() {
return
"Classes [cid="
+ cid +
", cname="
+ cname +
", students="
+ students +
"]"
;
}
}
|
②、在数据库中根据实体类创建相应的数据表
③、多对一:定义操作 Classes 表的sql映射文件classesMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"
>
select * from classes c,student s where s.cid=c.cid and c.cid=#{cid}
|
④、一对多:定义操作 Student 表的sql映射文件studentMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
|
PUBLIC
"-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd"
>
select * from classes c,student s where s.cid=c.cid and s.sid=#{sid}
|
⑤、向 mybatis-configuration.xml 配置文件中注册 classesMapper.xml 、studentMapper.xml文件
⑥、编写测试类
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
|
package
one.to.many;
import
java.io.InputStream;
import
org.apache.ibatis.session.SqlSession;
import
org.apache.ibatis.session.SqlSessionFactory;
import
org.apache.ibatis.session.SqlSessionFactoryBuilder;
import
org.junit.Before;
import
org.junit.Test;
import
com.ys.test.MyBatisTest;
public
class
OneToManyTest {
SqlSession session;
@Before
public
void
beforeLoadXML(){
//加载 mybatis 配置文件
InputStream inputStream = MyBatisTest.
class
.
getClassLoader().getResourceAsStream(
"mybatis-configuration.xml"
);
//构建sqlSession的工厂
SqlSessionFactory sqlSessionFactory =
new
SqlSessionFactoryBuilder().build(inputStream);
//根据 sqlSessionFactory 产生 session
session = sqlSessionFactory.openSession();
}
//一对多嵌套结果方式:根据班级id查询班级所有的学生信息
@Test
public
void
testGetClasses(){
String statement =
"one.to.many.classesMapper.getClasses"
;
Classes c = session.selectOne(statement,
1
);
System.out.println(c);
System.out.println(c.getStudents().size());
}
//多对一嵌套结果方式:根据学生id查询班级信息
@Test
public
void
testGetStudents(){
String statement =
"many.to.one.studentMapper.getStudents"
;
Student s = session.selectOne(statement,
1
);
System.out.println(s);
System.out.println(s.getClasses());
}
}
|
这里我们以 users 表和 groups 表为例,一个 users 可能加入多个 groups,而一个 groups 可能包含多个 users,故构成 多对多 的关联
①、在数据库中建立相应的表
users 表
groups 表
两者之间的关联表users_groups表
②、建立对应的实体类
Users.java
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
|
package
many.to.many;
import
java.util.Set;
public
class
Users {
private
int
uid;
private
String uname;
private
Set
public
int
getUid() {
return
uid;
}
public
void
setUid(
int
uid) {
this
.uid = uid;
}
public
String getUname() {
return
uname;
}
public
void
setUname(String uname) {
this
.uname = uname;
}
public
Set
return
groups;
}
public
void
setGroups(Set
this
.groups = groups;
}
@Override
public
String toString() {
return
"User [uid="
+ uid +
", uname="
+ uname +
", groups="
+ groups +
"]"
;
}
}
|
Groups.java
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
|
package
many.to.many;
import
java.util.Set;
public
class
Groups {
private
int
gid;
private
String gname;
private
Set
public
int
getGid() {
return
gid;
}
public
void
setGid(
int
gid) {
this
.gid = gid;
}
public
String getGname() {
return
gname;
}
public
void
setGname(String gname) {
this
.gname = gname;
}
public
Set
return
users;
}
public
void
setUsers(Set
|