mybatis和mybatisplus的使用,sql语句中#,$符号的区别

mybatis动态sql的编写

mybatis的一个重大好处是可写动态的sql,否则我们还需要在代码中判断。这里说的动态sql不是指使用参数,
是指使用if,else,choose等流程控制关键字,实例可以参考官网。

关于mybatis的参数变量,一个重要的区别就是#{},${}。# 表示该语句会使用sql预编译,其sql结构不会变,只会填入变量值。
而$会用字符代替,然后编译。典型的例子:

select  * from student where name = #{name};
select  * from student where name = ${name};

如果name值为1 or 1 =1,则语句变为:

select  * from student where name = '1 or 1 =1';
select  * from student where name = 1 or 1 =1;

  可以看到,$符号会改变sql的语句结构,增加了or关键字,可能出现sql注入问题,#则不存在。那就应该尽量使用#{},
那么是不是说${}就应该禁止呢?我们来看一下其他情况:

1.select * from student where name like '%#{name}%'; // 错误写法
2.select * from student where name like '%${name}%';

1语句在预编译是会变成:select * from student where name like '%’liyong’%',不符合sql语法,会报错,而后面就不会,
并且不会出现sql注入问题。如果一定要用#,则可以使用mysql的单双引号的间隔法:

select * from student where name like "%"#{name}"%"; // 字编译后会进行字符串的拼接
select * from student_class_${id} where name= '小王子' // 必须使用$,组成一个完整的表名

  下面来谈一下第二个主题,关于@param注解的使用。这两篇博文有很好的解释。@Param的原理是将@Param注解的编码封装成了map,
所以在使用Map参数据的接口中,不应该使用@param注解,但是其他情况应尽量使用@param注解,未使用则会报如下错误。

The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: select * from news where news_abstract like %?% and item1 = ?
### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; 
check the manual that corresponds to your MySQL server version for 
the right syntax to use near '%'abstract'% and
item1 = 'dsdzfs'' at line 1

    近期的数据库和批量查询写法,让我对mybatis中的mapper文件的写法更加熟练了。

mybatisplus更加自动化

    项目中使用mybatisplus,瞟了一眼,主要就是替代了mybatis中的sql语句,具体是怎么替代的,可以理解为用成语代替白话文,比如:

select  * from student where name=“AA“;
queryWrapper.eq("name",AA");// 第二句在一定的语以环境下可以翻译成第一句话,且更具有结构化,出错更少。
  mybatisplus提供了AutoGenetor,用于快速生成controller,service,mapper等类和文件

queryWrapper.groupBy("CODE"); // group by会显著降低性能,一个数据库查询就耗费13.2s,mybatis好用,但不要滥用

  在mybatis中,参数主要分为单一类型: 比如int,string..., JavaBean对象,比如User,
以及集合,List,Map等3个大类。一般来说,不建议将单一类型和JavaBean对象混用,
会报错,有这种需求时,可以将其放入Map中,组成符合类型。
mybatisplus可以非常方便的使用QueryWarraper和insert,update函数,去掉了上面的sql函数。 同时还有一个非常好用的功能,官方文档说的非常清楚,yaml + annotation

limit a,b: 从a开始,长度为b。

SELECT * FROM tb_qualification WHERE id IN
 (SELECT A.qualification_id FROM
(SELECT qualification_id FROM tb_trade_qualification WHERE trade_id=#{arg0} LIMIT ${5*arg1},5) AS )

看这个limit的子查询语句,很具有经验意义,写的sql语句较少的人都不会遇到。博客上这样解释的:mybastis中limit的#{pageSize}不允许运算。所以得用$或者使用对象参数。

参考博文:
Mybatis框架:foreach循环遍历字段(为了解决动态表、动态字段查询数据)

MyBatis-plus 代码自动生成器

mybatis-plus官网,逻辑删除
mybatis之foreach用法

posted @ 2020-04-16 22:36  懂得了才能做一些改变  阅读(2262)  评论(0编辑  收藏  举报