MyBatis官网地址:mybatis – MyBatis 3 | Introduction
01.什么是orm
orm,是对象关系映射,就是数据库中的每一个数据都用对象表示出来,自动将对象与数据映射的技术。 -----> 类 == 表;对象 == 表中的一行数据;属性 == 字段名(列)
02.常见的orm框架
2.1:Hibernate
优点:简化jdbc操作过程;代码移植性较好;开发效率较高
缺点:sql自动生成所以优化将困难;对复杂sql需要很多判断和组装;动态sql支持较欠缺
2.2:JdbcTemplate
优点:是在spring框架的基础上开发的,对于sql的写法和结果的组装上完全交给了开发者自己去控制,但是缺点是处理不了动态sql语句。
2.3:MyBatis(重点)
优点:2.3.1:半自动化持久层框架,需要手动写sql
2.3.2:支持动态sql,自动完成动态sql的判断和组装
2.3.3:是一个ORM思想的框架,对结果进行了封装
2.3.4:消除了JDBC大量冗余的代码,不需要手动开关连接
2.3.5:使用映射文件,可以让代码和配置文件完全分离
2.3.6:数据库移植性强,(MyBatis用JDBC连接数据库,所只要JDBC 支持的数据库 MyBatis 都支持,而JDBC提供了可扩展性,所以只要这个数据库有针对Java的jar包就可以就可以与 MyBatis 兼容)
缺点:1:SQL语句编写工作量较大,尤其是字段多、关联表多时,对开发员编写SQL语句的功底有一定要求
2:SQL语句依赖于数据库,导致数据库移植性差,不能随意更换数据库
2.4:什么是mybatis
是一个半自动化持久层框架、对原生jdbc操作细节进行了封装、是一个ORM思想的框架,对结果进行了封装
03.MyBatis常用标签
3.1:核心配置文件层级关系
3.2:常见标签
3.2.1:environments: 用于配置数据库环境,可以配置多环境
3.2.2:transactionManager: 配置事物管理器 -----> 值为: JDBC
3.2.3:dataSource: 配置数据库连接池 POOLED: 默认的数据库连接池 UNPOOLED: 不使用数据库连接池
3.2.4:properties: 用于加载外置的配置文件,
environments 配置的数据库信息,就可单独抽取出来到properites配置文件中
<properties resource="jdbc.properties"> </properties>
3.2.5:typeAliases: 用于给较长的名称起一个别名(小名)
Mybatis内置了一些别名 _int ---> int 、int ---> Integer、map ---> Map、list---> List
<typeAliases> <typeAlias type="类的全路径名" alias="起的别名"></typeAlias> <package name="包名,实体类所在的包名"></package> </typeAliases>
3.2.6: mappers : 用于加载映射配置文件 规则:实体类名+Mapper,一个表对就表示一个Mapper映射配置文件,关注的重点,mapper和sql语句
3.2.7:useGeneratedKeys:
3.2.8:foreach 标签:
3.2.9:where 标签 和 if 标签,
3.2.10:set 标签 和 if 标签,
<!-- 标签 set 能自动去掉最后的逗号,主要功能是用在更新数据--> <update id="updateUserSet" parameterType="User"> update user <set> <if test="username !=null"> username = #{username}, </if> <if test="birthday !=null"> id = #{birthday}, </if> <if test="gender !=null"> sex =#{gender}, </if> <if test="address !=null"> id = #{address}, </if> </set> </update>
3.2.11:association:一对一关系映射
属性名 | 说明 |
---|---|
property | 关联实体的属性名 |
javaType | 关联实体java类型 |
3.2.12:collection:一对多关系映射、多对多关系映射
属性名 | 说明 |
---|---|
property | 关联实体集合的属性名 |
javaType | 关联实体的java类型(集合泛型的类型) |
04:MyBatis的API
4.1:Resources:加载mybatis的核心配置文件
4.2:SqlSessionFactoryBuilder:根据mybatis的核心配置文件构建出SqlSessionFactory工厂对象
4.3:SqlSessionFactory:用于创建SqlSession会话对象(相当于Connection对象)这是一个工厂对象,对于这种创建和销毁都非常耗费资源,一个项目中只需要存在一个即可
4.4:SqlSession:这是Mybatis的一个核心对象。我们基于这个对象可以实现对数据的CRUD操作对于这个对象应做到每个线程独有,每次用时打开,用完关闭
05:注意事项
1:模糊查询,使用到关键字 concat ---> 解决sql注入问题
模糊查询的四种方式都有缺陷,最终使用concat的嵌套 格式: concat(concat('%',#{要获取值的属性}),'%') 另外 select 中不要写注释,可能会出现报错 select * from user where username like #{username} 正确写法: <select id="要查询接口方法名" parameterType="要查询内容数据类型" resultMap="查的那个类"> select * from user where username like concat(concat('%',#{username}),'%') </select>
2:MyBatis接口开发规范
2.1:Mapper 映射文件的 namespace 与 Mapper 接口全限定名一致
2.2:Mapper 接口的方法名与 CRUD 语句中的id属性名一致
2.3:方法的参数类型与 parameterType 属性类型一致,(库字段名和表字段名一致,使用)
2.4:方法的返回值类型与 resultType 属性类型一致,(库字段名和表字段名不一致,先映射,后使用)
2.5:映射文件需要与接口在同一个包下,文件名和接口名相同:扫描包,加载所有的映射文件
3:多条件查询 ---> 多个参数传递 parameterType 可不写(不写可能会出现注入问题)可用 @Param 代替
06:#{} 与 ${}区别
6.1:#{}:底层 PreparedStatement
1:sql与参数分离,不会出现sql注入问题
2:sql只需要编译一次
3:接收简单数据类型,命名:#{随便写}
4:接收引用数据类型,命名:#{属性名}
6.2:${}:底层 Statement
1:sql与参数拼接在一起,会出现sql注入问题
2:每次执行sql语句都会编译一次
3:接收简单数据类型,命名:${value}
4:接收引用数据类型,命名: ${属性名}
5:字符串类型需要加 '${value}'
07:SQL片段
7.1:什么是SQL片段 ---> 映射文件中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
7.2:案例
<!-- 抽取重复的SQL 将当前映射文件的共同的sql代码抽取一个片段,实现sql的复用性... id="selectUser" 当前sql片段的唯一标识 --> <sql id="selectUser"> select id,username,birthday,sex,address from user </sql>
<!-- 引用SQL片段 --> <select id="findUsersForEacheVO" parameterType="QueryVo" resultType="User"> <include refid="selectUser" /> where id in <foreach collection="ids" open="(" close=")" item="id" separator=","> #{id} </foreach> </select>
08:MyBatis加载策略
8.1:什么是加载策略
当多个模型(表)之间存在关联关系时, 加载一个模型(表)的同时, 是否要立即加载其关联的模型, 我们把这种决策成为==加载策略==
通俗理解,多个表之间关联,查询一个表时,其他表的信息是跟着立即显示,还是等需要时在显示
8.2:加载策略分类 ----->>> 默认是:立即加载
8.2.1:立即加载:加载一个表时,立即加载出相关联表的信息,即立即加载
8.2.2:延迟加载:加载一个表时,等需要时在加载出相关联表的信息,即延迟加载
8.3:加载策略使用场景
一对一查询时,既需要立即加载 ; 一对多、多对多时,使用延时加载。
8.4:嵌套查询
一对多查询,要将一条sql语句,拆分成两条sql语句,才能演示出延迟加载的效果。将一对一或一对多的一条sql语句,拆分成两条sql语句,这种方式我们称之为MyBatis的嵌套查询
09:MyBatis加载策略环境搭建
9.1:延迟加载: 局部优先级高于全局
全局:在.xml配置文件中设置
<!--全局配置--> <settings> <!--开启延迟(懒)加载 true 开始 false(默认值) 关闭--> <setting name="lazyLoadingEnabled" value="true"/> </settings>
局部:
9.2:立即加载: ---> 默认就是立即加载,下边是设置取消触发立即加载
<!-- 全局配置延迟加载: name="lazyLoadingEnabled" value="true" 属性值是专用不能改,专门用于指定是否开启延迟的--> <!-- name="lazyLoadTriggerMethods" value="" ,取消立即加载的触发机制,固定写法 equals,clone,hashCode,toString 默认这些方法会触发立即加载,上边的设置是取消这个默认 --> <settings> <setting name="lazyLoadingEnabled" value="true"/> <setting name="lazyLoadTriggerMethods" value=""/> </settings>
10.MyBatis缓存
缓存是用来提高查询效率的,所有的持久层框架基本上都有缓存机制Mybatis也提供了缓存策略,分为一级缓存,二级缓存
1.为什么使用缓存 ---> 提高查询效率
2.什么样的数据适合使用缓存 ---> 经常访问但又不经常修改的数据
3.一级缓存:MyBatis一级缓存是,SqlSession级别的缓存,默认开启,不需要手动配置,不同的SqlSession之间的缓存区域是互相不影响的,执行SqlSession的C(增加)U(更新)D(删除)操作,或者调用clearCache()、commit()、close()方法,都会清空缓存
4.二级缓存:二级缓存是mapper映射级别的缓存,虽然是默认开启的,但需要在映射文件中配置<cache/>
标签才能使用,而且要求实体类的必须实现序列化接口
public class 类名 implements Serializable
多个SqlSession去操作同一个Mapper映射的sql语句,多个SqlSession可以共用二级缓存,二级缓存是跨SqlSession的。二级缓存相比一级缓存的范围更大