关于Mybatis映射文件的学习笔记
一、基本的增删改查
1.1 操作实例
- (1)定义接口方法
1 | public interface EmployeeMapper { |
- (2)在映射文件中,填写相应的sql语句
- 增的标签为:
<insert>
- 删的标签为:
<delete>
- 改的标签为:
<update>
- 查的标签为:
<select>
- 查的标签要额外添加
resultType
来确定返回值的类型
- 查的标签要额外添加
- 传入的参数是个对象时,仍然可以直接使用#{}来获取对象属性
- 增的标签为:
1 | <mapper namespace="Dao.EmployeeMapper"> |
- (3)Java程序调用方法
1 |
|
1.2 拓展:获取自增主键的值
- 在插入时,mysql支持自增主键,自增主键的获取,mybatis底层是利用了JDBC的**statement.getGenreatedKeys()**的方法
- 使用方法:
- 在
<insert>
标签添加额外的属性 useGenerateKeys="true"
:开启获取自增主键keyProperty=""
:将获取的信息封装到JavaBean的哪个属性
- 在
- 举例
1 | 1、修改映射文件中的<insert>标签 |
1 | 2、修改Java程序的增方法进行测试 |
1.3 拓展:获取非自增主键的值
- 在
<insert>
中添加字标签<selectKey>
- keyProperty:sql查询出来的数据,封装给JavaBean的那个属性
- order:执行顺序”BEFORE/AFTER”,在sql语句之前/之后执行
- resultType:返回结果类型
- 举例:
1 | 以获取非自增主键的方式,来实现获取自增主键 |
二、参数传递
2.1 单个参数
- 对于单个参数,Mybatis不会做任何处理,参数名字可以随便起
- 使用方法:
#{参数名}
2.2 多个参数
- 对于过个参数。MyBatis对进行特殊处理,会将参数封装到为一个Map集合中
- 若全局配置文件
useActualParamName="true"
,则该Map存储格式为:- Key:param1, param2….paramN 或者 arg0, arg1 …. argN
- value:按顺序传入的参数
- 若全局配置文件
useActualParamName="false"
,则该Map存储格式为:- Key:param1, param2….paramN 或者 0, 1 …. N
- value:按顺序传入的参数
- Mybaits版本不同,默认值可能发生变化
1 | 接口 |
1 | 映射文件 |
2.3 命名参数
- 由于参数一多,上面的方法就十分不便利,由此引出命名参数
- 命名参数:【明确指定封装的参数时map的Key】
- 在接口传参时使用格式:Xxxx(@Param(“id”)int id, @Param(“name”)String name)
- Map存储格式为:
- Key:使用@Param注解指定的值
- value:按顺序传入的参数
1 | 接口方法 |
1 | 映射文件 |
2.4 Map集合
- 为了方便,我们也可以传入map
- 直接#{Key}:来取出对象的值
1 | 接口方法: |
1 | 映射文件 |
1 | 方法测试 |
2.5 集合/数组
- Mybatis也会对集合、数组封装为Map
- Collection:
- Key:collection[0], collection[1] … collection[N]
- 使用方法:#{Key}
- List:
- Key:list[0], list[1] … list[N]
- 使用方法:#{Key}
- Set:
- Key:set[0], set[1] … set[N]
- 使用方法:#{Key}
- Array:
- Key:array[0], array[1] … array[2]
- 使用方法:#{Key}
- 举例:以List集合为例
1 | 接口方法 |
1 | 映射文件 |
1 | 方法测试 |
2.6 补充
- (1)若接口定义返回类型为:集合
- 映射文件,resultType填写集合属性的类型
- (2)若接口定义返回类型为:Map
- 映射文件中resultTyoe填写map
2.7 获取参数
- #{}:可以获取map中的值或pojo对象属性的值
- ${}:可以获取map中的值或pojo对象属性的值
- #{} 和 ${} 的区别
- #{}是以预编译的形式,将参数设置到sql语句中;类似PreparedStatement
- ${}取出的值直接拼装在sql中,进行sql拼接;类似Statement
- 使用场景
- 大多情况下,使用#{}
- 在原生JDBC不支持占位符的地方(表名),可以用${}进行取值
2.8 参数处理
- #{},在取出参数时,可以进行一些规则
- 支持的属性:javaType、jdbcType、mode、numericScale、resultMap、typeHandler、jdbcTypeName、expression
- javaType:在Java中的属性
- jdbcType:在数据库中的属性
- mode:存储过程(后面讲)
- numericScale:保留几位小数
- resultMap:规定封装的结果集
- typeHandler:类型处理器
- jdbcTypeName:和jdbcType一样
- expression:表达式(未来支持的功能)
- 上述属性中,就jdbcType可能需要进行设置
- 在我们数据为null时,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle(报错)
- 解决方法:
- 因为mybatis对所有的null都映射为jdbc OTHER
- 解决方法(1):设置jdbcType=NULL
- 解决方法(2):全局配置文件
<setting name="jdbcTypeForNull" value="NULL">
三、resultMap的使用
3.1 基础介绍
- resultMap和resultType类,来确定返回的类型,但resultMap可以进行自定义
- resultMap和resultType不能同时使用
- reslutMap
<resultMap id="" type=""></resultMap>
- id:resultMap的唯一标识
- type:自定义规则的JavaBean
- 子标签
<id>
<id>
是用来定义主键<id column="" property=""/>
- column:数据库中列的字段名
- property:JavaBean的属性名
- 将查询对象的字段名,封装到对应JavaBean的属性
子标签
<result>
<result>
用来定义非主键<result column="" property=""/>
- column:数据库中列的字段名
- property:JavaBean的属性名
其他不指定的类会自动封装;但是一旦使用resultMap的话,建议全部指定
举例:
1 | 映射文件 |
3.2 前期准备
- (1)为Employee类添加多一个属性为Department
- (2)创建相应的类(JavaBean),接口,映射文件,并将映射文件注册到全局配置文件中
1 | 类 |
1 | 接口 |
1 | 映射文件 |
- (3)在数据库中创建相应的表部门表
1 | 创建部门表 |
- (4)在数据库为员工表添加额外字段,并和部门表进行联系
1 | 添加字段 |
1 | 联系两表 |
3.3 联合查询
- (1)级联属性封装结果集
- 举例:在查询员工表时,根据员工表的部门号,把相应的部门查询出来
- 在resultMap中的result,通过
对象.属性
进行对部门类赋值
1 | 映射文件 |
- (2)利用association对象实现
- 子标签
<association property="" javaType=""></association>
<assovaition>
:指定联合的JavaBean对象- property:指定哪个属性是联合对象
- javaType:联合的类的全类名
1 | 映射文件 |
- (3)关联的对象时集合时
- 关联的对象时多个值时使用
- 举例:一个部门有多个员工,在查询一个部门时,把该部门的员工查询出来
1 | 映射文件 |
3.4 分步查询
- 利用assocation来实现
- 分布查询的好处:以已有的方法,完成复杂的sql操作,不用额外写sql语句
1 | Employee映射文件 |
1 | Department映射文件 |
- 拓展:分步查询传递多个数据
- 可以将多个值封装到Map中进行传递
<association property="" select="" column="{key1=column1, key2=column2...}">
- Collection实现分步查询
- 关联的对象时多个值时使用
- 举例:一个部门有多个员工,在查询一个部门时,把该部门的员工查询出来
1 | 映射文件 |
3.5 延迟加载
- 我们每次查询Employee对象的时候,都将Department一起查询出来
- 为了提升效率,希望部门信息在我们使用的时候再去查询,也就是延迟加载
- 在分布查询的基础上,在全局配置文件加上两个配置即可实现延迟加载
<setting name="lazyLoadingEnable" value="true"/>
:开启所有关联对象都会延迟加载<setting name="aggressiveLazyLoading" value="false"/>
:关闭所有对象全部加载
- 可以不在全局配置文件中开启
lazyLoadingEnable
- 在
association
中添加fetchType="lazy/enger
来开启延迟加载
- 在
3.6 鉴别器
- mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装行为
- 举例:封装Employee
- 如果是男生,把last_name这一列的值赋值给email
- 如果查询的时女生,则把部门信息查询出来
1 | 映射文件 |