当前位置: 首页 > news >正文

ssm学习笔记day08mybatis

动态mysql if标签、where标签

现在思考一个情况,如果给你两个参数name和salary,让你寻找符合这两个条件的员工,但是只给了一个name或者salary,如果不采用动态标签,则找到的是否是我们想要的呢,即只满足name或者salary。
在这里插入图片描述
如果目前采用这种判断,一定是找满足emp_name = name && emp_salary = salary的。如果只给一个name,salary为空,找到的一定是满足emp_name = name && emp_salary = null,这和我们想要的答案不一致,我们想要的是emp_name = name。
这时候<if>标签登场了。
<if>有test属性,对test输入判断语句,只针对函数的输入的参数做出判断,如下图所示,只有满足非空才能插进去。

    <select id="queryEmpByNameAndSalary" resultType="com.atguigu.mybatis.bean.Emp">select * from t_empwhere<if test="name != null">emp_name = #{name}</if><if test="salary != null">and emp_salary = #{salary}</if></select>

但是这个语句是否正确呢,如果name为空,salary非空,或者两者为空,会不会出现问题。
name为空,salary非空的情况:
通过测试发现
在这里插入图片描述
在这里插入图片描述
会出现**where and emp_salary = ?**的错误。
现在我们来纠正这个写法,我们可以使用在最前面加一个1=1后面跟and **。

<select id="queryEmpByNameAndSalary" resultType="com.atguigu.mybatis.bean.Emp">select * from t_emp where1 = 1<if test="name != null">and emp_name = #{name}</if><if test="salary != null">and emp_salary = #{salary}</if></select>

使用改写法后无问题。
两者为空:
如果采用原写法,则会出现以下问题
在这里插入图片描述
采用修改后的写法如下,查询正常返回
在这里插入图片描述
那是否有更美观更简洁的写法呢,有的。采用<where>标签即可解决问题。<if>标签语句仍正常书写即可。

<select id="queryEmpByNameAndSalary" resultType="com.atguigu.mybatis.bean.Emp">select * from t_emp<where><if test="name != null">emp_name = #{name}</if><if test="salary != null">and emp_salary = #{salary}</if></where></select>

采用where标签后会自动帮你清除错误。
在这里插入图片描述

动态mysql set标签

和where标签类似,不过用于update中。如下所示

<update id="updateEmp">update t_emp<set><if test="empName != null">emp_name = #{empName},</if><if test="empSalary != null">emp_salary = #{empSalary},</if><if test="age!= null">age = #{age}</if></set>where id = #{id}</update>

动态mysql trim标签

有一个标签很强大,可以把<where><set>标签替代,这就是我们要讲的<trim>标签。
代替<where>如下

<select id="queryEmpByNameAndSalary" resultType="com.atguigu.mybatis.bean.Emp">select * from t_emp<trim prefix="where" prefixOverrides="and || or"><if test="name != null">emp_name = #{name}</if><if test="salary != null">and emp_salary = #{salary}</if></trim></select>

以下的几个主要属性
prefix:在 trim 的内容前面添加指定内容。
prefixOverrides:去除 trim 内容前面多余的字符,以空格作为分隔,会从最后一个分隔的字符开始判断是否去除。
suffix:在 trim 的内容后面添加指定内容。
suffixOverrides:去除 trim 内容后面多余的字符,以空格作为分隔,会从第一个分隔的字符开始判断是否去除。
上面的语句中,对where语句后面的,可能开头会出现and、or,我们要去掉才能得到一个合法的sql语句,所以prefixOverrides=“and || or”。
代替<set>如下

<update id="updateEmp">update t_emp<trim prefix="set" prefixOverrides="," suffix="where id = #{id}"><if test="empName != null">emp_name = #{empName},</if><if test="empSalary != null">emp_salary = #{empSalary},</if><if test="age!= null">age = #{age}</if></trim></update>

<where>不同的是<set>多了一个suffix。

动态mysql 分支选择choose、when、otherwise标签

<if>标签只有判断,如果我们要分支选择怎么办呢,即<choose><when><otherwise>标签。
使用方法如下

<select id="queryEmpByNameAndSalary" resultType="com.atguigu.mybatis.bean.Emp">select * from t_emp<where><choose><when test="name!=null">emp_name = name</when><when test="salary!=null">emp_salary = salary</when><otherwise></otherwise></choose></where>
</select>

choose套在外面,when相当于if,otherwise相当于else

动态mysql foreach标签

这个标签作为动态mysql功能最强的标签,也是我们学习的核心之一
主要属性
collection:必填属性,指定要遍历的集合。它的值根据传入参数类型的不同而不同。
如果传入的是单个集合对象(如List、Set),值为list。
如果传入的是数组,值为array。
若传入的是Map类型,collection指定Map中对应集合属性的键。
item:表示集合中每一个元素进行迭代时的别名。
index:指定在迭代过程中,当前元素在集合中的索引。在遍历List集合时,index是元素的下标;遍历Map时,index是Map的键。
open:表示该 SQL 语句以什么开始,比如(。
close:表示该 SQL 语句以什么结束,比如)。
separator:表示元素之间的分隔符,比如AND、,等。
示例
如果批量插入数据该怎么写,首先自己写一个SQL语句观察观察

insert into t_emp(emp_name , age , emp_salary) values ('zhangsan',18,33.2) , ('zhangsan2',19,33.2) , ('zhangsan3',20,34.2)

可以发现后面的(?,?,?)是重复的,我们对这个用<foreach>标签书写,如下所示,collection对应的是函数参数的名字,item是单个元素的别名,seperator是多个语句用什么分开。

