1、mybatis动态sql是?
1.动态 SQL 是 MyBatis 的强大特性之一。在 JDBC 或其它类似的框架中,开发人员通常需要手动拼接 SQL 语句。根据不同的条件拼接 SQL 语句是一件极其痛苦的工作。例如,拼接时要确保添加了必要的空格,还要注意去掉列表最后一个列名的逗号。而动态 SQL 恰好解决了这一问题,可以根据场景动态的构建查询。
2.动态SQL:code that is executed dynamically。 它一般是根据用户输入或外部条件动态组合的SQL语句块。 动态SQL能灵活的发挥SQL强大的功能、方便的解决一些其它方法难以解决的问题。 相信使用过动态SQL的人都能体会到它带来的便利,然而动态SQL有时候在执行性能 (效率)上面不如静态SQL,而且使用不恰当,往往会在安全方面存在隐患 (SQL 注入式攻击)。
1.1、if和where标签
<!--动态Sql : where / if--> <select id="dynamicSql" resultType="com.lks.domain.User"> select <include refid="tableAllkey"/> from users <where> <if test="id != null and id != 0"> AND id = #{id} </if> <if test="name != null and name != ''"> AND name = #{name} </if> <if test="county != null and county != ''"> AND county = #{county} </if> </where> </select>
1.2、trim标签
mybatis中trim是动态拼接;java中表示去除前后空格
prefix:前缀
suffix:后缀
suffixOverride:去除后缀指定的字符
prefixOverrides:去除前缀指定的字符
<!--动态Sql: trim 标签--> <select id="dynamicSqlTrim" resultType="com.lks.domain.User"> select * from users <trim prefix="where" suffix="order by age" prefixOverrides="and | or" suffixOverrides=","> <if test="name != null and name != ''"> AND name = #{name} </if> <if test="county != null and county != ''"> AND county = #{county} </if> </trim> </select>
1.3、foreach标签
item :循环体中的具体对象。支持属性的点路径访问,如item.age,item.info.details,在list和数组中是其中的对象,在map中是value。
index :在list和数组中,index是元素的序号,在map中,index是元素的key,该参数可选。
open :表示该语句以什么开始
close :表示该语句以什么结束
separator :表示元素之间的分隔符,例如在in()的时候,separator=","会自动在元素中间用“,“隔开,避免手动输入逗号导致sql错误,如in(1,2,)这样。该参数可选。
//批量查询 <select id="findAll" resultType="Student" parameterType="Integer"> <include refid="selectvp"/> WHERE sid in <foreach item="ids" collection="array" open="(" separator="," close=")"> #{ids} </foreach> </select> //批量删除 <delete id="del" parameterType="Integer"> delete from student where sid in <foreach item="ids" collection="array" open="(" separator="," close=")"> #{ids} </foreach> </delete>
1.4、set/choose/otherwise/when标签
使用set标签可以将动态的配置 SET 关键字,并剔除追加到条件末尾的任何不相关的逗号。使用 if+set 标签修改后,在进行表单更新的操作中,哪个字段中有值才去更新,如果某项为 null 则不进行更新,而是保持数据库原值。
<!--动态Sql: set 标签--> <update id="updateSet" parameterType="com.lks.domain.User"> update users <set> <if test="name != null and name != ''"> name = #{name}, </if> <if test="county != null and county != ''"> county = #{county}, </if> </set> where id = #{id} </update>
这三个标签需要组合在一起使用,类似于 Java 中的 switch、case、default。只有一个条件生效,也就是只执行满足的条件 when,没有满足的条件就执行 otherwise,表示默认条件。
<!--动态Sql: choose、when、otherwise 标签--> <select id="dynamicSql2" resultType="com.lks.domain.User"> select * from users <where> <choose> <when test="name != null and name != ''"> AND name = #{name} </when> <when test="county != null and county != ''"> AND county = #{county} </when> <otherwise> AND id = #{id} </otherwise> </choose> </where> </select>
2.模糊查询(3种方式)
2.1 参数中直接加入%%
2.2 使用${...}代替#{...}(不建议使用该方式,有SQL注入风险)
关键:#{...}与${...}区别?
参数类型为字符串,#会在前后加单引号['],$则直接插入值
注:
1) mybatis中使用OGNL表达式传递参数
2) 优先使用#{...}
3) ${...}方式存在SQL注入风险
2.3 SQL字符串拼接CONCAT
3.查询返回结果集
resultMap:适合使用返回值是自定义实体类的情况
resultType:适合使用返回值的数据类型是非自定义的,即jdk的提供的类型
3.1 使用resultMap返回自定义类型集合
3.2 使用resultType返回List<T>
3.3 使用resultType返回单个对象
3.4 使用resultType返回List<Map>,适用于多表查询返回结果集
3.5 使用resultType返回Map<String,Object>,适用于多表查询返回单个结果集
4.分页查询
为什么要重写mybatis的分页?
Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量offset和边界limit取结果),在大数据量的情况下这样的分页基本上是没有用的
4.1 导入分页插件
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.2</version> </dependency>
4.2 将pagehelper插件配置到mybatis中
<!-- 配置分页插件PageHelper, 4.0.0以后的版本支持自动识别使用的数据库 --> <plugin interceptor="com.github.pagehelper.PageInterceptor"> </plugin>
4.3 在你需要进行分页的Mybatis方法前调PageHelper.startPage静态方法即可,紧跟在这个方法后的第一个Mybatis查询方法会被进行分页
//设置分页处理 if (null != pageBean && pageBean.isPaginate()) { PageHelper.startPage(pageBean.getCurPage(), pageBean.getPageRecord()); }
4.4 获取分页信息(二种方式)
4.4.1 使用插件后,查询实际返回的是Page<E>,而非List<E>,Page继承了ArrayList,同时还包含分页相关的信息
Page<Book> page = (Page<Book>)list; System.out.println("页码:" + page.getPageNum()); System.out.println("页大小:" + page.getPageSize()); System.out.println("总记录:" + page.getTotal());
4.4.2 使用PageInfo
PageInfo pageInfo = new PageInfo(list); System.out.println("页码:" + pageInfo.getPageNum()); System.out.println("页大小:" + pageInfo.getPageSize()); System.out.println("总记录:" + pageInfo.getTotal());
5.特殊字符处理
>(>)
<(<)
&(&)
空格( )