赞
踩
1.框架技术
框架的概念
是一个应用程序的半成品
提供可重用的公共结构
按一定规则组织的一组组件
分析优势
不用再考虑公共问题,专心在业务实现上
结构统一,易于学习,维护
新手也可以写出好程序
主流框架的介绍
1.Struts2框架
2.Hibernate框架
3.Spring框架
4.SpringMVC框架
5.MyBatis框架
2.MyBatis介绍及其环境搭建
数据持久化概念
持久化是程序数据在瞬时状态和持久状态间转换的过程
MyBatis框架及ORM
MyBatis框架简介
MyBatis的前身是iBatis,本是Apache的一个开源项目,2010年这个项目由Apache Software Foundation迁移到了Google Code,并改名为MyBatis。2013年迁移到Github。
MyBatis官网:http://mybatis.org
Githob:http://github.com/mybatis
MyBatis框架特点
1.基于SQL语法,简单易学
2.能了解底层封装过程
3.SQL语句封装在配置,便于统一管理与维护,降低程序的耦合度
4.方便程序代码调试
什么是ORM
ORM(Object/Relational Mapping)即对象/关系映射,是一种持久化技术。
MyBatis通过简单的XML或者注解进行配置和原始映射,将实体类和SQL语句之间建立映射关系,是一种半自动化的ORM实现
MyBatis是ORM解决方案
基于ORM,MyBatis在对象模型和关系数据库的表之间建立了一座桥梁,通过MyBatis建立SQL关系映射,以便捷地实现数据库存储、查询、更改和删除等操作。
MyBatis环境搭建
在MyEclipse中新建工程后,要使用MyBatis,需做以下准备工作
1.下载jar包
2.部署jar包
3.编写MySatis核心配置文件
4.创建实体类-POJO
5.创建DAO接口
6.创建SQL映射文件
7.编写测试类
1.下载需要的jar包
(1)mybatis-3.2.2.zip(MyBatis的jar文件)
mybatis-3.2.2.zip解压后的目录结构如图所示
注意查看根目录(mybatis-3.2.2)和lib目录。在根目录下存放着mybatis-3.2.2.jar,为MyBatis的jar文件,mybatis-3.2.2.pdf为MyBatis官方使用手册。
lib目录下存放着编译依赖包,如图示,这些jar文件的作用如下表
名 称 | 说 明 |
---|---|
asm-3.3.1.jar | 操作Java字符码的类库 |
cglib-2.2.2.jar | 用来动态集成Java类或实现接口 |
commons-logging-1.1.1.jar | 用于通用日志处理 |
javassist-3.17.1-GA.jar | 分析、编辑和创建Java字节码的类库 |
log4j-1.2.17.jar | 日志系统 |
slf4j-api-1.7.5.jar | 日志系统的封装,对外提供统一的A |
slf4j-log4j12-1.7.5.jar | slf4j对log4j的相应驱动,完成slf4j绑定log4j |
(2)mybatis-3-mybatis-3.2.2.zip(MyBatis源码包)
mybatis-3-mybatis-3.2.2.zip是MyBatis的源码包,里面是MyBatis的所有源代码
2.部署jar文件
3.创建MyBatis核心配置文件configuration.xml
为了方便在框架集成时更好的区分各个配置文件,我们一般将此文件名命名为”mybatis-config.xml”。该文件需要配置数据库连接信息和MyBatis的参数。
4.创建持久化类(POJO)和SQL映射文件
接下来,继续进行SQL映射文件的创建,完成与POJO(实体类)的映射,该文件也是一个XML文件,命名为BranchersMapper.xml,如图示。
5.创建测试类
(1)读取核心配置文件mybatis-config.xml
String url = “mybatis-config.xml”;
//获取mybatis-config.xml文件的输入流
InputStream is = Resources.getResourceAsStream(url);
(2)创建SqlSessionFactory对象,读取配置文件
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
(3)创建SqlSession对象
SqlSession session = factory.openSession();//create
(4)调用mapper文件进行数据操作
List list = session.selectOne(“dao.BranchesMapper.getAllBranches”);
3.MyBatis的基础要素----核心对象
SqlSessionFactoryBuilder
SqlSessionFactoryBuilder负责构建SqlSessionFactory,并且提供了多个build( )方法的重载
通过源码分析,可以发现都是在调用同一签名方法:
Build(InputStream inputStream,String environment,Properties properties)
由于方法参数environment和properties都可以为null,那么去除重复的,真正的重载方法其实只有如下三种:
build(Reader reader,String environment,Properties properties)
build(InputStream inputStream,String environment,Properties properties)
build(Configuration config)
通过上述分析,发现配置信息可以以三种形式提供给SqlSessionFactoryBuilder的build( )方法,分别是InputStream(字节流)、Reader(字符流)、Configuration(类),由于字节流与字符流都属于读取配置文件的方式,所以从配置信息的来源就很容易想到构建一个SqlSessionFactory有两种方式:读取XML配置文件构造方式和编程构造方法。
SqlSessionFactory
SqlSessionFactory简单的理解就是创建SqlSession实例的工厂。所有的MyBatis应用都是以SqlSessionFactory实例为中心,SqlSessionFactory的实例可以通过SqlSessionFactoryBuilder对象来获得。有了它之后,顾名思义,就可以通过SqlSessionFactory提供的openSession()方法来获取SqlSession实例。
SqlSession
SqlSession是用于执行持久化操作的对象,类似于JDBC中的Connection。它提供了面向数据库执行SQL命令所需的所有方法,可以通过SqlSession实例直接运行已映射的SQL语句,如图所示。
4.MyBatis的基础要素----核心配置文件
mybatis-config.xml文件结构
DTD文件的引入
MyBatis有两种配置文件:核心配置文件(mybatis-config.xml)和SQL映射文件(mapper.xml)。
这两种配置文件都需要手动引入各自的DTD文件(mybatis-3-config.dtd和mybatis-3-mapper.dtd),并在IDE中进行相应配置,否则在编写配置文件的时候,节点元素以及属性等不能自动联想。
1.使用MyBatis实现条件查询
SQL映射文件
MyBatis真正强大之处就在于SQL映射语句,也是它的魅力所在
下面是关于SQL映射文件的几个顶级元素配置
mapper:映射文件的根元素节点,只有一个属性namespace(命名空间),其作用如下:
用于区分不同的mapper,全局唯一
绑定DAO接口,即面向接口编程。当namespace绑定某一接口之后,可以不用写该接口的实现类,MyBatis会通过接口的完整限定名查找到对应的mapper配置来执行SQL语句。因此namespace的命名必须要跟接口同名。
cache:配置给定命名空间的缓存。
cache-ref:从其他命名空间引用缓存配置
resultMap:用来描述数据库结果集和对象的对应关系
sql:可以重用的SQL语句,也可以被其他语句引用。
insert:映射插入语句。
update:映射更新语句
delete:映射删除语句
select:映射查询语句
使用select完成单条件查询
这是一个id为getBranchesByBusinessNo的映射语句,参数类型为string,返回结果集的类型是Branches。注意参数的传递使用#{参数名}
id:命名空间中唯一的标识符,可以被用来引用这条语句
parameterType:表示查询语句传入参数的类型的完全限定名或别名。它支持基础数据类型和复杂数据类型。
在上面的示例中使用的是基础数据类型”string”,这是一个别名,代表String,属于一个内建的类型别名。对于普通的Java类型,有许多内建的类型别名,并且它们对大小写不敏感。
下表只列出了部分别名和Java类型的映射,其他的别名映射请参考MyBatis的帮助文档。
使用select完成多条件查询
使用resultMap完成查询结果的展现
在前面对于结果列的展示,只是展示出用户表(smbms_user)中所有字段的值,比如用户表中userRole字段记录的是角色id.而不是其对应的角色名称。在实际开发中,作为列表页的展示,用户关注的往往是角色名称而不是角色id,那么如何解决呢?
有两种方案解决:
(1)修改POJO:User.java,增加userRoleName属性,并修改查询用户列表的SQL语句,对用户表(smbms_user)和角色表(smbms_role)进行连表查询,使用resultType做自动映射。
(2)通过resultMap来映射自定义结果。
我们推荐第二种方案,使用resuleMap做自定义结果映射,字段名可以不一样,并且还可以指定要显示的列,比较灵活,应用也广泛。
ResultMap元素的属性值和子节点。
Id属性:唯一标识,此id值用于select元素resultMap属性的引用
Type属性:表示该resultMap的映射结果类型
Result子节点:用于标识一些简单属性,其中column属性表示从数据库中查询的字段名,property则表示查询出来的字段的输出,展示列表(用户编码、用户名称、性别、年龄、电话、用户角色)。注意:用户角色不再是角色id,输出的是角色名称。
MyBatis中在对查询进行select映射的时候,返回类型可以用resultType,也可以用resultMap。那么resultType和resultMap到底有何关联和区别。
1.resultType
resultType直接表示返回类型,包括基础数据类型和复杂数据类型
2.resultMap
resultMap则是对外部resultMap定义的引用,对应外部resultMap的id,表示返回结果映射到哪一个resultMap上。
3.resultType和resultMap的关联
在MyBatis进行查询映射的时候,其实查询出来的每个字段值都放在一个对应的Map里面,其中键是字段名,值则是其对应的值。
注意:在MyBatis的select元素中,resultType和resultMap本质上是一样的,都是Map数据结构。但需要明确一点:resultType属性和resultMap属性绝对不能同时存在,只能二者选其一使用。
4.resultMap的自动映射级别
2.使用MyBatis实现增删改操作
使用insert完成增加操作
MyBatis实现增加操作,使用的是insert元素来映射插入语句。首先在UserMapper接口里增加add()方法:
public int add(User user);
要插入的User对象作为入参,返回值类型为int类型,即返回执行SQL影响的行数。
注意:对于增删改(inserrt、update、delete)这类数据库更新操作,需要注意两点:
(1)该类型的操作本身默认返回执行SQL影响的行数,所以DAO层的接口方法的返回值一般设置为int类型。最好不要返回boolean类型。
(2)inset、update、delete元素中均没有resultType属性,只是查询操作需要对返回结果类型(resultType/resultMap)进行相应的指定。
接下来修改测试类UserMapperTest.java,增加testAdd()方法。
使用update完成修改操作
MyBatis实现修改操作,使用的是update元素来映射修改语句。
首先在UserMapper接口里增加modify()方法:
public int modify(User user);
要修改的User对象作为入参,返回值类型为int类型,即返回执行SQL影响的行数。
接下来修改测试类UserMapperTest.java,增加testModify方法进行修改数据测试
使用@Param注解实现多参数入参
修改个人密码的方法,当参数有多个时.每个参数前都需增加@Param注解:
public int updatePwd(@Param(“id”)Integer id, @Param(“userPassword”)String pwd);
使用注解@Param来传入多个参数,如@Param(“userPassword”)String pwd.相当于将该参数pwd重命名为userPassword,在映射的SQL中需要使用#{注解名称},如#{userPassword}。
下面继续修改UserMapper.xml,增加id为updatePwd的SQL映射,示例如下。
使用delete完成删除操作
MyBatis实现删除操作,是使用delete元素来映射删除语句。具体的用法与insert、update类似。首先在UserMapper接口中增加delete方法:
接下来修改测试类UseMapperTest.java,增加testDeleteUserById方法。
3.使用resultMap实现高级结果映射
resultMap的基本配置顶
association
4.resultMap自动映射级别和MyBatis缓存
MyBatis缓存
1.一级缓存
一级缓存是基于PerpetualCache(MyBatis自带)的HashMap本地缓存,作为范围为session域内,当session flush或者close之后,该sessio中所有的cache就会被清空。
2.二级缓存
二级缓存就是global caching,它超出session范围之外,可以被所有SqlSession共享,开启它只需要在MyBatis的核心配置文件(mybatis-config.xml)setting中设置即可。
一级缓存缓存的是SQL语句,二级缓存缓存的是结果对象
3.二级缓存的配置
(1)MyBatis的全局cache配置,需要在mybatis-config.xml的settings中设置,代码如下:
(2)在mapper文件(如UserMapper.xml)中设置缓存,默认情况下是没有开启缓存的。需要注意的是,global caching 的作用域是针对mapper的namespace而言的,即只有在此namespace内(cn.smbms.dao.user.UserMapper)的查询才能共享这个cache,代码如下:
(3)在mapper文件配置支持caches后,如果需要对个别查询进行调整,可以单独设置caches,代码如下:
1.使用SQL完成多条件查询
动态SQL基于OGNL的表达式,可使我们方便地在SQL语句中实现某些逻辑。用于实际动态SQL的元素如下:
If:利用if实现简单的条件选择。
choose(when,otherwise):相当于Java中的switch语句,通常与when和otherwise搭配。
where:简化SQL语句中where的条件判断。
set:解决动态更新语句。
trim:可以灵活地去除多余的关键字。
foreach:迭代一个集合,通常用于int条件。
1.1使用if+where实现多条件查询
1.If
2.where
1.2使用if+trim实现多条件查询
Prefix:前缀,作用是通过自动识别是否有返回值后,在trim包含的内容上加上前缀,如此处的where
Suffix:后缀,作用是在trim包含的内容上加上后缀
PrefixOverrides:对于trim包含内容的首部进行指定内容(如此处的”and|or”)的忽略
SuffixOverrides:对于trim包含内容的首尾部进行指定内容的忽略
2.使用动态SQL实现更新操作
2.1使用if+set改造更新操作
2.2使用if+trim改造修改操作
3.使用foreach完成复杂查询
我们学习了使用动态SQL的if、where、trim元素来处理一些简单查询操作,那么对于一些SQL语句中含有in条件,需要迭代条件集合来生成的情况,我们就需要使用foreach标签来实现SQL条件的迭代
3.1MyBatis入参为数组类型的foreach迭代
Foreach主要用再构建in条件中,它可以在SQL语句中迭代一个集合。它的属性主要有:item、index、collection、separator、close、open。
对于SQL语句循环(int语句),需要使用foreach标签。通过上述代码,来介绍下foreach的基本属性:
Item:表示集合中每一个元素进行迭代时的别名(如此处的”rolelds”)
Index:指定一个名称,用于表示在迭代过程中,每次迭代到的位置。(此处省略,未指定)
Open:表示该语句以什么开始(既然是in条件语句,所以必然是以”(”开始)。
Separator:表示在每次进行迭代之间以什么符号作为分隔符(既然是in条件语句,所以必然是以”,”作为分隔符)。
Close:表示该语句以什么结束(既然是in条件语句,所以必然是以”)”结束)。
Collection:最关键并容易出错的属性,需格外注意,该属性必须指定,不同情况下,该属性的值是不一样的。主要有三种情况。
若入参为单参数且参数类型是一个List的时候,collection属性值为list
若入参为单参数且参数类型是一个数组的时候,collection属性值为array(此处传入参数Integer[] rolelds为数组类型,故此处collection属性值设为”array”)。
若传入参数为多参数,就需要把他们封装为一个Map进行处理
Select中返回的是一个resultMap(id=”userMapByRole”),该resultMap也进行了相应的字段映射。最后修改测试类,增加测试方法,示例代码如下。
3.2MyBatis入参为List类型的foreach迭代
在上述代码中,foreach的大部分属性设置跟上一示例基本一致,由于角色列表入参使用的List,故collection属性值为”list”。
最后修改测试类,增加测试方法testGetUserByRoleId_foreach_list(),示例关键代码
3.3MyBatis入参为Map类型的foreach迭代
除了使用之前章节介绍过的@Param注解,还可以按照前文中介绍collection属性的时候,提过的第三种情况:若入参为多个参数,就需要把它们封装为一个Map进行处理。此处我们就采用这种处理方式来解决此需求。
首先修改UserMapper.java,增加接口方法:根据传入的用户角色列表和性别获取相应的用户信息。示例代码如下。
在测试方法中把用户角色列表(roleList)和性别(gender)两个参数封装成一个Map(conditionMap)进行方法入参,比如。
修改UserMapper.xml
通过对foreach标签的collection属性的学习,我们发现不管传入的是单参数还是多参数,都可以得到有效解决。若单参数入参,是否可以封装成Map进行入参呢?答案是肯定的,单参数也可以封装Map进行入参。实际上,MyBatis在进行参数入参的时候,都会把它封装成一个Map,而Map的key就是参数名,对应的参数值就是Map的value。若参数为集合的时候,Map的Key会根据传入的是List还是数组对象相应地指定为”list”或者”array”。现在就更改之前的演示示例:根据用户角色列表,获取该角色列表下用户列表的信息,此处参数不使用List或者数组,直接封装成Map来实现。
增加接口方法
在以下代码中,把用户角色列表(roleList)这一个参数封装成Map(roleMap)进行方法入参
这样的好处是,我们可以自由指定Map的Key,此处指定roleMap的key为rKey
修改UserMapper.xml,增加相应的getUserByRoleId_foreach_map,示例代码如下
在上述代码中,注意collection的属性值不再是list,而是我们自己设置的roleMap的Key,即rKey,最后增加测试方法进行测试,运行结果正确
小结:
(1)MyBatis接收的参数类型:基本类型、对象、List、数组、Map。
(2)无论MyBatis的入参是那种参数类型,MyBtis都会将参数放在一个Map中,对于单参入参的情况:
若入参为基本类型:变量名作为key,变量值为value,此时生成的Map只有一个元素。
若入参为对象:对象的属性名作为key,属性值为value
若入参为List:默认”list”作为key,该List即为value
若入参为数组:默认”array”作为key,该数组即为value
若入参为Map:键值不变
3.4choose(when、otherwise)
Choose元素的作用相当于Java中的switch语句,基本上跟JSTL中choose的作用和用法是一样的,通常都是搭配when、otherwise使用。下面通过一个示例来说明
在上述代码中,使用@Param实现多条件入参,然后修改UserMapper.xml,示例代码如下
3.MyBatis实现分页功能
1.MyBatis分页
MySQL的分页功能是基于内存的分页,即查出来所有记录,再按起始位置和页面容量取出结果。
现在我们就给用户管理功能模板的查询用户列表功能增加分页,要求结果列表按照创建时间降序排列。
具体DAO层的实现步骤如下所示
(1)使用聚合函数count( )获取总记录数(在之前的示例中已经完成)代码如下。
(2)实现分页,通过limit(起始位置,页面容量)
修改UserMapper.java,增加分页方法,示例代码如下:
通过上述代码,相比原来的getUserList方法,增加了两个参数:起始位置(from)和页面容量(pageSize),用于实现分页查询。
然后修改UserMapper.xml的getUserList查询SQL语句,增加limit关键字,示例代码如下
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。