<insert id="addEmps">insert into t_emp(emp_name , age , emp_salary) values<foreach collection="emps" item = "emp" separator=",">(#{emp.empName},#{emp.age},#{emp.empSalary})</foreach></insert>

同理,也搞一个批量修改的操作。

update t_emp SET emp_name = 'zhangsan01', age=18, emp_salary = 3.2 where id = 8 ;
update t_emp SET emp_name = 'zhangsan01', age=19, emp_salary = 34.2 where id = 9 ; 
update t_emp SET emp_name = 'zhangsan01', age=20, emp_salary = 34.2 where id = 10 ;
update t_emp SET emp_name = 'zhangsan01', age=21, emp_salary = 34.6 where id = 11 ;

不过与插入不同的时,不能缩成一句话,必须写成多句话,然后xml语句如下。

<update id="updateBatchEmp"><foreach collection="emps" item="emp" separator=";">update t_emp<set><if test="emp.empName!=null">emp_name = #{emp.empName},</if><if test="emp.age!=null">age=#{emp.age},</if><if test="emp.empSalary!=null">emp_salary = #{emp.empSalary}</if></set>where id = #{emp.id}</foreach></update>

ps:需要注意的是item不要写成index,我就因为这个然后报There is no getter for property named 'empName' in 'class java.lang.Integer'的错误,只能说下次遇到这个错误就知道什么问题了,然后后面的update批量操作,springboot默认是不认识这个分号’;'的,所以需要在application.prosperites上修改配置,在spring.datasource.url=jdbc:mysql://localhost:3306/mybatis-example后面加上?allowMultiQueries=true即可
在这里插入图片描述

动态sql sql、include标签

有些地方复用性比较高,于是我们对这些判断定义为公共变量。如下:

 <select id="getEmpById" resultType="com.atguigu.mybatis.bean.Emp">SELECT id , emp_name empName, age , emp_salary empSalary FROM t_emp WHERE id = #{id}</select>

比如id , emp_name empName, age , emp_salary empSalary的复用性比较高,我们对这个片段设置一个公共变量,然后复写到当前函数。<sql>标签是定义公共变量,<include>是引用<sql>标签的内容,用id指定对应的<sql>

<sql id="columns">id , emp_name empName, age , emp_salary</sql><!--    在里面写方法 , id绑定方法名 #{变量名} resultType返回类型--><select id="getEmpById" resultType="com.atguigu.mybatis.bean.Emp">SELECT <include refid="columns"></include> empSalary FROM t_emp WHERE id = #{id}</select>

文章转载自:
http://cavendish.jopebe.cn
http://befuddle.jopebe.cn
http://admass.jopebe.cn
http://alleged.jopebe.cn
http://aristarch.jopebe.cn
http://brd.jopebe.cn
http://buskined.jopebe.cn
http://cesarevitch.jopebe.cn
http://annihilationism.jopebe.cn
http://chiasma.jopebe.cn
http://agami.jopebe.cn
http://alarm.jopebe.cn
http://aberrated.jopebe.cn
http://calls.jopebe.cn
http://catbrier.jopebe.cn
http://adversely.jopebe.cn
http://angelica.jopebe.cn
http://canaan.jopebe.cn
http://albiness.jopebe.cn
http://avadavat.jopebe.cn
http://bivallate.jopebe.cn
http://buckler.jopebe.cn
http://charmeuse.jopebe.cn
http://cellulous.jopebe.cn
http://aflare.jopebe.cn
http://andalusite.jopebe.cn
http://anchoretic.jopebe.cn
http://bugloss.jopebe.cn
http://brede.jopebe.cn
http://beatles.jopebe.cn
http://www.dtcms.com/a/281227.html

相关文章:

  • ESP32轻松实现UDP无线通信
  • 使用python的pillow模块将图片转化为灰度图,获取值和修改值
  • 雷军的 IP 革命:人格化力量如何重塑商业规则|创客匠人
  • uniapp微信小程序弹窗
  • 《汇编语言:基于X86处理器》第8章 高级过程(1)
  • 被人工智能激活的哲学
  • 短剧小程序的「技术革命」:从「粗放生长」到「精准运营」
  • Windows内核对象
  • 新方法!家长可用安卓或苹果,远程管理孩子使用iPhone的时长
  • LeetCode|Day12|58. 最后一个单词的长度|Python刷题笔记
  • 跨平台游戏引擎 Axmol-2.7.1 发布
  • C#中Static关键字解析
  • k8s环境使用Operator部署Seaweedfs集群(上)
  • AJAX 入门到精通
  • 堆内存、栈内存、内存地址
  • 作业:复制数组
  • EndNote
  • 【Keil】C/C++混合编程的简单方法
  • DGNNet:基于双图神经网络的少样本故障诊断学习模型
  • 深入浅出 RabbitMQ-核心概念介绍与容器化部署
  • Element plus参考vben逻辑实现的描述列表组件封装实践
  • 【PTA数据结构 | C语言版】二叉树前序序列化
  • 差分信号接口选型指南:深入解析LVDS、SubLVDS、SLVDS与SLVDS-EC**
  • 《大数据技术原理与应用》实验报告五 熟悉 Hive 的基本操作
  • [AI8051U入门第三步]串口1使用-printf重定向(乱码解决办法)
  • Django+Celery 进阶:动态定时任务的添加、修改与智能调度实战
  • Android target34升级到35中的edge-to-edge适配
  • Nestjs框架: 数据库架构设计与 NestJS 多 ORM 动态数据库应用与连接池的配置
  • 利用android studio,对图片资源进行二次压缩
  • 基于Ruoyi和PostgreSQL的统一POI分类后台管理实战