mybatis动态查询(分页排序搜索)+分解关联查询+Logback 日志配置(打印sql到控制台)+mybatis新增记录后返回自增的id。批量=11/2~11/20

一、mybatis动态查询(分页排序搜索)

mybatis框架分页实现,有几种方式,最简单的就是利用原生的sql关键字limit来实现,还有一种就是利用interceptor来拼接sql,实现和limit一样的功能,再一个就是利用PageHelper来实现。
因为我是使用的limit实现,有分页,排序,搜索功能,这里记录一下:

//Mapper.xml
<select id="findXxx" resultType="com.Xxx">
        SELECT
        *
        FROM
        Xxx
        <where>
        有其他条件加在这里,先搜索,再排序,最后分页。limit要放最后
            <include refid="SearchCond"/>
            <include refid="SortCond"/>
            <include refid="PageCond"/>
        </where>
    </select>
    
    <sql id="PageCond">
        <if test="@java.util.Objects@nonNull(pageInfo)">
            limit #{pageInfo.offset, jdbcType = INTEGER}, #{pageInfo.pageSize, jdbcType = INTEGER}
        </if>
    </sql>

    <sql id="SearchCond">
        <if test="@java.util.Objects@nonNull(searchRequest)">
            <if test="searchRequest.fields != null and searchRequest.fields.size() != 0">
                <foreach collection="searchRequest.fields" item="field" index="index" open="and (" close=")" separator="or">
                ${field} like concat ('%', #{searchRequest.keyword,jdbcType=VARCHAR} ,'%')
                </foreach>
            </if>
        </if>
    </sql>
    
    <sql id="SortCond">
        <if test="@java.util.Objects@nonNull(sortRequest) and @java.util.Objects@nonNull(sortRequest.field)">
            order by
               	${field}
            <choose>
                <when test="@java.util.Objects@nonNull(sortRequest.order) and sortRequest.order.toString.equals('DESC')">
                    desc
                </when>
                <otherwise/>
            </choose>
        </if>
    </sql>

//dao层
List<TagSet> findXxx(
            @Param("pageInfo") PageInfo pageInfo,
            @Param("searchRequest") SearchRequest searchRequest,
            @Param("sortRequest") SortRequest sortRequest);

//通用类,这个getOffset注意一下,如果不这样写也可以,就在Mapper.xml自己写。
public class PageInfo {
    private Integer pageIndex;
    private Integer pageSize;
    private Integer getOffset () {
        return (this.pageIndex - 1) * this.pageSize;
    }
}
public class SearchRequest {
    /**
     * 搜索字段名称
     * 可多选
     */
    private Set<String> fields;
    /**
     * 搜索关键字
     */
    private String keyword;
}
    public class SortRequest {
    private String field;
    private String order;
    public Sort.Direction getOrder() {
        if ("ascending".equalsIgnoreCase(order)) {
            return Sort.Direction.ASC;
        }
        return Sort.Direction.DESC;
    }
}

代码很简单,但是还是有很多细节需要注意,比如pageCond中的。如果我不是用的getOffset去获取的话,就只有用类似${(page-1)*size}的方式,当然这就没法防止sql注入。还有就是要考虑好各种情况,有时候参数不传的情况下自己的sql语句是否有语法错误等。

遗留问题:比如排序的时候,我们可能得到前端传过来的是updateTime,但是数据库字段是update_time。这就要自己写if判断然后转换了吗?有没有通用性更好的办法呢?

参考: mybatis三种分页方法

二、分解关联查询

《高性能sql》中有提到:分解了关联查询后,可以让缓存的效率更高;执行单个查询可以减少锁的竞争;在应用层做关联可以更容易做到高性能和可扩展;本身查询效率更高;减少冗余记录等优势。所以我应该减少关联查询。
在这里插入图片描述

三、logback 日志配置

日志级别:TRACE < DEBUG < INFO < WARN < ERROR < FATAL
springboot默认情况下是利用logback把info级别打印到控制台:
root标签可以改变你想打印的级别,比如debug,就会打印等于和大于该级别的日志。

<root level="DEBUG">

当然,想打印sql语句就需要用到logger标签,把dao层设为:

<logger name="com.xxx.dao" level="DEBUG" />

最后,如果设置了过滤级别,也需要同步修改,不然不生效

 <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>info</level>
        </filter>

参考:
SpringBoot项目的logback日志配置(包括打印mybatis的sql语句)

四、mybatis新增记录后返回自增的id。批量

单个自增id
这个好理解,直接加上useGeneratedKeys=“true” keyProperty=“user.Id”,就可以。

<insert id="insertXxx" useGeneratedKeys="true" keyProperty="xxx.id">
取这个id的话就:xxx.getId()

不过网上说有坑需要注意:主键要设自增,dao层不要用@param。
批量

我遇到的问题是:批量插入数据,永远只返回最后一个id。
解决:问题出在xml文件的写法上。我写成了<foreach>insert XXXXXX</foreach>。这样会导致只返回最后一个自增id。应该写成insertXXX<foreach>(XX,XX,XX)</foreach>。简单来说就是一个insert就够了,foreach标签位置要放对。如果很多insert的话感觉就会把前面的覆盖掉了。。。(不太懂底层是怎样的)

<insert id="insertList" useGeneratedKeys="true" keyProperty="dbId" keyColumn="dbId">
        INSERT INTO `aity`.`xxx`(`name`, `color`)
        <foreach collection="list" item="c" index="index" open="VALUES" separator=",">
            (#{c.name, jdbcType=VARCHAR},
            #{c.color, jdbcType=VARCHAR})
        </foreach>
    </insert>
    
//dao层
void insertList(List<Xxx> list);

取的话也好取,同样什么传入的就什么接收id,这里就是list了。for(Xxx l : list){l.getDbId()}

参考:
mybatis插入数据后返回自增主键ID详解

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值