MyBatis获取参数值的两种方式
MyBatis获取参数值的两种方式:${}和#{}
${}的本质就是字符串拼接,#{}的本质就是占位符赋值
${}使用字符串拼接的方式拼接sql,若为字符串类型或日期类型的字段进行赋值时,需要手动加单引号;但是#{}使用占位符方式拼接sql,此时为字符串类型或日期类型的字段进行赋值时,可以自动添加单引号
mapper接口方法的参数为单个字面量类型
第一种方式
注意单引号!
测试
第二种方式
测试
总结:
两种获取参数方式和参数名无关,只与位置有关,但是为了见名之义,最好和参数名一致
这样也可以获取到
mapper接口方法参数为多个
方式一
方式二
总结:
当mapper接口方法参数有多个时,MyBatis+会将这些参数放入一个同一个map中,以arg0,arg1......为键或以param1,param2......为键,参数为值(可以混用)
mapper接口方法参数为多个(情况2)
手动将多个参数放入一个map中存储
mapper接口方法的参数是一个实体类类型
以属性的方式访问属性值即可,需要属性有get方法
使用@param注解命名参数![](https://img-blog.csdnimg.cn/3f7e77ddff964fc2b9b5442a8f07224d.png)
参数为字面量类型和map类型的结合,自动将参数放入map中,以@Param注解的值为键,参数值为值。同时也以param1,param2......为键存放
MyBatis的各种查询功能
查询结果接收为实体类对象
单条数据
多条数据
使用集合
查询特殊值
返回值类型为Integer,resultType属性值可以是Integer/int 不区分大小写
MyBatis默认的类型别名
查询结果接收为map
单条数据
多条数据
利用集合
利用@MapKey注解
使用注解指定字段值作为map的键,查询到的每条数据转换成map集合作为值,放入同一个map中
当查询的结果没有实体类与之相吻合时使用map接收。
特殊SQL的执行
模糊查询
批量删除
只能使用${},因为#{}会自动添加单引号
动态设置表名
查询指定表
添加功能获取自增的主键
keyProperty:将自增的主键的值赋值给传输到映射文件中参数的某个属性
测试
获取到的自增主键,封装到了参数中的User对象中。
自定义映射resultMap
准备工作
新建表结构
部门表
员工表
随便添加一些测试数据
创建相应实体类(其中属性命名使用驼峰法),mapper接口,mapper映射文件
resultMap处理字段和属性的映射关系
解决字段名和属性名的映射关系
第一种方法:通过字段别名
第二种方法:通过核心配置文件的Settings标签
<!--设置MyBatis的全局配置-->
<settings>
<!--将下划线自动映射为驼峰,emp_name:empName-->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
此时不需要取别名也可以完成映射
第三种方式:通过resultMap
id:唯一标识,不能重复 type:设置映射关系中的类型 id:设置主键的映射关系
result:设置普通字段的映射关系
property:设置映射关系的属性名,必须是type属性所设置的实体类类型中的属性名
column:设置映射关系中的字段名,必须是sql语句查询出的字段名
解决多对一的映射关系
在Emp(员工)实体类中添加表示其所属部门的字段,并设置get,set方法,toString方法
此时数据库中的字段为did,为部门id,int类型
第一种方式:级联属性赋值
第二种方式:association
association:处理多对一的映射关系
property:需要处理多对一的映射关系的属性名
javaType:该属性的类型
第三种方式:分步查询
EmpMapper.xml
<resultMap id="EmpAndDeptByStepResultMap" type="emp">
<id property="eid" column="eid"></id>
<result property="empName" column="emp_name"></result>
<result property="age" column="age"></result>
<result property="sex" column="sex"></result>
<result property="email" column="email"></result>
<association property="dept" select="com.gyq.mybatis.mapper.DeptMapper.getEmpAndDeptByStepTwo"
column="did"></association>
</resultMap>
<!--Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);-->
<select id="getEmpAndDeptByStepOne" resultMap="EmpAndDeptByStepResultMap">
select *
from t_emp
where eid = #{eid}
</select>
select:设置分布查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
column:设置分布查询的条件
DeptMapper.xml
<!--Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);-->
<select id="getEmpAndDeptByStepTwo" resultType="Dept">
select *
from t_dept
where did = #{did}
</select>
分步查询的优点:可以实现延迟加载,但是必须在核心配置文件中设置全局配置变量:
lazyLoadingEnabled:延迟加载的全局开关。当开启时,所有关联对象都会延迟加载
aggressiveLazyLoading:当开启时,任何方法的调用都会加载该对象的所有属性,否则,每个属性会按需加载
此时就可以实现按需加载,获取的数据是什么,就只会执行相应的sql,此时可通过association和collection中的fetchType属性设置当前的分布查询是否使用延迟加载,fetchType=”lazy(延迟加载) | eager(立即加载)“
测试
当在核心配置文件中配置延迟加载
不配置延迟加载
当有些功能不需要延迟加载,可以单独在association标签添加一个fetchType属性(eager | lazy)
解决一对多的映射关系
在Dept(部门)实体类中添加表示部门员工的属性,get,set方法,toString方法
方式一:collection
方式二:分步查询
DeptMapper.xml
<resultMap id="deptAndEmpResultMap" type="dept">
<id property="did" column="did"></id>
<result property="deptName" column="dept_name"></result>
<collection property="emps" select="com.gyq.mybatis.mapper.EmpMapper.getDeptAndEmpByStepTwo" column="did">
</collection>
</resultMap>
<!--Dept getDeptAndEmpByStepOne(@Param("did") Integer did);-->
<select id="getDeptAndEmpByStepOne" resultMap="deptAndEmpResultMap">
select *
from t_dept
where did = #{did}
</select>
EmpMapper.xml