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

Mybatis操作数据库(进阶)

一、动态SQL

dongtaiSQL是Mybatis的强大特性之一,能够完成不同条件下不同的sql拼接,可以参考官方文档:

https://mybatis.net.cn/dynamic-sql.html

(一)<if>标签(输入判断)

场景:当我们登录某网站进行注册,在资料提交时。

注册分为两种字段:必填字段和非必填字段,那如果在添加用户的时候有不确定的字段传入,程序应该如何实现呢? 这个时候就需要使用动态标签来判断了,比如添加的时候性别 gender 为非必填字段,具体实现如下:

UserInfoMapperXML.java文件:

package com.bite.mybatis.mapper;import com.bite.mybatis.model.UserInfo;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Param;import java.util.List;
@Mapper
public interface UserInfoMapperXML {Integer insertUserByCondition(UserInfo userInfo);
}

UserInfoMapperXML.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bite.mybatis.mapper.UserInfoMapperXML"><insert id="insertUserByCondition">INSERT INTO user_info (username,`password`,age,<if test="gender != null">gender,</if>phone)VALUES (#{username},#{password},#{age},<if test="gender != null">#{gender},</if>#{phone})</insert>
</mapper>

UserInfoMapperXMLTest.java文件:

package com.bite.mybatis.mapper;import com.bite.mybatis.model.UserInfo;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;import static org.junit.jupiter.api.Assertions.*;
@SpringBootTest
class UserInfoMapperXMLTest {@Autowiredprivate UserInfoMapperXML userInfoMapperXML;@Testvoid insertUserByCondition() {UserInfo userInfo = new UserInfo();userInfo.setUsername("zz");userInfo.setPassword("password");userInfo.setAge(18);userInfo.setPhone("10086");userInfoMapperXML.insertUserByCondition(userInfo);}}

测试结果:

从以上测试中可知,可以使用<if>标签来设置非必填项,如果用户没有输入该数据,就不会被填入,实现了动态SQL。


(二)<trim>标签(处理多个选填项)

之前的插入用户功能,只是有一个 gender 字段可能是选填项,如果有多个字段都为选填项,一般考虑使用标签结合标签,对多个字段都采取动态生成的方式。
标签中有如下属性:

  • prefix:表示整个语句块,以 prefix 的值作为前缀
  • suffix:表示整个语句块,以 suffix 的值作为后缀
  • prefixOverrides:表示整个语句块要去除掉的前缀
  • suffixOverrides:表示整个语句块要去除掉的后缀

UserInfoMapperXML.xml文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bite.mybatis.mapper.UserInfoMapperXML"><insert id="insertUserByCondition">INSERT INTO user_info<trim prefix="(" suffix=")" suffixOverrides=","><if test="username != null">username,</if><if test="password != null">`password`,</if><if test="age != null">age,</if><if test="gender != null">gender,</if><if test="phone != null">phone,</if></trim>VALUES<trim prefix="(" suffix=")" suffixOverrides=","><if test="username != null">#{username},</if><if test="password != null">#{password},</if><if test="age != null">#{age},</if><if test="gender != null">#{gender},</if><if test="phone != null">#{phone},</if></trim>
</insert>
</mapper>

上述代码会将参数的前后加上括号,并且去掉整个参数后面的逗号。


(三)<where>标签(条件查询)

当我们浏览购物平台时,会遇到对商品进行筛选的场景。

这种如何实现呢? 接下来我们看代码实现:需求:传入的用户对象,根据属性做where条件查询,用户对象中属性不为 null 的,都为查询条件。如username 为 "a",则查询条件为 where username="a"。

接口定义:

List<UserInfo> queryByCondition();

UserInfoMapperXML.xml文件:

    <select id="queryByCondition">select * from user_info<where><!-- 只有当属性不为null时,才会拼接该条件 --><if test="username != null">and username = #{username}</if><if test="age != null">and age = #{age}</if><if test="gender != null">and gender = #{gender}</if><if test="phone != null">and phone = #{phone}</if><if test="deleteFlag != null">and delete_flag = #{deleteFlag}</if></where></select>

当使用where标签时,如果语句块中有查询条件,会添加where关键字,还会去除最前面的and关键字。


(四)<set>标签(更新数据)

