MyBatis进阶

目录

一、实现多表查询

二、#{}和${}

1、#{}和${}的使用

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

3、${}的使用场景

三、数据库连接池

1、数据库连接池概念

2、常见数据库连接池

3、修改连接池为Hikari

四、动态sql语句--xml

1、if标签

2、tirm标签

3、where标签

4、set标签

5、foreach标签

6、include标签

五、动态sql语句--注解


一、实现多表查询

1、准备两张表

userinfo表:

对应实体类:

articleinfo表:

对应实体类:

2、执行sql语句

若要查articleinfo表中id为1的书信息和用户信息,则需要进行多表查询。

多表查询的sql语句:select ta.id,ta.title,ta.content,ta.uid,tb.username,tb.age,tb.gender,tb.phone from articleinfo ta left join userinfo tb on ta.uid = tb.id where ta.id=1.

这时需要增加ArticleInfo类的属性,从而来接收多表查询的结果。

3、代码实现

4、测试

运行结果:

二、#{}和${}

#{}和${}都可以用于取参数值

1、#{}和${}的使用

(1)Integer类型的参数--根据id查询用户

#{}:

${}:

发现#{}是预编译sql,有?进行占位;${}是即时sql。

(2)String类型的参数--根据username查询用户

#{}:

${}:

当参数是字符串时,${}接收参数时,无法加引号,导致无法识别。

接收参数时将引号加上:

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

(1)#{}是预编译sql,性能更高;${}是即时sql。

即时sql的步骤:①解析语法和语义,检验sql语法是否正确;②优化sql语句,制定执行计划;③执行并返回结果。

预编译sql与即时sql的区别:一个sql语句若被反复执行或只是参数改变的,每一次执行若都需要经过以上步骤的话,则效率就会下降。此时预编译sql就会进行优化,编译一次sql语句后,就会将sql语句缓存起来,后面再执行这条语句时,不会再次编译,省去了解析优化等过程,直接执行,以此来提高效率。

(2)#{}更安全,${}有sql注入的风险。

sql注入:通过操作输入的参数,从而修改定义好的sql语句,已达到执行代码对服务器的攻击。

eg:根据username查询用户

正常输入username就会查询,但若进行sql注入的话:

'or 1='1一直为真,导致查询到所有结果。此时就是sql注入问题。

3、${}的使用场景

(1)排序功能

查询所有用户,并根据id升序

sql语句:select id,username,'password',age,gender,phone,delete_flag,create_time,update_time from userinfo order by id asc

#{}:

运行结果:

?处不应该有引号,所以不能使用#。

${}:

但需要考虑sql注入的问题,可以考虑升序和降序对应两个url,获取到url后由后台处理参数,客户端不输入参数。

(2)模糊匹配

查询姓名是‘l’开头的用户

sql语句:select id,username,'password',age,gender,phone,delete_flag,create_time,update_time from userinfo where username like '%l%';

#{}:

?处不应该有引号,所以不能使用#。

${}:

但需要考虑sql注入的问题,可以进行字符串拼接:

三、数据库连接池

1、数据库连接池概念

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个。

没有使用数据库连接池:每次在执行sql语句时,都需要重新进行数据库连接,建立一个新的连接对象,然后执行sql语句,语句执行完成后,再关闭连接释放资源。再次执行语句时,重复操作。这种重复的创建连接、释放资源比较消耗资源。

使用数据库连接池:程序启动时,会在数据库连接池创建一定数量的连接对象。每次在执行sql语句时,从线程池中拿连接对象,然后执行sql语句,语句执行完成后,再将连接对象放回连接池。减少了资源利用。

2、常见数据库连接池

C3P0、DBCP、Druid、Hikari。

springboot默认使用连接池为Druid

3、修改连接池为Hikari

引入相关依赖即可:

四、动态sql语句--xml

1、if标签

对于有一些属性,有默认值,比如userInfo中的gender的默认值为0,若该属性为非必填字段,如何使得不填值时为默认值,而不是为空值,此时可以使用if标签

(1)不使用if标签,gender不填值效果:

运行结果:

(2)使用if标签,gender不填值效果:

运行结果:

(3)if标签存在的问题

eg:

增加一个phone为空的userInfo对象,运行结果:

既然这样不行,那将逗号移到前面:

增加一个username为空的userInfo对象,运行结果:

我们发现,将逗号移到后面时,当最后一个属性为空时会报错;将逗号移到前面时,当第一个属性为空时会报错。有没有什么方法可以使得第一个属性为空时前面不会多一个逗号,最后一个属性为空时后面不会多一个逗号。考虑trim标签

2、tirm标签

(1)4个属性

(2)使用tirm标签解决上述问题

使用prefixOverrides删除前面多余逗号,使用suffixOverrides删除后面多余逗号;

可以使用prefix加'(',使用suffix加')'。

此时就可以很好的解决逗号问题了。

3、where标签

(1)不使用where标签存在的问题

根据username和age查询用户:

根据姓名为空的userInfo对象进行查询:

和逗号一样的问题,前一个属性为空,导致多出一个and,可以使用where标签解决问题。为什么不使用trim标签解决and问题???因为当属性都为空时,where也需要删除,但trim标签只能规定删除and,不能删除where,而where标签可以做到。

(2)where标签解决问题

此时就可以解决上述问题了。

4、set标签

可以解决在进行update操作时,删除可能多出的逗号,当然trim标签也可以。

5、foreach标签

对集合进行遍历时可以使用该标签。

例如:当需要删除多个用户时,传入的用户id就是一个集合,就需要遍历集合,根据id找到信息,从而进行删除。

运行结果:

6、include标签

可以对重复的代码片段进行抽取,降低冗余性。通过sql标签封装到一个SQL片段,然后再通过include标签进行引用。

代码实现:

include标签使用:

五、动态sql语句--注解

注解方法不推荐使用,单引号问题比较繁琐,且注解和xml的做法大同小异,以delete举个例子就能明白如何写了。

主要是在xml基础上加script标签,但要考虑单引号,不建议使用。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

ambition…

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

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

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

打赏作者

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

抵扣说明:

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

余额充值