mybatis之动态SQL和分页

动态SQL中本章只讲if/foreach

  • mybatis的动态sql语句是基于OGNL表达式的。可以方便的在sql语句中实现某些逻辑. 总体说来mybatis动态SQL语句主要有以下几类:
  1. if 语句 (简单的条件判断)
  2. choose (when,otherwize) ,相当于java 语言中的 switch ,与 jstl 中的choose 很类似
  3. trim (对包含的内容加上 prefix,或者 suffix 等,前缀,后缀)
  4. where (主要是用来简化sql语句中where条件判断的,能智能的处理 and or ,不必担心多余导致语法错误)
  5. set (主要用于更新时)
  6. foreach (在实现 mybatis in 语句查询时特别有用)

Mybatis中模糊查询的各种写法

#{exp}/${exp}

在这里插入图片描述
在这里插入图片描述

#与$的区别
前提:参数类型为字符串,#会在前后加单引号[’],$则直接插入值

  1. sql中字符串拼接(推荐)
    SELECT * FROM tableName WHERE name LIKE CONCAT(CONCAT('%', #{text}), '%');注:CONCAT是mysql数据库中才有的
    SELECT * FROM tableName WHERE name LIKE like '%'+#{bookName}+'%';注:sqlserver中的写法
  2. 使用 ${...}代替 #{…}
    SELECT * FROM tableName WHERE name LIKE '%${text}%';
    #与$的区别
    前提:参数类型为字符串,#会在前后加单引号[’],$则直接插入值
  3. 程序中拼接
    String searchText = “%” + text + “%”;
  4. 大小写匹配查询
    SELECT * FROM TABLENAME WHERE UPPER(SUBSYSTEM) LIKE '%' || UPPER('jz') || '%' 或者 SELECT * FROM TABLENAME WHERE LOWER(SUBSYSTEM) LIKE '%' || LOWER('jz') || '%'

注1:sql模糊查询中小于符号“<”报错,&lt; >(&gt;) <(&lt;) &(&amp;) 空格(&nbsp;)

注2:为防止SQL注入,一定要使用#进入赋值。什么是SQL注入参考附录一

  • mybatis中返回List集合
  1. 定义结果集
<!--为了简化开发,类名使用了别名-->
      <resultMap type="Book" id="bookList">
        <id property="bookId" column="book_id" />
        <result property="bookName" column="book_name" />
        <result property="bookPrice" column="book_price" />
        <result property="bookBrief" column="book_brief" />
      </resultMap>
  1. 指定结果集
	<select id="list" resultMap="bookList" parameterType="Book">
        select book_id, book_name, book_price, book_brief
        from t_book where 1=1
      </select>
       
  1. 为什么要重写mybatis的分页
    Mybatis的分页功能很弱,它是基于内存的分页(查出所有记录再按偏移量offset和边界limit取结果),在大数据量的情况下这样的分页基本上是没有用的
    selectList(String statement, Object parameter, RowBounds rowBounds)

使用pagehelper插件分页

  • 导入分页插件
	<dependency>
        <groupId>com.github.pagehelper</groupId>
        <artifactId>pagehelper</artifactId>
        <version>5.1.2</version>
      </dependency>
  • 将pagehelper插件配置到mybatis中
<!-- 配置分页插件PageHelper, 4.0.0以后的版本支持自动识别使用的数据库 -->
      <plugin interceptor="com.github.pagehelper.PageInterceptor">
      </plugin>
  • 在你需要进行分页的Mybatis方法前调用PageHelper.startPage静态方法即可,紧跟在这个方法后的第一个Mybatis查询方法会被进行分页
//设置分页处理
      if (null != pageBean && pageBean.isPaginate()) {
        PageHelper.startPage(pageBean.getPage(), pageBean.getRows());
      }
  • 获取分页信息(二种方式)
  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());
  1. 使用PageInfo
PageInfo pageInfo = new PageInfo(list);
          System.out.println("页码:" + pageInfo.getPageNum());
          System.out.println("页大小:" + pageInfo.getPageSize());
          System.out.println("总记录:" + pageInfo.getTotal());

如何数据库的数据并发问题

  • 通过version字段解决并发问题
throw new RuntimeException("对象已过期(ObjectExpired)或不存在(Object Not Found)")

   update t_book set book_price = #{bookPrice},version=version+1

   where book_id=#{bookId} and version=#vsersion#

附录

  • 以 MySQL 为例,如何进行 SQL 注入和防止被注入?
    MySQL为例,现在项目大部分都用框架实现,比如MyBatis框架,轻量级,功能强大:
    在MyBatis中,如果写${变量名},则为直接把传入的值填充到SQL语句中;
    如果写#{变量名},则为传入的值只能作为值,放到SQL语句中。
    举例:
    DELETE FROM student WHERE name=${stu_name}
    如果这样写,假如用户恶意传入这样一个字符串:abc OR 1=1,
    那么整个SQL就变成了
    DELETE FROM student WHERE name=abc OR 1=1,
    结果就是全部数据都删掉了。这就是SQL注入,如果把${stu_name}换成#{stu_name},那么依然传入上面的字符串,
    那么SQL是这样的:
    DELETE FROM student WHERE name=abc OR 1=1,会删除名字为abc OR 1=1的学生,没有这个学生则什么都删除不掉,这样就防止了SQL注入。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值