Mybatis-代码走查问题整理

实践篇

1、#{}和${}的区别

${}
直接替换变量 (有sql注入风险),使用场景:当表名、字段名作为变量传入时。
#{}
(PreparedStatement) 预处理编译,先替换为? 然后赋值 添加单引号。

2、使用注解和xml文件sql的方式区别?

注解:简单明了,无需额外文件。但长sql格式不友好,且无法额外做if等逻辑处理。
sql:能弥补注解sql的缺点,但对于不同场景下共用sql的情况,要处理好参数是否必须传入的问题。

3、使用map接收结果集时,有时会遇到属性的类型与预想的不一致。

在使用Map接收时,“type”的数据类型并非Integer,而是Long。这里涉及到JavaType和JDBCType之间的对应关系,在给参数赋值和结果集两个地方都会遇到。

尽量不要用map(好存不好取,不透明),改用dto等对象实体。明确每个字段的类型。

select case a.type when 1 then 2 when 2 then 3 else 0 end as type from table 

4、使用druid时,默认批量插入失效?
druid为了安全考虑,默认不开启批量操作。需要手动配置,以下是在Springboot中的配置。

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource dataSource() {
        DruidDataSource datasource = new DruidDataSource();
        List<Filter> filters = new ArrayList<>();
        filters.add(wallFilter());
        datasource.setProxyFilters(filters);
        return datasource;
    }
     @Bean
    public WallFilter wallFilter(){
        WallFilter wallFilter = new WallFilter();
        //允许执行多条SQL
        WallConfig config = new WallConfig();
        config.setMultiStatementAllow(true);
        wallFilter.setConfig(config);
        return wallFilter;
    }

5、使用ResultMap接收结果集时,需要注意的问题

当遇到map中新增或删除属性或数据类型变更等问题时,要考虑其他使用该map的方法。

<resultMap id="BaseResultMap" type="com.aoji.model.TaskTemplateInfo">
    <id column="id" jdbcType="INTEGER" property="id" />
    <result column="code" jdbcType="VARCHAR" property="code" />
    <result column="message" jdbcType="VARCHAR" property="message" />
  </resultMap>

6、批量插入sql时,foreach两种方式的比较
第一种:✅

        insert into table (user_id,create_time, delete_status ) VALUES
        <foreach collection="add" item="item" separator=",">
            (#{item.userId},#{item.createTime}, #{item.deleteStatus})
        </foreach>

第二种:❌ (本质是多条insert,并非一条sql的批量操作。)

        <foreach collection="add" item="item" separator=",">
           insert into table (user_id,create_time, delete_status ) VALUES (#{item.userId},#{item.createTime}, #{item.deleteStatus})
        </foreach>

7、需要并发校验的场景,不要直接扔给数据库。

服务层面需处理并发同步问题,若直接扔给数据库,会加剧数据库压力。也会产生很多报错信息。

  <insert id="insertOrUpdateStudentMaterialManage" parameterType="list">
        INSERT INTO  table (
        `id`,`business_id`,`material_name`,`business_type`,`material_url`,`only_read`,`material_describe`,`material_sort`,
        `delete_status`,`operator_no`,`operator_name`
        )VALUES
        <foreach collection="list" item="material" separator=",">
            (#{material.id},#{material.businessId}, #{material.materialName}, #{material.businessType}, #{material.materialUrl},
            #{material.onlyRead},#{material.materialDescribe},#{material.materialSort},
            #{material.deleteStatus}, #{material.operatorNo},#{material.operatorName})
        </foreach>
        on duplicate key update
        material_name=values(material_name),business_type = values(business_type),material_url = values(material_url),
        only_read = values(only_read),material_describe = values(material_describe),
        material_sort = values(material_sort),delete_status=values(delete_status),
        operator_no=values(operator_no),operator_name=values(operator_name)
    </insert>

8、mapper中方法考虑是否复用时,一定要慎重!

一味的考虑sql语句的复用,会使得原本简单的sql变得十分复杂臃肿,难以维护。尽量参考单一原则,不能只看当前业务。

原理篇

1、为什么Mybatis不需要为Mapper接口提供实现类?
Mybatis通过动态代理,根据我们提供的xml文件或者CRUD注解,为mapper接口动态的生成实现类。
2、Mybatis的拦截器如何实现?
参见之前博客《【Review】Mybatis-以PageHelper为例分析拦截器》

未完待续…

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值