一 Mybatis高级查询
1.1 ResutlMap属性
建立对象关系映射
resultType
如果实体的属性名与表中字段名称一致,将查询结果自动封装到实体类中
ResultMap
如果实体的属性名与表中字段名称不一致,可以使用ResultMap实现手动,封装到实体类中
<!--id:标签的唯一标识
type:封装后的实体类型-->
<resultMap id="userResultMap" type="com.lagou.domain.User">
<!--手动配置映射关系-->
<!--id:用来配置主键-->
<id property="id" column="id"></id>
<!--result:表中普通字段的封装-->
<result property="usernameabc" column="username"></result>
<result property="birthdayabc" column="birthday"></result>
<result property="sexabc" column="sex"></result>
<result property="addressabc" column="address"></result>
</resultMap>
1.2 多条件查询(三种)
1)方式一
使用 #{arg0}-#{argn} 或者 #{param1}-#{paramn} 获取参数
select*fromuserwhereid=#{param1}andusername=#{param2}
2)方式二
使用注解,引入 @Param() 注解获取参数
publicList<User>findByIdAndUsername2(@Param("id")intid,@Param("username")Stringusername);
<!--多条件查询:方式二-->
<select id="findByIdAndUsername2" resultMap="userResultMap">
Select * from user where id=#{id} and username=#{username}
</select>
3)方式三(推荐)
使用pojo对象传递参数
Public List<User> findByIdAndUsername3(Useruser);
<!--多条件查询:方式三-->
<select id="findByIdAndUsername3" resultMap="userResultMap" parameterType="user">
<!--参数要和实体类属性名称一样-->
Select * from user where id=#{id} and username=#{usernameabc}
</select>
1.3 模糊查询
1)方式一
<!--模糊查询方式一-->
<select id="findByUsername" resultMap="userResultMap" parameterType="string">
<!--#{}相当于占位符,引用参数的时候会自动加上单引号-->
Select * from user where username like #{username}
</select>
2)方式二
<!--模糊查询方式二-->
<select id="findByUsername2" resultMap="userResultMap" parameterType="string">
<!--paramterType是基本数据类型或者Strin的时候,${}里面的值只能写value
${}:sql是原样拼接-->
Select * from user where user name like'${value}'
</select>
3) ${} 与 #{} 区别【笔试题】
#{} :表示一个占位符号
- 通过 #{} 可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#
{}可以有效防止sql注入。
- #{} 可以接收简单类型值或pojo属性值。
- 如果parameterType传输单个简单类型值, #{} 括号中名称随便写。
${} :表示拼接sql串
- 通过 ${} 可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,会出现sql注入
问题。
- ${} 可以接收简单类型值或pojo属性值。
- 如果parameterType传输单个简单类型值, ${} 括号中只能是value。
- 补充:TextSqlNode.java 源码可以证明
二 Mybatis映射文件深入
2.1 返回主键
应用场景
我们很多时候有这种需求,向数据库插入一条记录后,希望能立即拿到这条记录在数据库中的主键
值。
<!--添加用户:获取返回主键:方式一
useGeneratedKeys:声明返回主键
keyProperty:把返回主键的值,封装到实体中的那个属性上
-->
<insert id="saveUser" parameterType="user" useGeneratedKeys="true" keyProperty="id">
Insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})
</insert>
注意:只适用于主键自增的数据库,mysql和sqlserver支持,oracle不行。
2.1.2 selectKey
<!--添加用户:获取返回主键:方式二
useGeneratedKeys:声明返回主键
keyProperty:把返回主键的值,封装到实体中的那个属性上
-->
<insert id="saveUser2" parameterType="user">
<!--selectKey:使用范围更广,支持所有类型数据库
order="AFTER":设置在sql语句执行前(后),执行此语句
keyColumn="id":指主键对应列名
keyProperty="id":把返回主键的值,封装到实体中的id属性上
resultType:返回类型-->
<selectKeyorder="AFTER" keyColumn="id" keyProperty="id" resultType="int">
SELECTLAST_INSERT_ID();
</selectKey>
Insert into user(username,birthday,sex,address)values(#{username},#{birthday},#{sex},#{address})
</insert>
2.2 动态SQL
应用场景
当我们要根据不同的条件,来执行不同的sql语句的时候,需要用到动态sql。
2.2.1 动态 SQL 之<if>
<!--动态sql之if:多条件查询-->
<select id="findByIdAndUsernameIf" parameterType="user" resultType="User">
Select * from user
<!--test里面写的就是表达式
<where>:相当于where1=1,但是如果没有条件的话,不会拼接上where关键字-->
<where>
<if test="id!=null">
And id=#{id}
</if>
<if test="username!=null">
andusername=#{username}
</if>
</where>
</select>
2.2.2 动态 SQL 之<set>
<!--动态sql之set:动态更新-->
<update id="updateIF" parameterType="user">
updateuser
<!--<set>:在更新的时候,会自动添加set关键字,还会去掉最后一个,-->
<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>
whereid=#{id}
</update>
2.2.3 动态 SQL 之<foreach>
<foreach>标签用于遍历集合,它的属性:
• collection:代表要遍历的集合元素
• open:代表语句的开始部分
• close:代表结束部分
• item:代表遍历集合的每个元素,生成的变量名
• sperator:代表分隔符
a)集合
<!--动态sql的foreach标签:多值查询,根据多个id值查询用户-->
<select id="findByList" parameterType="list" resultType="user">
<include refid="selectUser"/>
<where>
<!--
foreach:
collection:代表要遍历的集合元素,通常写collection或者list
open:代表语句的开始部分
close:代表语句的结束部分
item:代表遍历结合中的每个元素,生成的变量名
separator:分割符
Parameter'collection'notfound.-->
<foreach collection="list" open="idin("close=")" item="id"separator=",">
#{id}
</foreach>
</where>
</select>
b)数组
<!--动态sql的foreach标签:多值查询,根据多个id值查询用户-->
<select id="findByArray" parameterType="int" resultType="user">
<include refid="selectUser"/>
<where>
<!--
foreach:
collection:代表要遍历的集合元素,通常写collection或者list
open:代表语句的开始部分
close:代表语句的结束部分
item:代表遍历结合中的每个元素,生成的变量名
separator:分割符
Parameter'collection'notfound.-->
<foreach collection="array" open="idin("close=")" item="id" separator=",">
#{id}
</foreach>
</where>
</select>
2.3 SQL片段
映射文件中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
<sql id="selectUser">
select*fromuser
</sql>
<include refid="selectUser"/>
MyBatis映射文件配置
<select>:查询
<insert>:插入
<update>:修改
<delete>:删除
<selectKey>:返回主键
<where>:where条件
<if>:if判断
<foreach>:for循环
<set>:set设置
<sql>:sql片段抽取
三 Mybatis核心配置文件深入
3.1 plugins标签
MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封
装,使用简单的方式即可获得分页的相关数据
开发步骤:
①导入通用PageHelper的坐标
②在mybatis核心配置文件中配置PageHelper插件
③测试分页数据获取
①
<!--分页助手-->
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>3.7.5</version>
</dependency>
<dependency>
<groupId>com.github.jsqlparser</groupId>
<artifactId>jsqlparser</artifactId>
<version>0.9.1</version>
</dependency>
②
<plugins>
<plugin interceptor="com.github.pagehelper.PageHelper">
<!--dialect:指定方言mysql分页关键字limit-->
<property name="dialect" value="mysql"/>
</plugin>
</plugins>
3.2 知识小结
MyBatis核心配置文件常用标签:
1、properties标签:该标签可以加载外部的properties文件
2、typeAliases标签:设置类型别名
3、environments标签:数据源环境配置标签
4、plugins标签:配置MyBatis的插件