课程任务主要内容:
* Mybatis高级查询
* 映射配置文件深入
* 核心配置文件深入
* Mybatis多表查询
* Mybatis嵌套查询
一 Mybatis高级查询
1.1 ResutlMap属性
* resultType
如果实体的属性名与表中字段名一致,将查询结果自动封装到实体类中
* ResutlMap
如果实体的属性名与表中字段名不一致,可以使用ResutlMap实现手动封装到实体类中
<resultMap id="userResultMap" type="user">
<id column="uid" property="id"></id>
<result column="NAME" property="username"></result>
<result column="PASSWORD" property="username"></result>
</resultMap>
<select id="findAllResultMap" resultMap="userResultMap">
SELECT id AS uid,username AS NAME,password AS PASSWORD FROM USER
</select>
注意:association 和collection标签的使用。
1.2 多条件查询(三种)
需求:根据id和username查询user表
1)方式一
使用 #{arg0}-#{argn} 或者 #{param1}-#{paramn} 获取参数
UserMapper****接口
public interface UserMapper {
public List<User> findByIdAndUsername1(Integer id, String username);
}
UserMapper.xml
<mapper namespace="com.lagou.mapper.UserMapper">
<select id="findByIdAndUsername1" resultType="user">
<!-- select * from user where id = #{arg0} and username = #{arg1} -->
select * from user where id = #{param1} and username = #{param2}
</select>
</mapper>
2)方式二
使用注解,引入 @Param() 注解获取参数**(注意:mapper配置文件中的参数字段,就是@Param() 中的字段)**
UserMapper****接口
public interface UserMapper {
public List<User> findByIdAndUsername2(@Param("id") Integer id,@Param("username") String username);
}
UserMapper.xml
<mapper namespace="com.lagou.mapper.UserMapper">
<select id="findByIdAndUsername2" resultType="user">
select * from user where id = #{id} and username = #{username}
</select>
</mapper>
3)方式三(推荐)
使用pojo对象传递参数**(注意:mapper配置文件中的参数字段,就是要和实体类中的字段相同)**
UserMapper****接口
public interface UserMapper {
public List<User> findByIdAndUsername3(User user);
}
UserMapper.xml
<mapper namespace="com.lagou.mapper.UserMapper">
<select id="findByIdAndUsername3" parameterType="com.lagou.domain.User" resultType="com.lagou.domain.User">
select * from user where id = #{id} and username = #{username}
</select>
</mapper>
1.3 模糊查询
注意:当parameterType的属性是实体类型则sql语句中的字段用实体类对应的字段用#{},是mybatis框架为我们设置好的一些常用的类型的别名(基本数据类型和string)时,如果字段是一个则可以随便写。
需求
根据username模糊查询user表
1)方式一
2)方式二
注意:和方式一区别就是#{}和${}
注意:当parameterType的属性是实体类型则sql语句中的字段用实体类对应的字段用 , 是 m y b a t i s 框 架 为 我 们 设 置 好 的 一 些 常 用 的 类 型 的 别 名 ( 基 本 数 据 类 型 和 s t r i n g ) 时 , 如 果 字 段 是 一 个 则 只 能 写 成 {},是mybatis框架为我们设置好的一些常用的类型的别名(基本数据类型和string)时,如果字段是一个则只能写成 ,是mybatis框架为我们设置好的一些常用的类型的别名(基本数据类型和string)时,如果字段是一个则只能写成{value}。****注意要加‘’。
3) ${} 与 #{} 区别【笔试题】
#{} :表示一个占位符号
通过 #{} 可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。
#{} 可以接收简单类型值或pojo属性值。
如果parameterType传输单个简单类型值, #{} 括号中名称随便写。
${} **😗*表示拼接ql串
通过 ${} 可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,会出现sql注入问题。
${} 可以接收简单类型值或pojo属性值。
如果parameterType传输单个简单类型值, ${} 括号中只能是value。
二 Mybatis映射文件深入
2.1 返回主键
应用场景
我们很多时候有这种需求,向数据库插入一条记录后,希望能立即拿到这条记录在数据库中的主键值。
2.1.1 useGeneratedKeys
注意:只适用于主键自增的数据库,mysql和sqlserver支持,oracle不支持
<!--
useGeneratedKeys="true" 声明返回主键
keyProperty="id" 把返回主键的值,封装到实体的id属性中
注意:只适用于主键自增的数据库,mysql和sqlserver支持,oracle不支持 -->
<insert id="save" parameterType="user" useGeneratedKeys="true" keyProperty="id">
INSERT INTO `user`(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
2.1.2 selectKey
<!--
selectKey 适用范围广,支持所有类型数据库
keyColumn="id" 指定主键列名
keyProperty="id" 指定主键封装到实体的id属性中
resultType="int" 指定主键类型
order="AFTER" 设置在sql语句执行前(后),执行此语句 -->
<insert id="save" parameterType="user">
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
SELECT LAST_INSERT_ID();
</selectKey>
INSERT INTO `user`(username,birthday,sex,address) values(#{username},
#{birthday},#{sex},#{address})
</insert>
2.2 动态SQL
应用场景
当我们要根据不同的条件,来执行不同的sql语句的时候,需要用到动态sql。(说白了就是需要判断然后sql拼接)
2.2.1 动态 SQL 之
需求
根据id和username查询,但是不确定两个都有值。
注意:where标签相当于 where 1=1,但是如果没有条件,就不会拼接where关键字
<!--
where标签相当于 where 1=1,但是如果没有条件,就不会拼接where关键字
-->
<select id="findByIdAndUsernameIf" parameterType="user" resultType="user">
SELECT * FROM `user`
<where>
<if test="id != null"> AND id = #{id} </if>
<if test="username != null"> AND username = #{username} </if>
</where>
</select>
2.2.2 动态 SQL 之
需求
动态更新user表数据,如果该属性有值就更新,没有值不做处理。
<!-- set标签在更新的时候,自动加上set关键字,然后去掉最后一个条件的逗号 -->
<update id="updateIf" parameterType="user">
UPDATE `user`
<set>
<if test="username != null">
username = #{username},
</if>
<if test="birthday != null">
birthday = #{birthday},
</if> <if test="sex !=null">
sex = #{sex}, </if>
<if test="address !=null">
address = #{address},
</if>
</set>
WHERE id = #{id}
</update>
2.2.3 动态 SQL 之
foreach****主要是用来做数据的循环遍历
例如: select * from user where id in (1,2,3) 在这样的语句中,传入的参数部分必须依靠foreach遍历才能实现。
标签用于遍历集合,它的属性:
• collection:代表要遍历的集合元素
• open:代表语句的开始部分
• close:代表结束部分
• item:代表遍历集合的每个元素,生成的变量名
• sperator:代表分隔符
<!-- 如果查询条件为普通类型 List集合,collection属性值为:collection 或者 list -->
<!-- 如果查询条件为普通类型 Array数组,collection属性值为:array, parameterType="int"-->
<select id="findByList" parameterType="list" resultType="user" >
SELECT * FROM `user`
<where>
<foreach collection="collection" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
2.2.4 总结
MyBatis映射文件配置
<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<selectKey>:返回主键
<where>:where条件
<if>:if判断
<foreach>:for循环
<set>:set设置
<sql>:sql片段抽取
注意:
<!-- where标签相当于 where 1=1,但是如果没有条件,就不会拼接where关键字 -->
<!-- set标签在更新的时候,自动加上set关键字,然后去掉最后一个条件的逗号 -->
<!-- 如果查询条件为普通类型 List集合,collection属性值为:collection 或者 list -->
<!-- 如果查询条件为普通类型 Array数组,collection属性值为:array, parameterType="int"-->
2.3 SQL片段
应用场景
映射文件中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
<!--抽取的sql片段-->
<sql id="selectUser">
SELECT * FROM `user`
</sql>
<select id="findByList" parameterType="list" resultType="user" >
<!--引入sql片段-->
<include refid="selectUser"></include>
<where>
<foreach collection="collection" open="id in(" close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>