Mybatis的使用与流程解析
1. 什么是MyBatis
MyBatis的前身是Apache的一个开源项目ibatis,后来迁移到Google code就改名为MyBatis。
官方解释:
MyBatis是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
2. MyBatis的引入
如果是传统的的项目,则直接下载相应jar包引入到项目中即可,下载地址为:
http://central.maven.org/maven2/org/mybatis/mybatis/3.4.6/mybatis-3.4.6.jar
如果为maven构建的项目,则只需要在pom.xml中加入以下依赖然后reimport一下即可:
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>x.x.x</version>
</dependency>
3. MyBatis的配置和初始化
在引入mybatis之后,接下来需要学习的mybatis的配置
mybatis的基本配置:
1<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configuration 3 PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration> 5 <!--properties用于定义一些属性变量,以便在配置文件中调用--> 6 <properties> 7 <!--定义一个变量为driver的属性,在下面就可以用${driver}来获得其属性值--> 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="1234"/> 21 </dataSource> 22 </environment> 23 </environments> 24 <!--用于设置mapper文件的引入--> 25 <mappers> 26 <!--resource方式引入mapper文件--> 27 <mapper resource="mapper/UserMapper.xml"/> 28 </mappers></configuration>
这是一个标准的mybatis的配置文件,很多情况下,这个配置已经足够,但是为了在以后的使用有更好的认识,下面讲解配置文件中configuration标签下的常用子标签:
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}"/></dataSource>
2.settings标签
用于设置一些改变MyBatis运行时行为的配置
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"/></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></environments>
当我们需要增加一个环境配置时,只需要复制粘贴一份environment,修改其中属性的值即可。
4.mappers
用于mapper映射器的设置
mappers标签实际上是用于高速mybatis从哪找到我们写好的SQL语句,也就是映射文件。当我们写好一个表对应的mapper.xml时,我们只需要在mappers下增加一个mapper即可。
mappers查找mapper的方式有多种:
1. 根据mapper.xml文件定位
这些mapper.xml在resources中的某个文件夹xxx中,则用resource属性设置
1<mappers><mapper resource="xxx/AMapper.xml"/><mapper resource="xxx/BMapper.xml"/></mappers>
2. 根据映射器接口实现类的完全限定类名
当我们在这些mapper.xml设置好了namespace之后,我们可以通过映射器接口实现类的全路径类来设置,如在AMapper.xml设置namespace为com.xxx.dao.AMapper类之后,我们在这里可以使用class属性指定查找的mapper,但前提是:
AMapper.xml和AMapper.java必须在同一个包下。
1<mappers><mapper class ="com.xxx.dao.AMapper"/><mapper class ="com.xxx.dao.BMapper"/></mappers>
3. 包映射
有人会说,如果我们表有很多,这样一行一行的写不是很费劲吗,mybatis为了便于使用,提供了package的方式引入映射器,但前提
所有的mapper.xml和mapper.java必须在同一个包下。
1<mappers>
2 <package name="org.xxx.dao"/></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"/></mappers>
4. MyBatis的SQL语法
在现有的框架下编写代码,多数情况下都不需要理会mybatis底层的东西,而大量的工作都集中在编写mapper文件上。因此学会在mybatis下编写SQL语句是非常有必要的,我们首先来看一个标准的mapper文件的格式:
1<?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"><mapper namespace="com.xxx.dao.XxxMapper"></mapper>
MyBatis使用面向接口编程,就是把业务需求中具体逻辑实现和接口分开,对外只暴露接口,通过接口实现业务。而在业务需求变化时,仅需要修改实现类,而不需要变动现有的对接代码,降低对系统的影响。在namespace中指定该mapper对应的接口之后,不需要编写接口实现类,mybatis会通过该绑定自动帮你找到对应要执行的SQL语句。
如:在com.xxx.dao中创建一个XxxMapper.java的接口,需要编写一根据用户查询用户信息的方法。
1package com.xxx.dao;
2public interface XxxMapper {
3 //根据姓名查询一条用户信息
4 Map selectUserByName(@Param("name") String name);
5}
此时我们就可以在mapper.xml中设置namespace对应到上面的接口来:
1 <?xml version="1.0" encoding="UTF-8"?>
2 <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
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>
而在具体的业务实现类中,则是这样使用的:
@Service
public class XxxServiceImpl implements CustomerInfoService {
@Resource
private XxxMapper xxxMapper=null;
@Override
public Map getUser(String name) {
return xxxMapper.selectUserByName(name);
}
}
可以看出,从编写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">
5select * 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中最常用的两个子标签: <id>、<result>。还有很多其它的标签可以写成高级的resultMap,由于篇幅较长,而文章旨在入门,因此在此暂不对每个标签举例子解释,有兴趣的可以自行百度。
Mybatis的使用与流程解析的更多相关文章
- MyBatis 源码分析 - 配置文件解析过程
* 本文速览 由于本篇文章篇幅比较大,所以这里拿出一节对本文进行快速概括.本篇文章对 MyBatis 配置文件中常用配置的解析过程进行了较为详细的介绍和分析,包括但不限于settings,typeAl ...
- 深入Mybatis源码——执行流程
前言 上一篇分析Mybatis是如何加载解析XML文件的,本篇紧接上文,分析Mybatis的剩余两个阶段:代理封装和SQL执行. 正文 代理封装 Mybatis有两种方式调用Mapper接口: pri ...
- TCP/IP协议三次握手与四次握手流程解析
原文链接地址:http://www.2cto.com/net/201310/251896.html TCP/IP协议三次握手与四次握手流程解析 TCP/IP协议的详细信息参看<TCP/IP协议详 ...
- SSL/TLS算法流程解析
SSL/TLS 早已不是陌生的词汇,然而其原理及细则却不是太容易记住.本文将试图通过一些简单图示呈现其流程原理,希望读者有所收获. 一.相关版本 Version Source Description ...
- TCP/IP协议三次握手与四次握手流程解析(转载及总结)
原文地址:http://www.2cto.com/net/201310/251896.html,转载请注明出处: TCP/IP协议三次握手与四次握手流程解析 一.TCP报文格式 TCP/IP协议的详 ...
- Spring mybatis源码篇章-XMLLanguageDriver解析sql包装为SqlSource
前言:通过阅读源码对实现机制进行了解有利于陶冶情操,承接前文Spring mybatis源码篇章-MybatisDAO文件解析(二) 首先了解下sql mapper的动态sql语法 具体的动态sql的 ...
- Django生命周期 URL ----> CBV 源码解析-------------- 及rest_framework APIView 源码流程解析
一.一个请求来到Django 的生命周期 FBV 不讨论 CBV: 请求被代理转发到uwsgi: 开始Django的流程: 首先经过中间件process_request (session等) 然后 ...
- [MapReduce_3] MapReduce 程序运行流程解析
0. 说明 Word Count 程序运行流程解析 && MapReduce 程序运行流程解析 1. Word Count 程序运行流程解析 2. MapReduce 程序运行流程图
- HBase - 数据写入流程解析
本文由 网易云发布. 作者:范欣欣 本篇文章仅限内部分享,如需转载,请联系网易获取授权. 众所周知,HBase默认适用于写多读少的应用,正是依赖于它相当出色的写入性能:一个100台RS的集群可以轻松 ...
随机推荐
- PHP的一个牛逼的数组排序函数array_multisort
函数详情,具体可参考 官方手册 array_multisort 实际问题是这样的,有这么一组数据: $arr_times = array( array('2018-04-12 04:25:00', 3 ...
- 当碰到需要调试打包后的js
在react中经常开发碰到不能热更中进行调试的,如IE之类的 这个时候我们就需要打包才能运行看到效果, 但是往往每次打包都需要很长的时间: 这个时候我们就可以直接找到打包后的文件,直接在改文件中修改: ...
- 【c++错误】类的语法错误 error c2533:constructors not allowed a return type(构造函数不允许返回一个类型)
今天编写类的程序的时候不小心把类后的分号忘写了,就出现上面的错误提示. 顺便复习下类的正确格式: class 类名 { public: //习惯上将公有类型放在前面,便于阅读 ……(外部接口) pro ...
- vxworks固件分析
前言 vxworks 的固件分析流程 1.用binwalk查看固件基本信息并解压固件 2.获取固件相关信息, cpu架构,大小端 3.确定固件的加载地址 4.用IDA加载固件,并修复符号表 5. 分析 ...
- 导出PDF乱码
客户问题: 客户环境 LINUX系统weblogic10.3.0.0 用weblogic自带 JDK160_05 导出PDF中文字体全是口 解决方法: 客户的说他们的测试服务器和生产服务器环境是 ...
- Django基本设置
Dango设置流程图片示例: 设置路由时需要注意的一个点是:Django中定义路由时,通常习惯以斜线 / 结尾 其他常用命令: python manage.py runserver 0.0.0.0:8 ...
- 记一次es和mq的netty冲突
1.今天在服务里面加了 es 6.4的 依赖包后,在预发布测试时候出现了下列的问题 看了 半天,最后发现是 es的 jar包 和 mq的 netty包 有冲突.然后去idea的 jar包依赖里面查 ...
- IIS 中托管基于TCP绑定的WCF服务
IIS 中托管基于TCP绑定的WCF服务 一.创建一个基于TCP绑定的WCF服务 1.创建一个的简单的服务具体代码如下 服务契约定义 namespace SimpleService { // 注意: ...
- C#中的三种timer
转 https://blog.csdn.net/hoiven/article/details/51362582 如果你需要使用规律的时间间隔重复执行一些方法,最简单的方式是使用定时器(timer). ...
- 解决Failed to load the JNI shared library xxx/xxx/jvm.dll 错误
原因:jdk发生变化(新装了32位jdk),eclipse在启动时使用了 系统环境变量中的jdk路径(32位). 解决:只要把旧的64位的jre路径指定给eclipse启动文件即可. 在eclipse ...