需求:根据传入的用户对象属性来更新用户数据,可以使用标签来指定动态内容。

接口定义:根据传入的用户 id 属性,修改其他不为 null 的属性。

接口定义:

Integer updateUserByCondition(UserInfo userInfo);

UserInfoMapperXML.xml文件:

根据指定的id修改数据库中的对应值。

<update id="updateUserByCondition" parameterType="com.bite.mybatis.model.UserInfo">UPDATE userinfo<set><if test="username != null">username = #{username},</if><if test="age != null">age = #{age},</if><if test="deleteFlag != null">delete_flag = #{deleteFlag},</if></set>WHERE id = #{id}</update>

测试代码:

@Testvoid updateUserByCondition() {UserInfo userInfo=new UserInfo();userInfo.setId(7);userInfo.setUsername("nn");userInfo.setAge(17);userInfoMapperXML.updateUserByCondition(userInfo);}

先创建出一个UserInfo对象,设置它的属性,然后在数据库中找到要修改的对象,将它的值改成才创建的对象的值。

使用<set>标签时,动态地在SQL语句中插入set关键字,并会删掉额外的逗号。(用于update语句中) 以上标签也可以使用 <trim prefix="set" suffixOverrides=",">替换。


(五)<foreach>标签(处理集合)

对集合进行遍历时可以使用该标签。标签有如下属性:

  • collection:绑定方法参数中的集合,如 List,Set,Map 或数组对象
  • item:遍历时的每一个对象
  • open:语句块开头的字符串
  • close:语句块结束的字符串
  • separator:每次遍历之间间隔的字符串

需求:根据多个userID,删除用户数据。

比如:sql语句为 delete from user_info where id in (1,2,3,4,5)

接口方法:

void deleteByIds(List<Integer> ids);

UserInfoMapperXML.xml文件:

<delete id="deleteByIds">delete from user_infowhere id in<foreach collection="ids" item="id" separator="," open="(" close=")">#{id}</foreach></delete>

测试代码:

@Testvoid deleteByIds() {List<Integer> ids=new ArrayList<>();ids.add(4);ids.add(8);userInfoMapperXML.deleteByIds(ids);}

(六)<include>标签

在xml映射文件中配置的sql,有时候可能会存在许多重复的片段,此时就会存在冗余的代码:

我们可以对重复的代码片段进行抽取,将其通过 <sql> 标签封装到一个 SQL 片段,然后再通过 <include> 标签进行引用。

  • <sql>:定义可重用的 SQL 片段
  • <include>:通过属性 refid,指定包含的 SQL 片段

使用<sql>语句来封装重复的SQL片段:

<sql id="allColumn">id, username, age, gender, phone, delete_flag, create_time, update_time
</sql>

使用<include>语句来使用封装好的SQL片段:

<select id="queryAllUser" resultMap="BaseMap">select<include refid="allColumn"></include>from userinfo
</select><select id="queryById" resultType="com.example.demo.model.UserInfo">select<include refid="allColumn"></include>from userinfo where id = #{id}
</select>

二、案例练习(表白墙)

