30分钟入门MyBatis
本文旨在用最通俗的语言讲述最枯燥的基本知识
西湖网站建设公司创新互联公司,西湖网站设计制作,有大型网站制作公司丰富经验。已为西湖成百上千提供企业网站建设服务。企业网站搭建\成都外贸网站制作要多少钱,请找那个售后服务好的西湖做网站的公司定做!
当项目框架SSH(spring、Struts、Hibernate)日落西山时,SSM(spring、SpringMVC、MyBatis)就大行其道,大部分项目都渐渐转至SSM,因此 MyBatis 也成了Java程序员的必学知识,本文就mybatis的语法做一次小小的总结,旨在让读者用最少的时间学会使用MyBatis。
文章提纲:
什么是MyBatis
MyBatis的引入
MyBatis的配置
MyBatis的SQL语法
运行原理和实操一波
1. 什么是MyBatis
MyBatis的前身是Apache的一个开源项目ibatis,后来迁移到Google code就改名为MyBatis。
用网上已经说烂了的话来说就是:
MyBatis是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
2. MyBatis的引入
如果是传统的的项目,则直接下载相应jar包引入到项目中即可,下载地址为:
1
http://central.maven.org/maven2/org/mybatis/mybatis/3.4.6/mybatis-3.4.6.jar
如果为maven构建的项目,则只需要在pom.xml中加入以下依赖然后reimport一下即可:
1
<
dependency
>
2
<
groupId
>
org.mybatis
groupId
>
3
<
artifactId
>
mybatis
artifactId
>
4
<
version
>
x.x.x
version
>
5
dependency
>
如果是gradle构建的项目,则只需要在配置中添加以下代码:
1
// https://mvnrepository.com/artifact/org.mybatis/mybatis
2
compile group: 'org.mybatis', name: 'mybatis', version: '3.4.6'
3. MyBatis的配置和初始化
在引入mybatis之后,接下来需要学习的mybatis的配置,虽然现在流行的框架像springboot等已经不需要用XML方式进行配置,但作为一名新手,我们还是需要学习一些关于mybatis的配置的解释,这样有助于我们理解mybatis的原理。
mybatis的基本配置:
1
2
3
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
4
<
configuration
>
5
6
<
properties
>
7
8
<
property
name
=
"driver"
value
=
"com.MySQL.cj.jdbc.Driver"
>
property
>
9
<
property
name
=
"url"
value
=
"jdbc:mysql://rm-wz9b714vle01fg8ijmo.mysql.rds.aliyuncs.com/change_hair"
>
property
>
10
properties
>
11
12
<
environments
default
=
"development"
>
13
14
<
environment
id
=
"development"
>
15
<
transactionManager
type
=
"JDBC"
/>
16
<
dataSource
type
=
"POOLED"
>
17
<
property
name
=
"driver"
value
=
"${driver}"
/>
18
<
property
name
=
"url"
value
=
"${url}"
/>
19
<
property
name
=
"username"
value
=
"root"
/>
20
<
property
name
=
"password"
value
=
"Blackeye100"
/>
21
dataSource
>
22
environment
>
23
environments
>
24
25
<
mappers
>
26
27
<
mapper
resource
=
"mapper/UserMapper.xml"
/>
28
mappers
>
29
configuration
>
这是一个标准的mybatis的配置文件,很多情况下,这个配置已经足够,但是为了在以后的使用有更好的认识,下面讲解配置文件中configuration标签下的常用子标签:
properties标签:用于定义一些通用属性,便于配置文件中使用
settings标签:用于设置一些改变MyBatis运行时行为的配置
environments标签:用于配置成适应多种环境
mappers标签:用于mapper映射器的设置
下面分别对每个标签做简单讲解:
1.properties标签
当我们需要把一些值作为一个变量被配置中使用时,就可以在properties标签下增加一个property标签,其中属性name是指变量名称,属性value是值,如:
1
<
properties
>
2
<
property
name
=
"driver"
value
=
"com.mysql.cj.jdbc.Driver"
>
property
>
3
property
>
定义好之后,就可以在配置文件中使用了,如:
1
<
dataSource
type
=
"POOLED"
>
2
<
property
name
=
"driver"
value
=
"${driver}"
/>
3
dataSource
>
2.settings标签
settings标签中的每一个setting都是用于调整mybatis的运行行为,我们在需要使用其中某些setting时加入即可,其常用的配置以及各个setting的解释如下:
1
<
settings
>
2
#设置配置文件中的所有映射器已经配置的任何缓存,默认false。
3
<
setting
name
=
"cacheEnabled"
value
=
"true"
/>
4
#延迟加载的全局开关。当开启时,所有关联对象都会延迟加载,默认为false
5
<
setting
name
=
"lazyLoadingEnabled"
value
=
"true"
/>
6
#是否允许单一语句返回多结果集,默认为true
7
<
setting
name
=
"multipleResultSetsEnabled"
value
=
"true"
/>
8
#是否使用列标签代替列名,默认为true
9
<
setting
name
=
"useColumnLabel"
value
=
"true"
/>
10
#是否允许JDBC支持自动生成主键,默认为false
11
<
setting
name
=
"useGeneratedKeys"
value
=
"false"
/>
12
#指定 MyBatis 应如何自动映射列到字段或属性
13
<
setting
name
=
"autoMappingBehavior"
value
=
"PARTIAL"
/>
14
#指定发现自动映射目标未知列(或者未知属性类型)的行为,默认NONE
15
#NONE: 不做任何反应
16
#WARNING: 输出提醒日志
17
#FAILING: 映射失败 (抛出 SqlSessionException)
18
<
setting
name
=
"autoMappingUnknownColumnBehavior"
value
=
"WARNING"
/>
19
#配置默认的执行器。默认为SIMPLE
20
#SIMPLE 就是普通的执行器;
21
#REUSE 执行器会重用预处理语句;
22
#BATCH 执行器将重用语句并执行批量更新
23
<
setting
name
=
"defaultExecutorType"
value
=
"SIMPLE"
/>
24
#设置超时时间,它决定驱动等待数据库响应的秒数。
25
<
setting
name
=
"defaultStatementTimeout"
value
=
"25"
/>
26
#为驱动的结果集获取数量(fetchSize)设置一个提示值
27
<
setting
name
=
"defaultFetchSize"
value
=
"100"
/>
28
#是否允许在嵌套语句中使用分页。如果允许使用则设置为false。
29
<
setting
name
=
"safeRowBoundsEnabled"
value
=
"false"
/>
30
#是否开启自动驼峰命名规则(camel case)映射,默认为false
31
<
setting
name
=
"mapUnderscoreToCamelCase"
value
=
"false"
/>
32
settings
>
3. environments
environments是为了配置多环境数据源而生,在我们定义好了各种环境之后,只需要在代码中设置从哪个环境中加载数据源即可,或者修改environments标签中的default也可以达到切换环境的效果。
environments的基本配置如下:
1
<
environments
default
=
"development"
>
2
#定义一个名称为development的环境配置
3
<
environment
id
=
"development"
>
4
#设置事务管理器的类型,有JDBC和MANAGED梁总
5
<
transactionManager
type
=
"JDBC"
>
6
<
property
name
=
"..."
value
=
"..."
/>
7
transactionManager
>
8
#数据源设置
9
<
dataSource
type
=
"POOLED"
>
10
<
property
name
=
"driver"
value
=
"${driver}"
/>
11
<
property
name
=
"url"
value
=
"${url}"
/>
12
<
property
name
=
"username"
value
=
"${username}"
/>
13
<
property
name
=
"password"
value
=
"${password}"
/>
14
dataSource
>
15
environment
>
16
environments
>
当我们需要增加一个环境配置时,只需要复制粘贴一份environment,修改其中属性的值即可。
4.mappers
mappers标签实际上是用于高速mybatis从哪找到我们写好的SQL语句,也就是映射文件。当我们写好一个表对应的mapper.xml时,我们只需要在mappers下增加一个mapper即可。
mappers查找mapper的方式有多种:
1. 根据mapper.xml文件定位:
这些mapper.xml在resources中的某个文件夹xxx中,则用resource属性设置
1
<
mappers
>
2
<
mapper
resource
=
"xxx/AMapper.xml"
/>
3
<
mapper
resource
=
"xxx/BMapper.xml"
/>
4
mappers
>
2. 根据映射器接口实现类的完全限定类名:
当我们在这些mapper.xml设置好了namespace之后,我们可以通过映射器接口实现类的全路径类来设置,如在AMapper.xml设置namespace为com.xxx.dao.AMapper类之后,我们在这里可以使用class属性指定查找的mapper,但前提是:
AMapper.xml和AMapper.java必须在同一个包下。
1
<
mappers
>
2
<
mapper
class
=
"com.xxx.dao.AMapper"
/>
3
<
mapper
class
=
"com.xxx.dao.BMapper"
/>
4
mappers
>
3. 包映射
有人会说,如果我们表有很多,这样一行一行的写不是很费劲吗,mybatis为了便于使用,提供了package的方式引入映射器,但前提
所有的mapper.xml和mapper.java必须在同一个包下。
1
<
mappers
>
2
<
package
name
=
"org.xxx.dao"
/>
3
mappers
>
4. URL映射:
如果你的mapper不在项目中,而是放到了其他文件内,mybatis提供了通过URL的方式引入mapper.xml。
1
<
mappers
>
2
<
mapper
url
=
"C:///test/mappers/AMapper.xml"
/>
3
<
mapper
url
=
"C:///test/mappers/BMapper.xml"
/>
4
mappers
>
5. MyBatis的SQL语法
在现有的框架下编写代码,多数情况下都不需要理会mybatis底层的东西,而大量的工作都集中在编写mapper文件上。因此学会在mybatis下编写SQL语句是非常有必要的,我们首先来看一个标准的mapper文件的格式:
1
2
3
<
mapper
namespace
=
"com.xxx.dao.XxxMapper"
>
4
mapper
>
可以看出,一个mapper文件的根结构是mapper标签开始,而mapper标签中的namespace有什么用呢?他应该怎么写?
我们知道,有一种编程思想叫做面向接口编程,就是把业务需求中具体逻辑实现和接口分开,对外只暴露接口,通过接口实现业务。而在业务需求变化时,仅需要修改实现类,而不需要变动现有的对接代码,降低对系统的影响。
而mybatis正是基于这样的思想,在namespace中指定该mapper对应的接口之后,不需要编写接口实现类,mybatis会通过该绑定自动帮你找到对应要执行的SQL语句。
如:在com.xxx.dao中创建一个XxxMapper.java的接口,需要编写一根据用户查询用户信息的方法。
1
package
com.xxx.dao;
2
public
interface
XxxMapper
{
3
//根据姓名查询一条用户信息
4
Map
selectUserByName
(@Param(
"name"
)
String name)
;
5
}
此时我们就可以在mapper.xml中设置namespace对应到上面的接口来:
1
2
3
<
mapper
namespace
=
"com.xxx.dao.XxxMapper"
>
4
<
select
id
=
"selectUserByName"
parameterType
=
"String"
resultType
=
"hashmap"
>
5
select * from user where name = #{name}
6
select
>
7
mapper
>
而在具体的业务实现类中,则是这样使用的:
1
@Service
2
public
class
XxxServiceImpl
implements
CustomerInfoService
{
3
@Resource
4
private
XxxMapper xxxMapper=
null
;
5
@Override
6
public
Map
getUser
(String name)
{
7
return
xxxMapper.selectUserByName(name);
8
}
9
}
可以看出,从编写SQL语句到最终业务调用SQL语句的过程中,我们并没有给XxxMapper接口编写任何的实现类,这就是基于接口编程的思想,mybatis已经把这些事情都处理好了,我们只需要在namespace中把SQL映射文件和接口类对应起来,就可以使用了。
知道根节点mapper怎么设置之后,接下来我们需要学习如何在mapper节点里编写SQL语句,在mapper标签后,mybatis提供了很多语义化的标签以便于我们编写SQL语句和配置映射文件,下面是几个非常常用子标签:
1. select:用于编写查询语句的标签
2. update:用于编写update语句的标签
3. insert:用于编写insert语句的标签
4. delete:用于编写delete语句的标签
5. sql:编写语句块的标签,可被其它语句引用
6. resultMap:定义数据库结果和实体属性的映射关系
这些标签都是我们在编写SQL语句中的必备标签,下面一一描述他们的使用。
1. select标签
在一个项目中,大部分功能都涉及到查询,因此mybatis也为select元素配备了非常多的属性,一下仅列出最常用的几个属性以及作用解释:
1
<
select
2
#必填,唯一标识符,和
mapper
接口中的方法一一对应
3
id
=
"selectUser"
4
#选填,默认值为
unset
,用于传入参数的类型设置
5
parameterType
=
"String"
6
#选填,语句查询结果返回的期望类型,
resultType
和
resultMap
不能同时使用
7
resultType
=
"HashMap"
8
#选填,语句查询结果返回的数据集,可以对应实体类和和
resultMap
定义的
ID
。
9
resultMap
=
"com.xxx.entity.User"
10
#是否清除缓存,为
true
时本地缓存和二级缓存都会被清除
11
flushCache
=
"false"
12
#是否启用缓存,为
true
时查询结果会被放入二级缓存
13
useCache
=
"true"
>
14
15
#SQL语句编写....
16
17
select
>
2. update标签
1
<
update
2
#必填,唯一标识符,和
mapper
接口中的方法一一对应
3
id
=
"updateUser"
4
#选填,默认值为
unset
,用于传入参数的类型设置
5
parameterType
=
"com.xxx.entity.User"
6
#是否清除缓存,为
true
时本地缓存和二级缓存都会被清除
7
flushCache
=
"true"
>
8
9
#编写update的SQL语句...
10
11
update
>
3. insert标签
1
<
insert
2
#必填,唯一标识符,和
mapper
接口中的方法一一对应
3
id
=
"updateUser"
4
#选填,默认值为
unset
,用于传入参数的类型设置
5
parameterType
=
"com.xxx.entity.User"
6
#是否清除缓存,为
true
时本地缓存和二级缓存都会被清除
7
flushCache
=
"true"
8
#是否取出由数据库内部生成的主键,默认为
false
9
useGeneratedKeys
=
"false"
10
#选填,设置了之后,会通过
getGeneratedKeys
的返回值或者通过
insert
语句的
selectKey
子元素设置它的键值。
11
keyProperty
=
"id"
12
>
13
14
#编写insert的SQL语句...
15
16
insert
>
4. delete标签
1
<
delete
2
#必填,唯一标识符,和
mapper
接口中的方法一一对应
3
id
=
"updateUser"
4
#选填,默认值为
unset
,用于传入参数的类型设置
5
parameterType
=
"com.xxx.entity.User"
6
#是否清除缓存,为
true
时本地缓存和二级缓存都会被清除
7
flushCache
=
"true"
>
8
9
#编写delete的SQL语句...
10
11
delete
>
5. sql标签
SQL节点用来编写那些可以被重用的SQL代码段,当我们用SQL编写好一个代码段之后,就可以在其他语句使用。
我们都知道,在写满了SQL之后,如果要修改表名,是一件很痛苦的事情,因为表名都写到了SQL语句中了,但是在mybatis中,我们可以利用sql标签来定义好表名,如果在所有的SQL中引入这个代码块即可:
1
<
sql
id
=
"TABLE_NAME"
>
user
sql
>
2
3
#在语句中用include的方式把表名动态化
4
<
select
id
=
"selectUserByName"
>
5
select * from
6
<
include
refid
=
"TABLE_NAME"
/>
7
where name = #{name}
8
select
>
类似的用法还有非常多,比如把查询字段一致的可以用sql块统一定义,然后在需要的地方调用…需要我们在实际使用过程,灵活运用这些标签来减轻SQL的代码量和降低复杂度。
6. resultMap标签
resultMap标签用于表示数据库查询结果和实体对象的映射关系,它是映射文件中中所复杂的一个标签,常用的属性有两个:
1
<
resultMap
2
#定义这个
resultMap
的唯一标识
3
id
=
"XXXResult"
4
#返回值的全限定类名,或类型别名
5
type
=
"com.xxx.entity.User"
>
6
7
#子节点....
8
9
resultMap
>
而它的子节点则就非常多了:
1
<
resultMap
id
=
"XXXResult"
type
=
"java.util.HashMap"
>
2
#constructor:类在实例化时,用来注入结果到构造方法中
3
<
constructor
>
4
#idArg:ID参数;标记结果作为ID可以帮助提高整体效能
5
<
idArg
/>
6
#arg:注入到构造方法的一个普通结果
7
<
arg
/>
8
constructor
>
9
#一个 ID 结果;标记出作为 ID 的结果可以帮助提高整体性能
10
<
id
/>
11
#注入到字段或 JavaBean 属性的普通结果
12
<
result
/>
13
#一个复杂类型的关联;许多结果将包装成这种类型
14
<
association
property
=
""
/>
15
#一个复杂类型的集合
16
<
collection
property
=
""
/>
17
# 使用结果值来决定使用哪个 resultMap
18
<
discriminator
javaType
=
""
>
19
#基于某些值的结果映射
20
<
case
value
=
""
>
case
>
21
discriminator
>
!
22
resultMap
>
如查询要把查询结果的字段用驼峰的写法映射,可以定义一个resultMap,吧对象和实体属性一一对应起来:
1
<
resultMap
id
=
"UserResultMap"
type
=
"java.util.HashMap"
>
2
<
id
column
=
"id"
property
=
"id"
/>
3
<
result
column
=
"nick_name"
property
=
"nickName"
/>
4
<
result
column
=
"gmt_created"
property
=
"gmtCreated"
/>
5
<
result
column
=
"gmt_modified"
property
=
"gmtModified"
/>
6
resultMap
>
在SQL用就可以直接使用这个resultMap作为返回类型:
1
<
select
id
=
"selectUserByName"
resultMap
=
"UserResultMap"
>
2
select id,nick_name,gmt_created,gmt_modified from user where name =#{name}
3
select
>
上面的例子只用到resultMap中最常用的两个子标签:
6. 运行原理和实操一波
看完一波语法之后,脑子处于似懂非懂的状态,好像都是在讲配置文件和mapper的使用。当我们学会了编写这些mapper之后,究竟应该怎么使用它?
到这里我们就不得不提一下mybatis的运行过程了,先了解几个mybatis提供的接口/类:
SqlSessionFactoryBuilder : SqlSessionFactory的构造器,用于创建SqlSessionFactory,采用了Builder设计模式。
SqlSessionFactory:SqlSession工厂类,以工厂形式创建SqlSession对象,采用了Factory工厂设计模式。
SqlSession:执行SQL的接口
由于mybatis的运行原理非常复杂,远远不是30分钟能掌握的,因此在此只是概括为最大的四个过程:
加载配置创建SqlSessionFacotry
通过sqlSessionFactory获取SqlSession
SqlSession查找和转化Mapper
SqlSession执行mapper中的SQL语句
知道了运行流程之后,我们就可以实操一波了,虽然主流的开发框架都已经看不见这些东西了,但作者还是决定抛弃一切框架,只用maven构建一个空白项目进行实操:
在idea上创建一个maven项目,并且在pom中引入mybatis和mysql依赖
这个简单,不多描述。
其中pom中的依赖为:
1
<
dependencies
>
2
<
dependency
>
3
<
groupId
>
org.mybatis
groupId
>
4
<
artifactId
>
mybatis
artifactId
>
5
<
version
>
3.2.7
version
>
6
dependency
>
7
<
dependency
>
8
<
groupId
>
mysql
groupId
>
9
<
artifactId
>
mysql-connector-java
artifactId
>
10
<
version
>
6.0.6
version
>
11
dependency
>
12
dependencies
>
在resources中创建一个名为mybatis-config.xml的配置文件,内容为:
1
2
3
PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
4
<
configuration
>
5
6
<
properties
>
7
8
<
property
name
=
"driver"
value
=
"com.mysql.cj.jdbc.Driver"
>
property
>
9
<
property
name
=
"url"
value
=
"jdbc:mysql://10.9.0.111/test"
>
property
>
10
properties
>
11
12
<
environments
default
=
"development"
>
13
14
<
environment
id
=
"development"
>
15
<
transactionManager
type
=
"JDBC"
/>
16
<
dataSource
type
=
"POOLED"
>
17
<
property
name
=
"driver"
value
=
"${driver}"
/>
18
<
property
name
=
"url"
value
=
"${url}"
/>
19
<
property
name
=
"username"
value
=
"root"
/>
20
<
property
name
=
"password"
value
=
"test100"
/>
21
dataSource
>
22
environment
>
23
environments
>
24
25
<
mappers
>
26
27
<
mapper
resource
=
"mapper/UserMapper.xml"
/>
28
mappers
>
29
configuration
>
创建表结构:
1
DROP
TABLE
IF
EXISTS
`user`
;
2
CREATE
TABLE
`user`
(
3
`id`
int
(
11
)
NOT
NULL
AUTO_INCREMENT,
4
`name`
varchar
(
255
)
DEFAULT
NULL
,
5
`gmt_created`
varchar
(
255
)
DEFAULT
NULL
,
6
`gmt_modified`
varchar
(
255
)
DEFAULT
NULL
,
7
PRIMARY
KEY
(
`id`
)
8
)
ENGINE
=
InnoDB
AUTO_INCREMENT=
2
DEFAULT
CHARSET
=utf8mb4;
9
-- 插入一条数
10
INSERT
INTO
`user`
VALUES
(
'1'
,
'hello mybatis'
,
null
,
null
);
在java下创建User.java的实体类(注意:为了简化代码,getter和serter已经去掉,实操时自行补上):
1
public
class
User
{
2
private
Integer id;
3
private
String name;
4
private
String gmtCreated;
5
private
String gmtModified;
6
//getter 和 setter...
7
}
在java下创建UserMapper.java的映射类:
1
public
interface
UserMapper
{
2
User
getUserByName
(@Param(
"name"
)
String name)
;
3
}
在resources下创建mapper文件夹,在mapper下创建UserMapper的xml文件:
1
2
3
<
mapper
namespace
=
"UserMapper"
>
4
<
select
id
=
"getUserByName"
resultType
=
"User"
>
5
select * from user where name =#{name}
6
select
>
7
mapper
>
启动mybatis执行SQL
根据上面的运行流程,就可以编写一个测试类:
1
public
static
void
main
(String args[])
{
2
try
{
3
String resource =
"mybatis-config.xml"
;
4
// 1. 获取配置文件的输入流
5
InputStream inputStream = Resources.getResourceAsStream(resource);
6
// 2. 读取配置文件并用SqlSessionFactoryBuilder创建一个SqlSessionFactory
7
SqlSessionFactory sqlSessionFactory =
new
SqlSessionFactoryBuilder().build(inputStream);
8
// 3. 从SqlSessionFactory中获取一个SqlSession
9
SqlSession s= sqlSessionFactory.openSession();
10
// 4. 查找映射SQL文件
11
UserMapper mapper=s.getMapper(UserMapper.class);
12
// 5.执行CURD操作
13
User user=mapper.getUserByName(
"hello mybatis"
);
14
15
if
(user!=
null
){
16
System.out.print(
"查询成功,我的名次是:"
+user.getName());
17
}
18
19
}
catch
(Exception e){
20
e.printStackTrace();
21
}
22
}
查看输出:
1
查询成功,我的名次是:hello mybatis
大功告成!有兴趣的读者可以根据上面的过程,编写属于自己的原生态mybatis的测试项目,如果有问题或者需要源码请关注公众号留言或加微信:sisi-ceo,我们一起来征服写代码这做大山~
分享标题:30分钟入门MyBatis
分享网址:http://myzitong.com/article/gssgis.html