一、映射文件解析
- 获取自增主键的值
- 参数处理封装
- 查询sql映射解析
1、获取自增主键的值
<insert id="addOkrRole" parameterType="com.tan.bo.OkrRole" useGeneratedKeys="true" keyProperty="id">
INSERT INTO okr_role(role_id, role_name, create_time, update_time, create_person, update_person)
VALUES (#{role_id},#{role_name},#{create_time},#{update_time},#{create_person},#{update_person})
</insert>
parameterType:参数类型可以省略 useGeneratedKeys="true":使用自增主键获取主键值策略。 keyProperty:指定对应主键属性,也就是mybatis获取到主键值后,将这个值封装给Javabean的哪个属性。
2、参数处理封装
(1)、单个参数
单个参数:不会做特殊处理 #{}:取出值,在mapsql映射文件中的sql参数可以随意命名。
(2)、多个参数
多个参数会做特殊化处理,对个参数会被封装成一个map
传参的方式有多种:
1、使用参数的索引:key param1,param2...... value:传入的参数值。
select * from okr_role where id = #{param1} and name =#{param2}
2、使用命名参数的方式:明确指定封装参数时map的key:@Param("id")
public OkrRole getInfo(@Param("id") Integer id, @Param("name") String name);
3、可以直接传入POJO:#{属性名},取出传入的pojo的属性值
public OkrRole getInfo(OkrRole OkrRole);
4、如果对个参数不是业务模型中的数据,没有对应的pojo,为了方便,我们可以传入map
#{key}取出map中对应的值。
如果对个参数不是业务模型中的数据,但是经常使用,就用map这种方式,比如我们的分页参数。
public OkrRole getInfo(Map<String, OkrRole>);
(3)、参数处理源码解析
(4)#{}和${}传参的区别
#{}:是预编译的形式,将参数设置sql语句中,PreparedStatement,防sql注入。
${}:取出值直接拼装在sql语句中;会有安全问题。
原生jdbc不支持占位符的地方我们就是可以使用${}进行取值(如:动态的查表,动态获取字段等)_。
参数中还有其他属性的设置如:
javaType:以根据参数对象的类型确定 javaType jdbcType:如果一个列允许使用 null 值,并且会使用值为 null 的参数,就必须要指定 JDBC 类型(jdbcType),比如有些数据库可能不能识别mybatis对null的默认处理,比如我们的oracle。 jdbcType other:无效的类型,因为mybatis对所有的null都映射的是原生JDBC的other
3、查询sql映射解析
(1)、常用查询方式
/***************查询一个列表****************/
public List<OkrRole> getListByNameLike(String name);
对应map映射文件:
<select id="getListByNameLike" resultType="com.tan.bo.OkrRole">
select * from okr_role where id = #{id}
</select>
/***************返回一条记录的map;key是列名,值就是对应的值****************/
public Map<String, Object> getOkrRoleByIdReturnMap(Integer id);
对应map映射文件:
<select id="getOkrRoleByIdReturnMap" resultType="map">
select * from okr_role where id = #{id}
</select>
/*多条记录就封装成一个map,Map<Integer, OkrRole>:键是这条记录的主键,值是记录封装后的Java对象*/
@MapKey("id")
public Map<Integer, OkrRole> getgetOkrRoleByNameReturnMap(String name);
对应map映射文件:
<select id="getgetOkrRoleByNameReturnMap" resultType="com.tan.bo.OkrRole">
select * from okr_role where name LIKE #{name}
</select>
(2)、resultType:返回值类型
别名或者全类名,如果返回的是集合,定义集合中元素的类型,不能和resultMap同时使用。
(3)、resultMap:返回值类型
实例规则1:
<!--
自定义某个javabean的封装规则
type:自定义贵则Java类型
id:唯一id方便引用
-->
<resultMap id="resultOkrRoleMap" type="com.tan.bo.OkrRole">
<!--
指定主键封装规则
id:定义主键会底层有优化
column:指定哪一列
property:指定对应Javabean属性
-->
<id column="id" property="id" />
<!--定义普通列封装规则-->
<result column="last_name" property="lastName"/>
<!--其他不指定的列会自动封装,我们只要写resultMap就把全部的映射规则都写上-->
<result column="email" property="email"/>
</resultMap>
实例规则2:
联合查询:级联属性封装结果集
<!--如果OkrRole实体类有其他实体的属性,就用以下级联的方式去写,dept就是OkrRole定义的别的实体的,deptName:在别的实体中-->
<result column="dept_name" property="dept.deptName"/>
实例规则3: 是对实例规则2的另外一种实现方式
association标签也可以指定联合Javabena的对象
<!--
association标签也可以指定联合Javabena的对象.
roperty="dept":指定哪个属性是联合的对象
javaType:指定这个属性对象的类型(不能省略)
-->
<association property="dept" javaType="com.tan.bo.Dept">
<id column="did" property="id" />
<result column="dept_name" property="deptName"/>
</association>
实例规则4:利用association进行分步查询:
/*******分步查询步骤*******/
利用association进行分步查询
1、先按照员工id查询员工信息
2、根据查询员工信息中关联d_id值取部门表查询部门信息
3、部门设置到员工中
/*******解析*******/
<association property="dept" select="com.tan.bo.Dept.getDeptById" column="d_id"/>
association:定义关联对象的封装规则
select:标明当前属性是代用select指定的方法查出的结果
column:指定将哪一列的值传给这个方法
实例5:使用延迟加载(按需加载,懒加载)
上面我们查询员工的信息的时候,会将员工关联的部门信息会一起查询出来,现在我们要做的是,部门信息在我们去使用的时候在去查询,这就是延迟加载,在分步查询的基础之上加上两个配置就可以,如下实例:
/*******在mybatis全部配置文件中设置延迟加载*****/
<!--开启延迟加载-->
<setting name="lazyLoadingEnabled" value="true" />
<!--侵入加载设置,如果这个地方为true的话,在我们使用其中一个属性的时候会将所有的属性加载出来,如果是false的话使用哪个属性就加载出哪个属性-->
<setting name="aggressivelazyLoading" value="false" />
实例6:查询某个部门下所有员工信息
collection嵌套结果集的方式,定义关联的集合类型元素的封装规则
第一步:写一个连表查询
第二步:
<!--
collection定义关联集合类型的属性的封装规则
ofType:指定集合里面原色的类型
-->
<collection property="okrRole" ofType="com.tan.bo.OkrRole">
<id column="okrRole_id" property="id" />
<result column="last_name" property="lastName"/>
</collection>
实例7:鉴别器
mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装的行为
<!--
鉴别器:mybatis可以使用discriminator判断某列的值,然后根据某列的值改变封装的行为
column:指定判断的列
javaType:列值对应的Java类型
-->
<discriminator javaType="" column="gengder">
<!--女生 resultMap:指定封装的结果类型-->
<case value="0" resultMap=""></case>
<!--男生 resultMap:指定封装的结果类型-->
<case value="1" resultMap=""></case>
</discriminator>