在之前学习的案例中(https://blog.csdn.net/2301_79204376/article/details/151903418?spm=1011.2415.3001.5331),我们写了表白墙,但是一旦服务器重启,所有的数据都会消失。

想要数据不丢失,需要把数据存储在数据库中,接下来咱们使用Mybatis来实现数据的操作。


(一)数据准备

创建数据库

DROP TABLE IF EXISTS message_info;
CREATE TABLE `message_info` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`from` VARCHAR ( 127 ) NOT NULL,`to` VARCHAR ( 127 ) NOT NULL,`message` VARCHAR ( 256 ) NOT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常,1-删除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now() ON UPDATE now(),PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;

以上代码,在数据库中创建了一个名为message_info的表。


引入Mybatis和Mysql驱动依赖

有两种方式:

第一种:在pom文件中添加一下代码

<dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>3.0.3</version>
</dependency>
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
</dependency>

第二种:使用插件EditStarters来引入依赖

在添加处 右键选择Generate中的EditStarters插件

勾选SQL中的Mybatis Framework和Mysql Driver选项,即可添加驱动依赖。

配置Mysql账号和密码

spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false&allowPublicKeyRetrieval=trueusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver
mybatis:configuration: # 配置打印 MyBatis日志log-impl: org.apache.ibatis.logging.stdout.StdOutImplmap-underscore-to-camel-case: true # 配置驼峰自动转换

(二)后端代码

MessageInfo.java:

package com.bite.demo.model;import lombok.Data;import java.util.Date;@Data
public class MessageInfo {private Integer id;private String from;private String to;private String message;private Integer deleteFlag;private Date createTime;private Date updateTime;
}

MessageInfoMapper.java:

package com.bite.demo.mapper;import com.bite.demo.model.MessageInfo;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;import java.util.List;@Mapper
public interface MessageInfoMapper {@Select("select `id`, `from`, `to`, `message` from message_info where delete_flag=0")List<MessageInfo> queryAll();@Insert("insert into message_info (`from`, `to`, `message`) values(#{from}, #{to}, #{message})")Integer addMessage(MessageInfo messageInfo);
}

MessageInfoService.java:

package com.bite.demo.service;import com.bite.demo.mapper.MessageInfoMapper;
import com.bite.demo.model.MessageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class MessageInfoService {@Autowiredprivate MessageInfoMapper messageInfoMapper;public List<MessageInfo> queryAll() {return messageInfoMapper.queryAll();}public Integer addMessage(MessageInfo messageInfo) {return messageInfoMapper.addMessage(messageInfo);}
}

MessageInfoController.java:

package com.bite.demo.controller;import com.bite.demo.model.MessageInfo;
import com.bite.demo.service.MessageInfoService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RequestMapping("/message")
@RestController
public class MessageController {@Autowiredprivate MessageInfoService messageInfoService;@PostMapping("/publish")public String publish(@RequestBody MessageInfo messageInfo){//判断前端上传的数据是否合法if(!StringUtils.hasLength(messageInfo.getFrom())||!StringUtils.hasLength(messageInfo.getMessage())||!StringUtils.hasLength(messageInfo.getTo())){//返回json格式return "{\"ok\": 0}";}messageInfoService.addMessage(messageInfo);return "{\"ok\": 1}";}//获取所有留言@RequestMapping("getList")public List<MessageInfo> getList(){return messageInfoService.queryAll();}
}
http://www.dtcms.com/a/610437.html

相关文章:

  • 卡索(CASO)汽车调查:我们缺数据,但更缺的是对数据的“解读能力”
  • VsCode通过SSH远程连接云服务器遇到主机密钥变更问题
  • UE5.7:3D 内容生产的新范式
  • 横沥网站制作招聘外卖小程序源码
  • 网站建设 思路互联网工资一般有多少
  • 智能家居,需要的是“主控智能体”而不是“主控节点”
  • 数据科学每日总结--Day19--数据库
  • 公司做网站一般微信搜一搜seo优化
  • 智能包装加速产业重构,紧固件交付体系迎来新升级动力
  • 基于NLMS算法的自适应噪声消除方法研究
  • 精准配置重构光模块成本效能:深圳光特通信1X9、SFP单收/单发光模块
  • 手机怎么登录自己做的网站wordpress怎么加404
  • 网站备案在哪里备案象山县住房和城乡建设局网站
  • MEXA-1170HCLD 加热型 NOₓ测定装置技术解析
  • 科技感图片素材推荐:像素里的未来叙事探索
  • Spring Boot 3.X:Unable to connect to Redis错误记录
  • 深度学习--个人总结
  • RNN与LSTM详解:AI是如何“记住”信息的?
  • 临沂做网站的公司有哪些杭州网站搭建公司
  • 泰国公共建设网站免费网站建设平台 iis
  • 淄博企业网站排名优化创意营销新点子
  • 网站建设页面带声音wordpress设置后台自定义功能选项
  • 成都培训网站建设广东建设信息网行业服务版
  • 架构师人员技能模型
  • 分布式系统中数据库连接池之外资源瓶颈
  • 数据结构进阶——红黑树
  • 开源数据同步中间件(Dbsyncer)简单玩一下 mysql to mysql 的增量,全量配置
  • 在 VS Code 中用 MyBatis 操作数据库的 Spring Boot 示例
  • 唐山网站建设开发专业网站建设经费申请
  • Java 抽象类