Mybatis
MyBatis是一款ORM模型,支持定制化 SQL、存储过程以及高级映射。可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java对象)映射成数据库中的记录
特点
半自动化 集成方便
简单易学 灵活度高 功能完整
Mybatis和hibernate 区别
-
Hibernate是全自动化ORM; Mybatis是半自动化ORM。
-
Hibernate简化dao层,不用考虑SQL语句的编写和结果映射,重点放在业务逻辑上; Mybatis需要手写SQL语句以及结果映射。
-
Hibernate是一个重量级的框架,内部生成SQL语句,反射操作太多,导致性能下降; Mybatis是一个轻量级的框架,需要自己写sql语句,有较少的反射操作。
-
Hibernate 不方便做SQL优化,遇到较复杂的SQL语句需要绕过框架实现复杂, 对多字段的结构进行部分映射困难; Mybatis 不仅可以做SQL优化还可以SQL与Java分离,还可以自行编写映射关系, 复杂的SQL语句Mybatis效率更高
Mybatis优势:
可以进行更细致的SQL优化;容易掌握
Hibernate优势:
dao层开发比mybatis简单,mybatis需要维护SQL和结果映射 hibernate数据库移植性好
动态代理
-
接口的返回值要和sqlMapper中的resultType一致
-
接口中的入参要和sqlMapper中的parameterType一致
-
接口的方法名要和sqlMapper中的id一致(dao层不允许方法重载)
-
sqlMapper中的namespace指向接口的类路径
-
接口要和sqlMapper同包
-
接口要和sqlMapper同名
使用SqlSession的方法getMapper() 让Mybatis自动生成对应接口的实现对象
映射器的特点
半自动化 :配置SQL语句,体现了半自动化和灵活性
ORM的体现:对象关系映射的实现,数据库表和POJO的映射关系
多个参数传递
-
Javabean 2. Map 3.param数(1) 4.arg数(0) 5. @Param
主键回填
当主键在数据库中为自增字段时,新增成功后,回填主键。
resultMap
定义映射规则:ORM 的特性,POJO 类和数据库的映射关系;
级联操作:多表存在主外键关系时,主表和从表之间的关联操作;
类型转换:数据库字段的类型和 POJO 类属性的类型转换。
级联
级联(cascade),是指多个对象之间的映射关系,建立数据之间的级联关系提高管理效率。
一对一 | 一对多 | 多对多 |
---|---|---|
一个对象对应唯一的对象, 举例:中国公民和身份证; | 一个对象对应多个对象, 举例:班级和学生; | 多个对象对应多个对象, 举例:公司角色和公司员工 |
一对一级联映射: 一对一使用association
一对多级联映射:使用ofType指定集合中的元素的类型
级联的缺陷
性能缺陷
复杂度缺陷
mybatis中所有的id不能相同
mybatis中在dao层不允许方法重载,id和方法名相同 id是唯一的
动态SQL
根据不同条件拼接SQL语句,实现对数据库更准确的操作
常用的动态SQL元素
if元素:进行单条件分支判断;
< if test ="条件"> 满足条件的语句 </ if>
choose元素(when):进行多条件分支判断;
<choose>
<when test="条件">满足条件的语句</ when>
<otherwise> 满足其他条件的语句 <otherwise>
</choose>
trim(where,set):辅助元素,用于处理一些 SQL 拼接问题;
<where>
<if test ="条件"> 满足条件的语句 </if>
</where>
<set>
<if test ="条件"> 满足条件的语句 </if>
</set>
<trim
prefix = ""
suffixOverrides = ""
prefixOverrides=""
suffix="">
</trim>
prefix:需要拼接的子句,可以是where,or或者set;
suffixOvrrides:忽略通过管道分隔的文本序列后缀。
prefixOvrrides:忽略通过管道分隔的文本序列前缀。
foreach元素:在 in 语句等列举条件时使用,循环获取列举的条件;
<foreach
item = ""
index=""
collection=""
open=""
separator=""
close="">
</foreach>
item:循环中的当前元素;
index:当前循环元素的位置下标;
collection:方法传递的参数,一个数组或者集合;
open:以什么符号开始将这些集合元素包装起来;
separator:各个元素的间隔符号。
close:以什么符号结束将这些集合元素包装起来;
bind元素:自定义一个上下文变量
<bind name=""value="_parameter">
</bind>
<bind name = “name1” value =
" '%' + _parameter+ '%' ">
</bind>
可以用来做模糊查询
Mybatis注解
常用的注解
基本注解
实现简单的增删改查操作。
增加操作 | 删除操作 | 修改操作 | 查询操作 |
---|---|---|---|
@Insert | @Delete | @Update | @Select |
结果映射注解
实现结果的映射关系,也可以完成级联映射
@Results 结果映射
一对一映射
@One( Select = 一对一查询方法,
fetchType = FetchType.EAGER )
例:
@Results({@Result(column="card_id",propert
y="card", one = @One ( select=
"dao.CardMapper.getCardById",
fetchType=FetchType.EAGER ) ) })
public void getNews (News news);
一对多映射
@Many( Select = 一对多查询方法,
fetchType = FetchType.EAGER )
例:
@Results({@Result(column="type_id",propert
y="news", many = @Many ( select=
"dao.NewsMapper.getNewsByType",
fetchType=FetchType.EAGER ) ) })
public void getNews (News news);
动态SQL注解
XML配置方式的动态SQL,是用<script> 的方式吧他照搬过来,用注解来实现。适用于xml配置转换到注解配置
@SelectProvider 查询语句的动态SQL,
@InsertProvider 新增语句的动态SQL,
@DeleteProvider 删除语句的动态SQL,
@UpdateProvider 修改语句的动态SQL;
脚本动态sql
在sql语句中加入标签,按照之前sqlmap中的动态sql的样式书写
实现动态SQL的内容
// 方式三 构造器生成动态sql语句 将方式二进制封装-- 构造器
@SelectProvider(type = Studentsql.class,method = "getSelectGZQStuSql")
public List<Student> findStudentGZQ(Student s);
class Studentsql{
public String getSelectGZQStuSql(Student s) {
return new SQL() {
{
//字段名
SELECT("sid,sname");
SELECT("birthday");
SELECT("ssex,classid");
//表
FROM("student");
//条件
if(s.getSsex() != null) {
WHERE("ssex = #{ssex}");
}
if(s.getClassid() != 0) {
WHERE("classid = #{classid}");
}
}
}.toString();
}
}
SQL 语句构造器
功能
解决 Java 代码中嵌入 SQL 语句,通过简单 地创建一个实例来调用方法生成SQL语句
Mybatis缓存
//分页
//方式一 limit 物理分页
@Select("select * from student limit #{param1},#{param2}")
public List<Student> findStudentPagelimit(int wz,int bc);
// 方式二 逻辑分页
@Select("select * from student")
public List<Student> findStudentPageRowBounds(RowBounds rb);
// 方式三 第三方插件 PageHelper
@Select("select * from student")
public List<Student> findStudentPageHelper();
立即加载
不管用不用信息,只要调用,马上发起查询并进行加载
延迟加载
在真正使用数据时才发起查询,不用的时候不查询,按需加载(也叫懒加载)
一级缓存
功能
减少 Java Application 与数 据库的交互次数,从而提升程序的运行效率;
缓冲的适用性
适合使用缓存: | 不适合用于缓存: |
---|---|
经常查询并且不经常改变的 数据的正确与否对最终结果影响不大的 比如:一个公司的介绍,新闻等 | 经常改变的数据 数据的正确与否对最终结果影响很大 比如商品的库存,股市的牌价等 |
一级缓存失效情况
不同SqlSession对应不同的一级缓存
同一个SqlSession单查询条件不同
同一个SqlSession两次查询期间执行了任何一次增删改操作
同一个SqlSession两次查询期间手动清空了缓存
二级缓存
Mybatis 的二级缓存相对于一级缓存来说,实现了缓存数据的共享,可控性也更强;
极大可能会出现错误数据,有设计上的缺陷,安全使用的条件比较苛刻;
分布式环境下,必然会出现读取到错误数据,所以不推荐使用;
-
什么是缓存
-
数据交换的缓冲区,当应用程序需要读取数据时,先从数据库中将数据取出,放置在缓冲区中,应用程序从缓冲区读取数据;
-
缓冲特点
-
数据库取出的数据保存在内存中,具备快速读取和使用。
-
什么是一级缓存
-
相对同一个SqlSession对象而言的缓存;
-
什么是二级缓存
-
一个namespace下的所有操作语句,都影响着同一个Cache;
-
自定义缓存的方式
-
实现org.apache.ibatis.cache.Cache接口自定义缓存;
-
引入Redis等第三方内存库作为MyBatis缓存。