如果对您有帮助
请点击上方“程序猿干货铺”关注我们
您的关注对我们意义重大
本文共4427字,阅读需要约9.8分钟
1MyBatis入门
1. 持久层与持久化
持久化指的是把数据保存到可永久的存储设备中(例如磁盘),持久化指的是将内存中的对象存储在数据库中,或是XML文件等等。
1. 面向对象的三层架构有表现层、业务层、持久层
2. 持久层:Dao模式,建立实体类和数据库表的映射 (也叫做ORM映射)。持久层的目的是完成对象数据和关系数据的转换
3. 业务层:将业务中的操作封装成一个方法,要保证同时成功或同时失败,不能部分成功部分失败
4. 表现层,使用MVC模式:M为模型,也就是实体类,用于数据封装和数据传输;V为视图,也就是GUI组件,用于数据的展示;C为控制,也就是控制器,负责流程的控制
一个完善的持久化层应该能达到以下的目标
代码重用性高
支持多种数据库平台
有相对独立性,持久层发生变化时不会影响上层实现
2. MyBatis
MyBatis是一款持久性框架,避免所有JDBC代码和设置阐述。MyBatis可以使用Xml或注解来配置和映射原生信息。MyBatis支持ORM、动态SQL、外部化SQL和封装SQL语句,使得它成为一款优秀的持久性框架。
配置MyBatis需要设置几个配置文件
mybatis-config.xml 指定MyBatis相关信息
sqlserver.properties 指定数据库信息
log4j.properties 配置日志信息
在使用的过程中,要按照以下的步骤
创建Bean实体类
创建Mapper数据操作的接口类
创建映射器配置文件
配置文件中,namespace表示该配置文件对于映射器接口的完全路径
insert映射插入语句
Id表示标识符
parameterType表示参数类型
useGeneratedKeys会从数据库内部自动生成主键
select映射查询语句
Id表示标识符
parameterType表示参数类别
resultType表示返回的期望类别
操作数据分为下面的步骤
读取并解析配置文件,创建SqlSessionFactory
从SqlSessionFactory中获取SqlSession对象
使用SqlSession对象操作数据
提交事务,可以回滚
关闭SqlSession对象
String resource = "mybatis-config.xml";Reader reader = Resources.getResourceAsReader(resource);SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();SqlSessionFactory factory = builder.build(reader);SqlSession sqlSession = factory.openSession();
SqlSession本身已经封装了对数据的增删改查操作
User user = new User(1,"Test");// insertUser是节点的idsqlSession.insert("insertUser",user);
但是更推荐使用映射器接口
User user = new User(1,"Test");UserMapper userMapper = sqlSession.getMapper(UserMapper.class);userMapper.insertUser(user);
UserMapper是一个映射接口,里面是我们想要的操作
public interface UserMapper{ int insertUser(User user); void updateUser(User user); List selectUsersByCondition(User user);}
定义接口后我们需要在UserMapper.xml中配置相关的Sql语句信息
之后我们可以提交事务或进行回滚,并关闭SqlSession对象
// 提交sqlSession.commit();// 回滚sqlSession.rollback();// 关闭sqlSession.close();
我们可以创建MyBatisUtil工具类,来简化操作的过程
public class MyBatisUtil{ private final static SqlSessionFactory sqlSessionFactory; static{ String resource = "mybatis-config.xml"; Reader = reader = null; try{ reader = Resources.getResourceAsReader(resource); }catch (IOException e){ System.out.println(e.getMessage()); } sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); public static SqlSessionFactory getSqlSessionFactory(){ return sqlSessionFactory; } }}
2MyBatis配置与API
通过加载配置,会生成一个Configuration对象,来生成Mapper Annotations和SqlMapConfig.xml文件。之后通过SQL解析生成Mapped Statement,最后生成映射的结果。
MyBatis的功能架构分为基础支撑层、数据处理层、API接口层
基础支撑层:最基础的功能支撑、包括连接管理、事务管理、配置加载和缓存处理等
数据处理层:负责具体的SQL查找、解析、执行和映射处理
API接口层:提供给外部使用的接口API,开发人员通过这些API来操纵数据库
SQL执行的时候有三种模式,在后面会详细介绍三种Executor的区别。
2. MyBatis配置文件详解
mybatis-config.xml文件的顶层为configuration,下层有properties、settings、typeAliases、typeHandlers、objectFactory、plugins、environments、mappers,一定要按照这个顺序。
properties
该元素是外部化的、可以替代的属性,这些属性也可以配置在Java属性配置文件中。其属性值可以在整个配置文件中使用,使用可替换的属性来实现动态配置,例如
settingssettings会修改MyBatis在运行时的行为方式,我们介绍一些常用的选项
//开启二级缓存 默认为true //全局设置懒加载 //用列标签代替列名称 //是否开启驼峰命名规则 // 配置和设定执行器 SIMPLE执行器创建一个新的预处理语句 REUSE执行器可能重复使用预处理语句 //BATCH执行器可以重复执行语句和批量更新 默认为SIMPLE // 驱动器等待数据库响应超时时间 // 查询结果日志打印
再详细介绍一下ExecutorType,
设为SIMPLE,在执行dao.save()的时候,相当于JDBC的stmt.execue(sql)
设为REUSE,在执行dao.save()的时候,相当于JDBC重用一条sql,再通过stmt传入多项参数值,然后执行stmt.executeUpdate()或stmt.executeBatch()
设为BATCH,在执行dao.save()时,相当于JDBC语句的stmt.addBatch(sql),即仅仅是将执行SQL加入到批量计划
typeAliases
定义类别名,缩短Java类名的长度,仅同xml配置有关
之后在其他的选项中即可使用缩略名
typeHandlerstypeHandlers选项将获取的值以一个合适的方式转换为Java类型
environmentsMyBatis可以配置多种环境(开发环境、测试环境等等)。这便于将SQL映射应用于多种数据库之中。environment可以配置多个,但如果是同一种模式,如development模式,配置了两个环境environment,myBatis会用后面的覆盖前面的。
在MyBatis中,transactionManager有两种类型
JDBC: 该配置直接使用JDK提供的JDBC来管理事务的各个环节。依赖于从数据源得到的链接来管理事务范围
MANAGED:是一个托管模型,本身并没有任何事物功能,而是托管出去由其他框架来实现,为整合而设
dataSource使用基本的JDBC数据源接口来配置JDBC连接对象的资源。内建数据类型有三种
UNPOOLED:不使用任何数据库连接池管理数据库连接
POOLED:使用MyBatis默认的数据库连接池管理数据库连接
JNDI:使用JNDI实现数据源
mappers
mappers定义MyBatis要从哪里寻找映射文件,其余的细节在每个SQL映射文件中
我们也可以通过@MapperScan注解来扫描包的路径
3. SQL映射文件详解
查询语句
SELECT * FROM PERSON WHERE ID = #{id}
ResultMap设置
insert、update和delete也非常类似。
sql节点可以定义重复使用的SQL代码段,并包含在其他语句中
id,username,password select from some_table wehre id=#{id}
4. 一级缓存与二级缓存
MyBatis有两种缓存的方式,一级缓存与二级缓存。一级缓存是在一个Session中,相同的查询结果会缓存起来。二级缓存可以调用会话间缓存的结果。
启用一级缓存要在settings.xml中设置cached选项,二级缓存需要在Mapper的配置文件中设置cached节点。
3MyBatis进阶
有的时候我们会使用到多表的关联查询,这样的时候该怎么使用MyBatis呢
1. 高级关联
关联指的是一种对象与另一种对象之间有联系。在给定的两个类中,可以从其中一个类的对象访问到另一个类的对象。如果只存在一个方向上的关联,称为单向关联;在两个方向上都存在关联,成为双向关联。
最多的关联是一对多,例如一个老师要管理多个学生,或者一篇博客有多个评论
ofType="comment" select="SelectComments"/> select="findById"/> select * from comment where blog_id=#{id} select * from blog
2. 配置与性能优化
每次执行一次查询都会联合另一个查询语句来加载关联的对象或集合,如果加载的关联数据较多,则执行的查询语句次数会增加
我们可以使用嵌套结果来提高查询效率
SELECT B.id,B.title,B.create_time, A.id, comment_id,A.blog_id,A.content,A.commentDate FROM Blog B left outer join comment A on B.ID = A.blog_id ofType="comment" select="SelectComments"/> select="findById"/>
4动态SQL
MyBatis另一个特性是动态SQL功能。
1. if标签
select id, author_id as author, content, create_time as createTime, type from BLOG where type=1 and title like #{title} and content like #{content}
2. choose、when、otherwise标签
select id, author_id as author, content, create_time as createTime, type from BLOG where type=1 and title like #{title} and contentlike #{title} and type = 1
3. where、set、trim标签
where会剔除多余的and
select id, author_id as author, content, create_time as createTime, type from BLOG where type=1 and type=1 and title like #{title} and content like #{content}
set剔除追加到条件末尾的任何不相关逗号
and type=1 and title like #{title}
trim一般用于去除sql语句中多余的and关键字,逗号,或者给sql语句前拼接where、set以及values等后缀,可用于选择性插入、更新、删除或者条件查询等操作
and type=1 and title like #{title}
4. foreach标签
在mapper配置文件中可以使用foreach标签来实现sql条件的循环,可完成批量的sql。MyBatis接收:基本类型、对象、List、数组、Map,无论传哪种参数,他都会将参数放在一个Map中。
foreach标签中有如下几个选项:
collection:要循环的集合
index:循环索引
item:集合中的一个元素
open:以什么开始
close:以什么结束
separator:循环内容之间以什么分割
update user_type set user_type_name=concat(user_type_name,'-new') where user_type_code in #{val}
动态SQL技术可以灵活的处理多条件查询,无需在代码中动态拼接SQL语句,简化了数据访问层的开发。
总结一下,动态SQL主要有以下标签:
if标签:根据结果动态为SQL拼接条件表达式,多个if的条件以AND来连接
choose标签(when,otherwise):根据when中的结果选择一个条件拼接到SQL语句中,如果所有的when均不满足,则选择otherwise中的条件
trim标签(where,set):where+if可以动态地添加条件,set+if可以动态地实现更新相应的值,使用trim可以替代where或者set
foreach标签:该标签通常结合in子句使用,可以通过循环迭代条件值来进行相关的操作