1.MyBatis简介:
MyBatis是一个开源的数据持久层框架。内部封装了所有能通过JDBC访问数据库的操作,MyBatis的主要思想就是将程序的sql剥离出来,配置在配置文件中(.xml),实现sql的灵活配置,可以在不修改代码的情况下直接修改配置文件中的sql。
- ORM
*ORM(Object/Relational Mapping)*通过单词分析来讲就是对象 | 关系| 映射,它是一中数据持久化技术,它在对象模型和关系型数据库之间建立起对应关系,并且提供了一种机制,通过JavaBean对象去操作数据库表中的数据。如果能够理解ORM的原理,对接下来学习MyBatis会非常有帮助。 - MyBatis的实现方案
MyBatis通过简单的XML或注解进行配置和原始映射,将实体类(pojo)和sql语句之间建立映射关系,它是一种半自动化的ORM实现,还有一种全自动化的持久化框架Hibernate这里不多赘述。
1.2 MyBatis的环境搭建
使用MyBatis一般分为以下几步:
1.下载jar包
2.部署jar包
3.编写MyBatis的核心配置文件
4.创建实体类
5.创建DAO接口
6.创建SQL的映射文件
7.编写测试类
1.下载jar包
如果你没有使用maven的话就要去官网下载MyBatis的jar包(http://mybatis.org)
下载后解压应该是这样的目录:
如果你idea创建的是maven项目的话就简单了,只需要在mvnrepository网站搜索MyBatis即可
只需要选择你需要的版本导入maven即可
2.部署jar包
我演示的话是使用idea+maven演示,不会使用maven的可以去看看别人写的学习文档,从mvnrepository拿到版本之后,只需要在idea中的pom.xml中粘贴即可
这样MyBatis的jar就部署成功了
3.编写MyBatis的核心配置文件
MyBatis的核心配置文件主要用于配置数据库连接和MyBatis运行时需要的各种特性,包含了设置和影响MyBatis行为的属性,配置文件都会放在resources目录下面,一个标准的MyBatis目录是这样的:
- java目录为编写java代码的目录
- resources目录为编写配置文件的目录
- webapp是web项目的目录
- test为测试类的目录
介绍完目录之后, 我们在resources下面新建一个命名为‘mybatis-config.xml’
<?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>
<!-- 引用 database.properties 配置文件 -->
<properties resource="database.properties"></properties>
<!--配置mybatis的log实现log4j-->
<settings>
<setting name="logImpl" value="LOG4J"></setting>
</settings>
<!--设置别名-->
<typeAliases>
<package name="pojo" />
</typeAliases>
<!--配置mybatis的运行环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!-- 告诉mybatis需要加载的sql映射文件 -->
<mappers>
<mapper resource="mapper/BillMapper.xml" />
</mappers>
</configuration>
上面就是基本的mybatis的核心配置文件的所有内容,如果想直接使用的话还需要在resources下面建立一个数据库的.properties文件,当然也可以直接在dataSource 节点下面的value直接给值
我使用的是mysql8.0,如果是其他版本请自行更改。
3.1 mybatis-config.xml元素的作用:
1). configuration:配置文件的根元素节点
2). properties:通过resources属性从外部指定properties属性文件,文件主要用来描述数据库连接的相关配置
3). settings:设置mybatis运行中的一些行为
4). environments:表示配置mybatis的多套运行环境,将sql映射到多个不同的数据库上,可以配置多个environment子元素节点,但是必须指定一个默认的(default:id)
5). environment:配置mybatis的一套运行环境,需指定运行环境id、事务管理、数据源配置等
6).mappers:告诉mybatis去哪里找到sql映射文件,整个项目可以有一个或多个sql映射文件
7). mapper:mappers的子元素节点,具体指定sql映射文件的路径,resource属性的值为sql映射文件的路径
需要注意的是mybatis-config.xml的节点必须按照顺序来排位,否则XML就会报错
4.创建持久化类和SQL映射文件
持久化类是指其实例状态需要被mybatis持久化到数据库中的类,持久化类通常对应需求中的业务实体:
因为我使用了lombok,所以没有getset方法,在mybatis中不需要pojo类名和数据库名一样,但是得保证pojo的属性和数据库的字段名一致。
在pojo包下面创建完之后,我们就可以创建pojo的映射文件了,我们一般命名为pojo类名+mapper,它也是个xml文件,因为mapper属于mapper(dao)层的操作,所以应该放在mapper(dao)包下面。
下面展示的代码为sql映射文件:
<?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:命名空间,它的作用就是对SQL进行分类化管理,可以理解为SQL隔离
注意:使用mapper代理开发时,namespace有特殊且重要的作用
-->
<mapper namespace="mapper.RoleMapper">
<!--
[id]:statement的id,要求在命名空间内唯一
[parameterType]:入参的java类型
[resultType]:查询出的单条结果集对应的java类型
[#{}]: 表示一个占位符?
[#{id}]:表示该占位符待接收参数的名称为id。注意:如果参数为简单类型时,#{}里面的参数名称可以是任意定义
-->
<select id="getRoleList" parameterType="String" resultType="Role">
SELECT * FROM `smbms_role` WHERE roleName LIKE CONCAT('%',#{roleName},'%')
</select>
</mapper>
上面就是一个标准的sql映射文件,我上门namespace的值是刚刚新建的pojo的接口,跟sql映射文件同包,具体接口的作用会在之后详解。
5.创建测试类
- 读取配置文件
- 通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂
- 通过SqlSessionFactory创建SqlSession
- 调用SqlSession的操作数据库方法
- 关闭SqlSession
@Test
public void test01() throws IOException {
// a) 读取配置文件;
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// b) 通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂。
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// c) 通过SqlSessionFactory创建SqlSession。
SqlSession sqlSession= sqlSessionFactory.openSession();
// d) 调用SqlSession的操作数据库方法。
List<Role> role= sqlSession.selectList("mapper.RoleMapper.getRoleList","陈");
System.out.println(role.size()); //请通过foreach输出
// e) 关闭SqlSession。
sqlSession.commit();
}
测试之前记得在maven中添加juint4进行测试,有些人在第一次测试的时候可能会遇到Resources.getResourceAsStream点不出来,因为可能是你声明错了包,使用的应该是这个:
这样整个mybatis的搭建就完成了。
1.3Mybatis框架核心
首先我们再来看下Mybatis的核心接口和类,如图:
1). mybatis通过读取配置文件信息(全局配置文件和映射文件),构造出SqlSessionFactory,每个
mybatis的应用程序都有一个SqlSessionFactory对象的实例为核心。
2). 首先获取SqlSessionFactoryBuilder对象,可以根据XML配置文件或Configuration类的实例构建该对象。
3). 然后获取SqlSessionFactory对象,该对象实例可以通过SqlSessionFactoryBuilder对象来获得
4). 有了SqlSessionFactoryBuilder,就可以获取(创建)Sqlsession(会话)了。
5).Mybatis是通过SqlSession来操作数据库的。SqlSession本身不能直接操作数据库,它是通过底层的Executor执行器接口来操作数据库的。Executor接口有两个实现类,一个是普通执行器,一个是缓存执行器(默认)。
6).Executor执行器要处理的SQL信息是封装到一个底层对象MappedStatement中。该对象包括:SQL语句、输入参数映射信息、输出结果集映射信息。其中输入参数和输出结果的映射类型包括HashMap集合对象、POJO对象类型。
观看核心对象的解释,最好配合刚刚的测试类一起观看,更容易理解
1.3.1SqlSession的二种使用方式
(1).通过SqlSession实例来直接执行已映射的SQL语句,比如上面的测试方法, 通过sqlSession.selectList(),这种是通过SqlSession实例来执行查询的。
(2).上面我说除了在mapper下面新建xml之外还要建立一个同名的接口,这种方法就是通过接口来进行映射的,该接口称为映射器。(接口的方法名必须与SQL映射文件中SQL语句的ID一一对应),下面我们来改造上面的测试方法:
@Test
public void test01() throws IOException {
// a) 读取配置文件;
InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
// b) 通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂。
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
// c) 通过SqlSessionFactory创建SqlSession。
SqlSession sqlSession= sqlSessionFactory.openSession();
// d) 调用SqlSession的操作数据库方法。 getRoleList 是接口中的方法
List<Role> role= sqlSession.getMapper(RoleMapper.class).getRoleList();
System.out.println(role.size()); //请通过foreach输出
// e) 关闭SqlSession。
sqlSession.commit();
}
第一种方式是旧版本MyBatis提供的操作方式,虽然现在也可以使用,但是第二种是MyBatis官方所推荐使用的,其表达方式也更加直白,代码更加清晰,类型安全,也不用担心易错的字符串字面值以及强制类型转换。
2.MyBatis的SQL映射文件详解
MyBatis真正的强大在于SQL映射文件,使用SQL映射文件配置可以减少50%以上的代码量,下面来介绍几个*的
元素配置:
- mapper:映射文件的根元素节点,只有一个属性namespace(命名空间)
~用于区分不同的mapper,全局唯一
~绑定DAO接口,即面向接口编程。当namespace绑定某一接口(如上面的测试映射文件),可以不用写该接口的实现类,namespace的命名必须与接口名相同**!!** - cache:配置给命名空间的缓存
- cache-ref:从其他命名空间引用缓存配置
- resultMap:用来描述数据库结果集和对象的对应关系
- sql:可以重用的SQL块,也可以被其他语句引用。
- inser:映射插入语句
- update:映射更新语句
- delete:映射删除语句
- select:映射查询语句
2.1 SQL映射文件–select
select元素(查询)是我们使用MyBatis时最常用的元素,下面我们用一个select实例来进行分析:
id:命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType:表示查询语句传入参数的类型的完全限定名或别名。它支持基础数据类型和复杂数据类型,比如上面我使用的就时String类型
resultType:查询语句返回类型必须时完全限定名或别名,规则与parameterType一样,上面我 resultType返回的就是一个Role对象,接口中的方法返回值为List集合,我的resultType使用了别名,如果你不会使用别名可以用完全的限定名,就是包名+pojo+实体类名。
2.1.1 resultMap的使用详解
举个日常查询中使用的例子:如果我查询某个用户表,用户表中有一个关联id,如果我想查询显示用户和这个关联id的name,一般我们会在实体类中新增一个新属性,然后通过多表连接进行查询,下面可以使用resultMap来自定义结果映射,字段名可以不一致,并且你可以指定你想要显示的列。下面我们再来改变刚刚的测试方法:
<!--映射resultMap-->
<resultMap type="User" id="userList">
<id property="id" column="id" />
<result property="userCode" column="userCode" />
<result property="userName" column="userName" />
<result property="userRole" column="userRole" />
--!!<result property="userRoleName" column="roleName" /> --!!
</resultMap>
<select id="getUserListResultMap" parameterType="User" resultMap="userList">
select u.*,r.roleName FROM subms_user as u,smbms_role as r
where u.userName like CONCAT('%',#{userName},'%') and
u.userRole = #{userRole} AND u.userRole=r.id
</select>
下面我来概述下这个测试映射:
- resultMap :resultMap的type的值为pojo(类)名,id的值为下面select(resultMap属性)用来引用的值,id必须唯一。
- result:id节点主要用来声明为id的意思,也可以使用result来代替,property为pojo的属性名,column为数据库中的列名
resultType和resultMap的关联和区别
- resultType : 直接返回类型,包括基础类型和复杂数据类型。
- resultMap:resultMap则是对外部resultMap定义的引用,对应外部resultMap的id,表示返回结果映射到哪一个resultMap上。
- resultMap主要用来应对再数据库字段信息与对象属性不一致或者需要做复杂的联合查询时,如果只是简单的单表查询就使用resutType即可,需要注意的时resultType和resultMap不能同时存在,只能二选一。
resultMap的映射级别
上面我们说到,通过resultMap可以自定义你想要映射的字段,如果没有映射是不是不能显示呢?是可以显示的,但前提是必须是查询到的数据,这时就关系到了一个叫做映射级别的东西了。
NONE:禁止自动匹配,如果改为这个属性,那么没有映射的字段就不能显示了。
PARTIAL(默认):自动配置所有属性,除了内部嵌套的(association、collection)
FULL:自动匹配所有
设置映射级别是在mybatis-config.xml中进行settings设置
2.2使用Mybatis实现增删改操作
Mybatis的增删改的操作都是一致的,下面只介绍增加:
接口方法:
对于增删改数据库更新的操作,只需要注意二点:
(1). 该类型的操作本身默认返回执行SQL影响的行数,所有mapper的接口方法返回值一般为int类型
(2).insert、update、delete元素中均没有resultType(resultMap)属性,只有查询操作需要对返回结果类型进行指定。
3.编写动态SQL+批量执行SQL
动态SQL是Mybatis的一个强大的特性。动态SQL基于OGNL,可以方便我们在SQL语句中实现某些逻辑,用于实现动态SQL的元素如下:
if:利用if实现简单的条件选择。
choose(where,otherwise):相当于java中的switch语句,通常与where和otherwise搭配。
where:简化SQL语句中where的条件判断。
set:解决动态更新语句。
trim:可以灵活地去除多余的关键字
foreach:迭代一个集合,通常用于in条件。
3.1if+where使用详解
我们直接来一个实例来进行解释了解>>
if标签中的test的值为实体类中属性名,判断有没有为空,如果不等于空和不等于‘’,就进行添加条件,where标签会自动识别其标签内是否有返回值,若有就插入一个where,若该标签返回的内容是以and或者or开头的,会自动剔除。
3.2if+set使用详解
我们再来一个实例来进行解释了解>>
set元素主要用于更新,主要功能类似于where元素,主要是在包含的语句前输出一个set,若包含的语句是以逗号结束的,会自动把该逗号忽略掉。
3.3foreach使用详解
关于foreach的使用详解,直接使用实例来解释:
foreach主要用在构建in条件中,它可以在sql语句中迭代一个集合。
- item:表示集合中每一个元素进行迭代时的别名(如roleIds)。
- index:指定一个名称,用于表示在迭代过程中,每次迭代到的位置。
- open:表示该语句以什么开始(in条件语句,所以必然是以"("开始)
- separator:表示在每次进行迭代之间以什么符号作为分隔符(in条件语句,所以必然是以","作为分隔符)
- close:表示该语句以什么结束(以“)”结束)
- collection:最关键并容易出错的属性,会有三种情况:
-!若入参为单参数且参数类型是一个List的时候,collection属性值为list。
-!若入参为单参数且参数类型是一个数组的时候,collection属性值为array。
-!若入参数为多参数,就需要把它封装成一个Map进行处理。
关于本文章有解释不清楚或者纰漏,请联系我!!