mybatis相关记录:参数获取${}、#{},#{}是如何防止注入的?批处理插入和更新

mybatis的参数获取:${}、#{}

本质:就好像 JDBC 中 预编译的俩种参数化查询方式
${}:字符串拼接,可能造成SQL注入,需要手动拼接‘’
在这里插入图片描述
#{}:占位符赋值
在这里插入图片描述
为什么可以防止SQL注入?
#{}通过set方法为参数赋值会将传入参数字符串的'字符进行转义\'
大多数情况建议直接使用#{},尽量避免使用${}。有什么情况必须使用${}的?
当我们需要拼接的变量上不能带单引号时,就必须使用${}通过字符串拼接方式。例如:
1.当sql中表名是从参数中取的情况
2.order by排序语句中,因为order by 后边必须跟字段名,这个字段名不能带引号,如果带引号会被识别会字符串,而不是字段。

顺便贴下JDBC:JDBC编程之预编译SQL与防注入JDBC连接如何防止SQL注入?

在JDBC编程中,常用Statement、PreparedStatement 和 CallableStatement三种方式来执行查询语句,其中 Statement 用于通用查询, PreparedStatement 用于执行参数化查询,而 CallableStatement则是用于存储过程。
预编译的好:
① 安全性不同: PreparedStatement可以有效防止sql注入,而Statment不能防止sql注入。
② 语法不同:PreparedStatement可以有效防止sql注入,而Statment不能防止sql注入。
③ 效率不同:SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。

mybatis参数值获取的各种情况

1、Mapper接口方法的参数为单个的:
可以通过${}和#{}以任意的名称获取参数值,但是需要注意${}的单引号问题
2、Mapper接口方法的参数为多个:
Mybatis会将参数放在一个map集合中,以俩种方式进行存储
a > 以arg0,arg1…为键,以参数为值
b > 以param1,param2…为键,以参数为值
因此只需要通过#{}和${}以键的方式访问值即可,但是需要注意${}的单引号问题
3、Mapper接口方法多个参数,手动将参数放在一个map集合:
只需要通过#{}和${}以键的方式访问值即可,但是需要注意${}的单引号问题
4、Mapper接口方法的参数是实体类类型参数:
只需要通过#{}和${}以属性的方式访问属性值即可,但是需要注意${}的单引号问题
5、使用@Param注解命名参数:2和3的结合
Mybatis会将参数放在一个map集合中,以俩种方式进行存储
a > 以@Param注解的值为键,以参数为值
b > 以param1,param2…为键,以参数为值

mybatis的查询结果

1,若查询出的数据只有一条
a > 可以通过实体类对象接收
b > 可以通过集合接收
c > 可以通过map
2,若查询出的数据有多条,一定不能通过实体类对家接收,此时会抛异常TooManyResultsException
a > 可以通过一个实体类类型的list集合接收
b > 可以通过一个map类型的list集合接收
c > 可以在mapper接口的方法上添加@MapKey注解,此时将每条数据转化的map集合作为值,注解标注的某个字段作为键,放在同一个map中

mybatis的模糊查询,三种写法

1、select * from user where username like '%${username}%'存在SQL注入风险
2、select * from user where username like concat('%',#{username},'%')
3、select * from user where username like "%"#{username}"%"

mybatis插入获取自增主键

在映射文件的SQL语句中,使用useGeneratedKeys和keyProperty参数
useGeneratedkeys:设置当前标签中的sqL使用了自增的主键
keyProperty:将自增的主键的值赋值给传输到映射文件中参数的某个属性

mybatis 解决字段名和属性名映射问题的三种方法

参考:映射体系之ResultMap原理

1、通过resultMap自定义映射关系
resultMap的子标签:
id:主键字段
result:普通字段
association:关联字段,一对一
collection:关联字段,一对多
在这里插入图片描述 2、查询字段起别名 select user_id userId from user
3、通过全局配置mapUnderscoreToCamelCase的值为true,将下划线_自动映射为驼峰在这里插入图片描述

解决一对一关联映射关系,
a > 级联属性复制
b > association
c > 分步查询(推荐,实现延迟加载,mybatis默认不开启)

解决一对多关联映射关系,
a > collection
b > 分步查询(推荐,实现延迟加载,mybatis默认不开启)
可以通过子查询参数 fetchType设置或通过全局mybatis参数进行控制:
lazyLoadingEnabled: 全局懒加载开关 (默认false)
aggressiveLazyLoading: 任意方法触发加载 (默认false)
在这里插入图片描述在这里插入图片描述

mybatis的缓存

一级缓存:默认开启,sqlSession级别,对于同一个sqlSession查询的数据会进行缓存
一级缓存失效:
1、不同sqlSession对应不同一级缓存
2、同一sqlSession不同查询调节剂
3、同一sqlSession俩次查询间进行过其他操作
4、同一sqlSession俩次查询间清除了缓存

二级缓存:SQLSessionFactory级别,同一sqlSessionFactory创建的sqlSession查询的数据进行缓存
二级缓存开启条件:
a>在核心配置文件中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置
b>在映射文件中设置标签<cache/>
c>级缓存必须在SqISession关闭或提交之后有效
d>查询的数据所转换的实体类类型必须实现序列化的接口
使二级缓存失效的情况:
两次查询之间执行了任意的增剧改,会使一级和二级缓存同时失效

二级缓存相关配置:

  • eviction是缓存的淘汰算法,可选值有"LRU"、“FIFO”、“SOFT”、“WEAK”,缺省值是>- LRU
  • flashInterval指缓存过期时间,单位为毫秒,60000即为60秒,缺省值为空,即只要容量足够,永不过期
  • size指缓存多少个对象,默认值为1024
  • readOnly是否只读,如果为true,则所有相同的sql语句返回的是同一个对象(有助于提高性能,但并发操作同一条数据时,可能不安全),如果设置为false,则相同的sql,后面访问的是cache的clone副本。
  • type:二级缓存类型,默认使用mybatis,可以使用第三方缓存

缓存查询顺序:先查大范围
1、先查询二级缓存,因为二级缓存中可能会有其他程序已经查出来的数据,可以拿来直接使用。
2、如果二级缓存没有命中,再查询一级缓存(未close或commit)
3、如果一级缓存也没有命中,则查询数据库
4、SqlSession关闭之后,一级缓存中的数据会写入二级缓存

mybatis 批处理

参考:Mybatis 三种批量插入数据 方式

1、循环调用
2、foreach标签
3、批处理(ps:千万记得关闭sqlSession)
这里只贴一个批处理
比较:网传,都是在说批处理快在这里插入图片描述
我的测试结果:
分析:
影响因素①:开启了日志打印
影响因素②:我插入的对象只有俩个字段(不知道)
在这里插入图片描述
批处理优点:不需设置分批次批量插入也可(当然,设置了可能更快呢?)
速度:还行
分批次插入,中间可以设置等待时间,避免一次性提交过多数据库压力过大

	@Autowired
    private SqlSessionFactory sqlSessionFactory;
	
 	@Override
    public void insertBatch(List<Xxx> xxxs) {
        // 批处理
        SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH, false);
        XxxMapper mapper = sqlSession.getMapper(XxxMapper.class);
        xxxs.stream().forEach(xxx -> {
            mapper.insertZdDd(xxx);
        });
        sqlSession.commit();
        sqlSession.clearCache();
        sqlSession.close();
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

洪泽涛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值