读《深入浅出 Mybatis 技术与原理实战》有感
前言
随着大数据时代的到来,Java持久层框架 Mybatis 成为越来越多企业的选择。 这本书分为三个部分,我简单的把我的理解在这篇博客简单记录一下!如果想有更深的了解,可以看一下杨开振老师的这本书《深入浅出 Mybatis 技术与原理实战》。
一、如何高效使用 Mybatis
Mybatis 什么场景下使用;Mybatis 基础模块和生命周期实例;Mybatis 配置的含义和内容;Mybatis 元素和使用方法;动态SQL等…
1.1、MyBatis 简介
首先传统的JDBC连接
- 注册驱动(数据库)
- 创建连接
- 执行Statement
- 返回结果集
- 关闭数据库
ORM 模型 ,数据库的表与简单的Java 对象(POJO 类)的映射关系模型。
Hibernate 全自动 ORM 框架,Mybatis 半自动 ORM 框架。
1.2、MyBatis 基本构成
核心组件:
- SqlSessionFactoryBuilder 构造器 ,根据配置信息或代码生成SqlSessionFactory(工厂接口)。
- SqlSessionFactory 依赖工厂生成 SqlSession 会话。
- SqlSession 既可以 发送sql 去执行并返回结果,也可以获取Mapper 接口。
- Sql Mapper 组件, 由Java接口 和 XML文件 (或注解)构成,需要给出对应 sql 及 映射规则。负责发送sql并执行,并返回结果。
1.2.1、SqlSessionFactory 通过 SqlSessionFactoryBuilder 构造器 获得实例 。 SqlSessionFactory 是一个工厂接口,而不是一个类,任务是创建 SqlSession,类似于一个JDBC的一个连接对象。
提供两种方式创建 SqlSessionFactory:
- XML配置的方式(建议)
- 代码的方式(不建议)
1、初始化数据库连接池
2、定义数据库事务管理方式
3、创建Configuration,数据库运行环境注册给他
4、加入映射器,SqlSessionFactoryBuilder 通过Configuration 对象创建 SqlSessionFactory
1.2.2、创建SqlSession
SqlSession (美女)为你服务,你问了问题后,她会找工程师(Executor)解决,解决完成后,把结果Result 返回。
SqlSesion 主要用途两种:
- 获取映射器,映射器通过命名空间和方法名称找到对应SQL,发送给数据库执行后返回结果。
- 通过命名信息执行sql返回结果,ibatis留下的方式。SqlSession 通过update、insert、delete、select等方法,带上方法id,找到对应的XML对应的SQL,也支持事务,执行commit、rollback命令。
1.2.3、映射器
映射器由Java 接口和 XML 文件(或注解)组成。作用如下:
- 定义参数类型
- 描述缓存
- 描述sql语句
- 定义查询结果与对应POJO的映射关系
1.3、MyBatis 配置
Mybatis 配置 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> <!-- 配置 -->
<properties /> <!-- 属性 -->
<settings /> <!-- 设置 -->
<typeAliases /> <!-- 类型命名 -->
<typeHandlers /> <!-- 类型处理器 -->
<objectFactory /> <!-- 对象工厂 -->
<plugins /> <!-- 插件 -->
<environments> <!-- 配置环境 -->
<environment> <!-- 环境变量 -->
<transactionManager /> <!-- 事务管理器 -->
<dataSource /> <!-- 数据源 -->
</environment>
</environments>
<databaseIdProvider /> <!-- 数据库厂商标识 -->
<mappers /> <!-- 映射器 -->
</configuration>
1.4、动态SQL
1.4.1、if 元素
相当于Java中的 if, 经常与 test 属性联合使用
<select id="getEmpById2" resultType="emp">
SELECT * FROM emp WHERE 1=1
<if test="empno != null">
AND empno = #{empno}
</if>
</select>
1.4.2、choose 、when、otherwise 元素
相当于Java 中的Switch… Case… default…
<select id="getEmpById3" resultType="emp" parameterType="emp">
SELECT * FROM EMP
<where>
<choose>
<when test="empno != null">
AND empno like #{empno}
</when>
<when test="ename != null">
AND ename like #{ename}
</when>
<otherwise>
AND job = "zz"
</otherwise>
</choose>
</where>
</select>
1.4.3、trim、where、set 元素
- 使用 where 就不用编写1=1
- trim 元素
Prefix:前缀。
prefixOverrides:去掉第一个指定内容。
suffix:后缀。
suffixoverride:去掉最后一个指定内容。
<!-- 代替where -->
<select id="getEmpById4" resultType="emp" parameterType="emp">
SELECT * FROM emp
<!-- <where> <if test="username!=null"> and name = #{username} </if> </where> -->
<trim prefix="where" prefixOverrides="AND |OR ">
<if test="empno != null">
and empno = #{empno}
</if>
<if test="ename!=null">
AND ename = #{ename}
</if>
</trim>
</select>
- Set 主要用于更新语句使用
<update id="updateEmprById2" parameterType="emp">
UPDATE emp
<set>
<if test="ename!=null"> ename=#{ename},</if>
<if test="job!=null"> job=#{job},</if>
</set>
<where>
<if test="empno!=null">
empno=#{empno};
</if>
</where>
</update>
1.4.4、foreach 元素
foreach用来遍历,遍历的对象可以是数组,也可以是集合。
相关属性:
Collection:collection属性的值有三个分别是list、array、map三种。
Open:前缀。
Close:后缀。
Separator:分隔符,表示迭代时每个元素之间以什么分隔。
Item:表示在迭代过程中每一个元素的别名。
Index:用一个变量名表示当前循环的索引位置。
<insert id="addEmp6">
insert into emp(ename,job)values
<foreach collection="emps" item="emp" separator=",">
(#{emp.ename},#{emp.job})
</foreach>
</insert>
Mapper 接口:
public int addEmp6(@Param("emps")List<Emp> emps);
1.4.5、bind 元素
<select id="getEmpById6" resultType="emp">
<!-- 声明了一个参数empno 在后面就可以使用了 -->
<bind name="empno" value="'%' + empno + '%'" />
select * from emp where empno=${empno}
</select>
二、深入 Mybatis 源码
了解内部运行原理和插件开发方法和技巧;SqlSession 构建方法 以及四大对象如何工作;插件设计原理、开发方法
三、Mybatis 实战应用
Spring 集成 MyBatis 应用;Mybatis 实用场景
3.1、对于文件的操作,使用BLOB 字段读写
File file = new File("D:\");
FileInputStream in = new FileInputStream(file);
byte[] bytes = new byte((int) file.length());
try{
in.read(bytes);
} finally {
in.close();
}
Files files = new Files();
files.setFile(bytes);
转载自:https://blog.csdn.net/weixin_45395031/article/details/109495114