MyBatis是另外一款优秀的ORM框架,前身为iBATIS。凡事预则立,不预则废。鉴于以后的项目可能会用到它,因此决定提前学习。本着分享和督促自己学习的目的,笔者将陆续把学习笔记贴出,希望对朋友们有所帮助。如前述博文所述,笔者将使用ant来管理工程。对ant不熟悉的朋友,请参考笔者的两篇预备篇博文:《ant的下载与安装——mybatis学习笔记之预备篇(一)》和《ant入门示例——mybatis学习笔记之预备篇(二)》。
本学习笔记以模拟学生选课管理为背景,以MySQL5.5作为数据库。创建数据库、用户、表以及用户授权的SQL脚本(courseman.sql)如下(在本文下方可下载附件,含本示例全部代码。):
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
|
/*数据库编码UTF8,以下命令是为了在脚本和
命令行中支持中文*/
set
names gbk;
/*创建courseman数据库*/
drop
database
if exists courseman;
create
database
courseman;
/*切换到courseman数据库*/
use courseman;
/*创建学生表*/
CREATE
TABLE
student(
id
int
NOT
NULL
AUTO_INCREMENT primarykey,
name
varchar
(10)
NOT
NULL
,/*姓名*/
gender
char
(1)
NOT
NULL
,/*性别*/
major
varchar
(20)
NOT
NULL
,/*专业*/
grade
char
(4)
NOT
NULL
/*年级*/
);
/*授予courseman用户访问courseman数据库的全部权限。
为方便起见,用户名与数据库同名。该用户若不存在则被
创建,密码为abc123*/
grant
all
privileges
on
courseman.*
to
courseman@
'%'
identified
by
'abc123'
;
flush
privileges
;
/*添加第一条记录*/
insert
into
student(
name
, gender, major, grade)
values
(
'李林'
,
'男'
,
'计算机科学与技术'
,
'2011'
);
|
在命令行下以root用户登录(mysql –uroot -p),用source命令运行此脚本(假如此脚本在D盘下,即d:\courseman.sql,则运行命令:source d:/courseman.sql。注意,这里是“/”,而不是“\”)。
本示例的任务是根据学生的ID读取学生信息。
笔者在自己机器上的E:\DemoPrograms目录下新建目录MyBatis01,用来存放本示例的工程。按照ant工程常见的组织形式,生成文件build.xml存放在此目录下,另外建立两个目录:src(存放源代码和配置文件)lib(存放jar包),而classes目录让ant帮我们创建。将本次要用到的jar包复制到lib目录下(分别为mybatis的mybatis-3.0.6.jar和MySQL的JDBC驱动包mysql-connector-java-5.1.20-bin.jar)。
在src目录下新建resources目录,用来保存相关的配置文件。之后,我们将要求ant把此目录复制到classes目录下。由于classes目录会被ant添加到类路径中,因此MyBatis可以访问到这些配置文件。其中核心配置文件configuration.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
|
<?
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
>
<!--表明重用预编译的SQL语句-->
<
settings
>
<
setting
name
=
"defaultExecutorType"
value
=
"REUSE"
/>
</
settings
>
<!--类型别名定义。今后可只用Student来代替它冗长的
全限定名-->
<
typeAliases
>
<
typeAlias
alias
=
"Student"
type
=
"com.abc.domain.Student"
/>
</
typeAliases
>
<!--environments可包含多个environment元素。
每个environment配置与数据库交互的细节,这里
只需要配置一个。default属性是指在创建SqlSessionFactory
时,若没有明确指定要用哪个environment,则使用此
属性指定的-->
<
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/courseman"
/>
<
property
name
=
"username"
value
=
"courseman"
/>
<
property
name
=
"password"
value
=
"abc123"
/>
</
dataSource
>
</
environment
>
</
environments
>
<!--指定要用到的mapper文件。以下的resource属性告诉
MyBatis要在类路径下的resources目录下找StudentMapper.xml文件。我们将把mapper文件存放在src目录下的resources目录中,并让ant把resources目录拷贝到classes中,而classes目录会被ant添加到类路径中。-->
<
mappers
>
<
mapper
resource
=
"resources/StudentMapper.xml"
/>
</
mappers
>
</
configuration
>
|
(注:我在configuartion.xml和下面的StudentMapper.xml中添加中文注释后报“Invalid byte 1 of 1-byte UTF-8 sequence.”错误,不知为何。有知道的朋友望告知。因此需要本示例代码的朋友不要复制这两个文件的代码,在本文下方下载附件即可。附件可直接运行。)
此配置文件很简单,这也体现了笔者一向的原则:从最简单的开始。其实有部分知识不太理解也属正常,慢慢用多了自然就理解了,熟悉了,这符合一般的学习规律。相信包括笔者在内的学习者,都是这种情况。
接着编写学生类,这是一个普通的java bean。代码如下:
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
|
package
com.abc.domain;
public
class
Student {
private
int
id;
private
String name;
//姓名
private
String gender;
//性别
private
String major;
//专业
private
String grade;
//年级
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
String getGender() {
return
gender;
}
public
void
setGender(String gender) {
this
.gender = gender;
}
public
String getMajor() {
return
major;
}
public
void
setMajor(String major) {
this
.major = major;
}
public
String getGrade() {
return
grade;
}
public
void
setGrade(String grade) {
this
.grade = grade;
}
}
|
按照包的层次结构,在src目录下建立子目录层次com\abc\domain,然后把Student.java存放于此。
MyBatis需要我们提供一个接口,在接口中声明访问数据库的方法。因此,编写接口StudentMapper.java如下:
1
2
3
4
5
6
|
package
com.abc.mapper;
import
com.abc.domain.Student;
public
interface
StudentMapper {
//根据学生ID查询学生实体
public
Student getById(
int
id);
}
|
类似地,将此文件放置在src目录下的com\abc\mapper目录下。
现在编写上面提到的mapper文件StudentMapper.xml。在此文件里,我们写好查询的SQL语句,并配置好映射关系。内容如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
|
<?
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该是StudentMapper的完整限定名-->
<
mapper
namespace
=
"com.abc.mapper.StudentMapper"
>
<!--定义java bean的属性与数据库表的列之间的映射。type="Student"用到了configuration.xml中定义的别名-->
<
resultMap
id
=
"studentResultMap"
type
=
"Student"
>
<!--id映射-->
<
id
property
=
"id"
column
=
"id"
/>
<!--普通属性映射-->
<
result
property
=
"name"
column
=
"name"
/>
<
result
property
=
"gender"
column
=
"gender"
/>
<
result
property
=
"major"
column
=
"major"
/>
<
result
property
=
"grade"
column
=
"grade"
/>
</
resultMap
>
<!--与StudentMapper接口中的getById方法对应,包括
方法名和参数类型。SQL语句中以“#{}”的形式引用参数-->
<
select
id
=
"getById"
parameterType
=
"int"
resultMap
=
"studentResultMap"
>
SELECT *
FROM student WHERE id = #{id}
</
select
>
</
mapper
>
|
MyBatis将根据此文件帮我们实现StudentMapper接口。下面编写TestMyBatis.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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
|
package
com.test;
import
java.io.IOException;
import
java.io.Reader;
import
org.apache.ibatis.io.Resources;
import
org.apache.ibatis.session.SqlSessionFactory;
import
org.apache.ibatis.session.SqlSessionFactoryBuilder;
import
org.apache.ibatis.session.SqlSession;
import
org.apache.ibatis.session.SqlSessionFactory;
import
com.abc.mapper.StudentMapper;
import
com.abc.domain.Student;
public
class
TestMyBatis
{
public
static
void
main(String[] args)
{
//与configuration.xml中的mapper配置类似,告诉MyBatis
//应读取的核心配置文件
String resource =
"resources/configuration.xml"
;
Reader reader =
null
;
try
{
reader = Resources.getResourceAsReader(resource);
}
catch
(IOException e)
{
e.printStackTrace();
}
//创建SqlSessionFactory实例。没有指定要用到的
//environment,则使用默认的environment
SqlSessionFactory sqlSessionFactory
=
new
SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = sqlSessionFactory.openSession();
try
{
StudentMapper mapper =
sqlSession.getMapper(StudentMapper.
class
);
Student student = mapper.getById(
1
);
if
(student !=
null
)
{
System.out.println(
"姓名: "
+student.getName()
+
"\n专业: "
+student.getMajor());
}
else
{
System.out.println(
"没有找到。"
);
}
}
finally
{
sqlSession.close();
}
}
}
|
在命令窗口进入E:\DemoPrograms\MyBatis01目录,运行命令:ant run。则运行结果如下: