实验三:Mybatis-动态 SQL

目录:

一 、实验目的:

通过 mybatis 提供的各种标签方法实现动态拼接 sql

二 、预习要求:

预习 if、choose、 when、where 等标签的用法

三、实验内容:

  1. 根据性别和名字查询用户
  2. 使用 if 标签改造 UserMapper.xml
  3. 使用 where 标签进行改造 UserMapper.xml
  4. 使用 Sql 片段改造 UserMapper.xml
  5. 利用 foreach 标签实现根据多个 id 查询用户信息

四、实验方法和步骤:

实验前准备:

①创建数据库experience03,创建表user,并插入以下数据:

CREATE DATABASE experience03;
USE experience03;DROP TABLE IF EXISTS `user`;
CREATE TABLE `user`  (`id` int(0) NOT NULL AUTO_INCREMENT,`username` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,`birthday` date NULL DEFAULT NULL,`sex` char(1) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,`address` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NULL DEFAULT NULL,PRIMARY KEY (`id`) USING BTREE
) ;INSERT INTO `user` VALUES (1, '关羽', '2024-09-29', '男', '蜀国');
INSERT INTO `user` VALUES (2, '梁王孙', '2024-09-11', '男', '北京市');
INSERT INTO `user` VALUES (3, '陈长生', '2024-05-14', '女', '京都西庙');
INSERT INTO `user` VALUES (4, '王婆', '2024-09-05', '女', '快远');
INSERT INTO `user` VALUES (5, '黄忠', '2016-07-24', '1', '三国');
INSERT INTO `user` VALUES (6, '张飞', '2024-10-16', '女', '三国');
INSERT INTO `user` VALUES (7, 'lucky', '2021-10-08', '男', '三国');
INSERT INTO `user` VALUES (14, '关羽', '2024-12-02', '男', '蜀国');

②配置pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"><modelVersion>4.0.0</modelVersion><groupId>com.haust</groupId><artifactId>experience03</artifactId><version>1.0-SNAPSHOT</version><dependencies><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.14</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><dependency><groupId>log4j</groupId><artifactId>log4j</artifactId><version>1.2.16</version></dependency></dependencies></project>

③编写User.java在com.haust.pojo中

package com.haust.pojo;import java.util.Date;public class User {private int id;private String username;private Date birthday;private String sex;private String address;public int getId() {return id;}public void setId(int id) {this.id = id;}public String getUsername() {return username;}public void setUsername(String username) {this.username = username;}public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}public String getSex() {return sex;}public void setSex(String sex) {this.sex = sex;}public String getAddress() {return address;}public void setAddress(String address) {this.address = address;}@Overridepublic String toString() {return "User{" +"id=" + id +", username='" + username + '\'' +", birthday=" + birthday +", sex='" + sex + '\'' +", address='" + address + '\'' +'}';}
}

在java/com/haust/mapper中创建UserMapper接口

package com.mapper;public interface UserMapper {
}

在resources/com/haust/mapper简历UserMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapperPUBLIC "-//mybatis.org//DTD Mapper 3.0//EN""http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace=""></mapper>

在resources下创建db.properties

jdbc.driver=com.mysql.cj.jdbc.Driverjdbc.url=jdbc:mysql://localhost:3306/experience03jdbc.username=rootjdbc.password=root

在resources根目录下配置mybatis-config.cml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configurationPUBLIC "-//mybatis.org//DTD Config 3.0//EN""http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><properties resource="db.properties"/>
<!--    <settings>-->
<!--        <setting name="logImpl" value="LOG4J"/>-->
<!--    </settings>--><typeAliases><typeAlias type="com.haust.pojo.User" alias="User"/></typeAliases><environments default="environment"><environment id="environment"><transactionManager type="JDBC"></transactionManager><dataSource type="POOLED"><property name="driver" value="${jdbc.driver}"/><property name="url" value="${jdbc.url}"/><property name="username" value="${jdbc.username}"/><property name="password" value="${jdbc.password}"/></dataSource></environment></environments><mappers><mapper resource="com/haust/mapper/UserMapper.xml"/></mappers>
</configuration>

(1)根据性别和名字查询用户

查询 sql:

SELECT id, username, birthday, sex, address 
FROM `user` 
where sex = '1' AND username LIKE '%张%'

①Mapper.xml 文件

UserMapper.xml 配置 sql,如下:

<select id="findUserUsernameAndSex" parameterType="com.haust.pojo.User" resultType="com.haust.pojo.User">select * from userwhere username like '%${username}%' and sex = #{sex}</select>

②Mapper 接口

编写 Mapper 接口,如下:

List<User> findUserUsernameAndSex(User user);

③测试方法

在 UserMapperTest 添加测试方法,如下:

@Test
public void test09() throws IOException {String resources = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resources);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();user.setSex("女");user.setUsername("王");List<User> list = userMapper.findUserUsernameAndSex(user);System.out.println(list);sqlSession.commit();sqlSession.close();
}

④实验效果

测试效果如下图:

如果注释掉 user.setSex("1"),测试结果如下图:

测试结果二很显然不合理。

按照之前所学的,要解决这个问题,需要编写多个 sql,查询条件越多,需要编写的 sql 就 更多了,显然这样是不靠谱的。

解决方案,使用动态 sql 的 if 标签


(2)使用 if 标签改造 UserMapper.xml

(二)使用 if 标签改造 UserMapper.xml

①改造 UserMapper.xml,如下:

<select id="findUserUsernameAndSex" parameterType="com.haust.pojo.User" resultType="com.haust.pojo.User">select * from userwhere 1=1<if test="username != null and username != ''">and username like '%${username}%'</if><if test="sex != null and sex != ''">and sex = #{sex}</if></select>

注意字符串类型的数据需要要做不等于空字符串校验。

②实验效果

测试类:

@Testpublic void test09() throws IOException {String resources = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resources);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();//    user.setSex("男");user.setUsername("王");List<User> list = userMapper.findUserUsernameAndSex(user);System.out.println(list);sqlSession.commit();sqlSession.close();}

如上图所示,测试 OK

注意:使用<if test="">后sex注释掉,会选择username作为唯一条件

(3)使用 where 标签进行改造 UserMapper.xml

(三)使用 where 标签进行改造 UserMapper.xml

上面的 sql 还有 where 1=1 这样的语句,很麻烦

可以使用 where 标签进行改造,where 标签可以自动添加 where,同时处理 sql 语句中第一个 and 关键字

①改造 UserMapper.xml,如下

<select id="findUserUsernameAndSex" parameterType="com.haust.pojo.User" resultType="com.haust.pojo.User">select * from user<where><if test="username != null and username != ''">and username like '%${username}%'</if><if test="sex != null and sex != ''">and sex = #{sex}</if></where></select>

测试类:

@Testpublic void test09() throws IOException {String resources = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resources);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);User user = new User();//    user.setSex("男");user.setUsername("王");List<User> list = userMapper.findUserUsernameAndSex(user);System.out.println(list);sqlSession.commit();sqlSession.close();}

②实验效果


(4)使用 Sql 片段改造 UserMapper.xml

使用 Sql 片段改造 UserMapper.xml Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的。

①把上面例子中的 id, username, birthday, sex, address 提取出来,作为 sql 片段,如下:

<select id="findUserUsernameAndSex" parameterType="com.haust.pojo.User" resultType="com.haust.pojo.User">select <include refid="userFields"></include> from user<where><if test="username != null and username != ''">and username like '%${username}%'</if><if test="sex != null and sex != ''">and sex = #{sex}</if></where></select><sql id="userFields">id, username, birthday, address, sex</sql>

如果要使用别的 Mapper.xml 配置的 sql 片段,可以在 refid 前面加上对应的 Mapper.xml 的

namespace。

(5)利用 foreach 标签实现根据多个 id 查询用户信息

利用 foreach 标签实现根据多个 id 查询用户信息

向 sql 传递数组或 List,mybatis 使用 foreach 解析,如下:

①根据多个 id 查询用户信息

查询 sql:

SELECT * FROM user WHERE id IN (1,3,4)

①在java/com/haust/pojo下创建 QueryVo

如下在 pojo 中定义 list 属性 ids 存储多个用户 id,并添加 getter/setter 方法

package com.haust.pojo;import java.util.List;public class QueryVo {private User user;private List<Integer> ids;public List<Integer> getIds() {return ids;}public void setIds(List<Integer> ids) {this.ids = ids;}public User getUser() {return user;}public void setUser(User user) {this.user = user;}@Overridepublic String toString() {return "QueryVo{" +"user=" + user +", ids=" + ids +'}';}
}

②Mapper.xml 文件

UserMapper.xml 添加 sql,如下:

<select id="findUserByList" parameterType="com.haust.pojo.QueryVo" resultType="com.haust.pojo.User">select * from user where id in<foreach collection="list" item="id" index="index" separator="," open="(" close=")">#{id}</foreach></select>

③测试方法如下图:

@Testpublic void test10() throws IOException {String resources = "mybatis-config.xml";InputStream inputStream = Resources.getResourceAsStream(resources);SqlSessionFactory sqlSessionFactory =new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();UserMapper userMapper = sqlSession.getMapper(UserMapper.class);QueryVo queryVo = new QueryVo();List<Integer> list = new ArrayList();list.add(1);list.add(3);list.add(4);List<User> list1 = userMapper.findUserByList(list);for (User u:list1){System.out.println(u);}sqlSession.commit();sqlSession.close();}

④实验效果

测试效果如下图:

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/888409.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

pytorch加载预训练权重失败

问题 给当前模型换了个开源的主干网络&#xff0c;并且删除了某些层后&#xff0c;但是发现预训练权重一直加载不上。strict为True时加载报错&#xff0c;strict为False时又什么都加载不上&#xff0c;然后不知道哪里出问题了。 解决 当strict为False时&#xff0c;load_sta…

python 笔记之线程同步和死锁

同步&#xff1a; 共享数据&#xff1a; 如果多个线程共同对某个数据修改&#xff0c;则可能出现不可预测的结果&#xff0c;为了保证数据的正确性&#xff0c;需要对多个数据进行同步 同步&#xff1a;一个一个的完成&#xff0c;一个做完另一个才能进来 效率会降低 使用Thre…

Python爬虫——猫眼电影

用python中requests库爬取猫眼电影信息并保存到csv文件中 猫眼专业版 爬取界面 效果预览 代码 import requests import jsonurl1https://piaofang.maoyan.com/dashboard-ajax?orderType0&uuid1938bd58ddac8-02c2bbe3b009ed-4c657b58-144000-1938bd58ddac8&timeStamp…

python 三钱筮法项目开发

三钱筮法项目技术说明 1. 技术栈 GUI框架: CustomTkinter 现代化的Tkinter扩展提供美观的界面组件支持主题定制 数据存储: JSON 卦象数据: gua_info.json记忆数据: memory.json易经解释: detail.json 图像处理: PIL (Python Imaging Library) 处理图标和图片资源 2. 主要功…

yagmail邮件发送库:如何用Python实现自动化邮件营销?

&#x1f3a5; 作者简介&#xff1a; CSDN\阿里云\腾讯云\华为云开发社区优质创作者&#xff0c;专注分享大数据、Python、数据库、人工智能等领域的优质内容 &#x1f338;个人主页&#xff1a; 长风清留杨的博客 &#x1f343;形式准则&#xff1a; 无论成就大小&#xff0c;…

NLP 的研究任务

自然语言处理&#xff08;Natural Language Processing, NLP&#xff09; NLP 的研究任务 自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;1. **机器翻译**2. **情感分析**3. **智能问答**4. **文摘生成**5. **文本分类**6. **舆论分析**7. **知识图谱*…

无人机的计算机仿真模拟控制

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f916;编程探索专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年12月3日10点24分 神秘男子影, 秘而不宣藏。 泣意深不见, 男子自持重, 子夜独自沉。 论文链接 点击开启你的论文编程之旅h…

vue+mars3d给影像底图叠加炫酷效果

话不多说&#xff0c;直接上效果图&#xff1a; 在这里墙体其实是有一个不太明显的流动效果 实现方式&#xff1a;这里我使用了PolylineEntityWallPrimitive&#xff0c;开始我用的是polygonEntity但是发现实现效果并不好&#xff0c;所有直接改用了线 map.vue文件&#xff1…

浅谈volatile

volatile有三个特性&#xff1a; &#xff08;1&#xff09;可见性 &#xff08;2&#xff09;不保证原子性 &#xff08;3&#xff09;禁止指令重排 下面我们一一介绍 &#xff08;一&#xff09;可见性 volatile的可见性是说共享变量只要修改&#xff0c;就可以被其他线…

Redis自学之路—高级特性(实现消息队列)(七)

目录 简介 Redis的Key和Value的数据结构组织 全局哈希表 渐进式rehash 发布和订阅 操作命令 publish 发布消息 subscribe 订阅消息 psubscribe订阅频道 unsubscribe 取消订阅一个或多个频道 punsubscribe 取消订阅一个或多个模式 查询订阅情况-查看活跃的频道 查询…

Java-09 深入浅出 MyBatis - 注解开发 注解映射 基本介绍 与 一对一模型

点一下关注吧&#xff01;&#xff01;&#xff01;非常感谢&#xff01;&#xff01;持续更新&#xff01;&#xff01;&#xff01; 大数据篇正在更新&#xff01;https://blog.csdn.net/w776341482/category_12713819.html 目前已经更新到了&#xff1a; MyBatis&#xff…

【k8s】kubelet 的相关证书

在 Kubernetes 集群中&#xff0c;kubelet 使用的证书通常存放在节点上的特定目录。这些证书用于 kubelet 与 API 服务器之间的安全通信。具体的位置可能会根据你的 Kubernetes 安装方式和配置有所不同&#xff0c;下图是我自己环境【通过 kubeadm 安装的集群】中的kubelet的证…

ES语法(一)概括

一、语法 1、请求方式 Elasticsearch&#xff08;ES&#xff09;使用基于 JSON 的查询 DSL&#xff08;领域特定语言&#xff09;来与数据交互。 一个 ElasticSearch 请求和任何 HTTP 请求一样由若干相同的部件组成&#xff1a; curl -X<VERB> <PROTOCOL>://&l…

Redis开发实践

在现代开发中&#xff0c;Redis 已经成为一种重要的高性能内存数据库。无论是作为缓存、消息队列还是排行榜的实现工具&#xff0c;它都表现出了极高的性能和灵活性。本文将带你了解 Redis 的基本概念&#xff0c;并通过 Python 示例代码实现 Redis 的核心功能。 文章目录 1. R…

【el-table】表格后端排序

在需要排序的列添加属性 sortable&#xff0c;后端排序&#xff0c;需将sortable设置为custom 如果需要自定义轮转添加 sort-orders 属性&#xff0c;数组中的元素需为以下三者之一&#xff1a;ascending 表示升序&#xff0c;descending 表示降序&#xff0c;null 表示还原为原…

Linux迁移gitlab容器

Linux迁移gitlab容器并配置 迁移gitlab容器本文分两部分&#xff0c;第一步在新服务器上安装相同版本的gitlab容器&#xff0c;可以在确定gitlab版本之后直接在docker上拉取&#xff0c;我这里直接从原服务器上将镜像打包加载到新服务器上。第二步从原服务器上操作备份文件&am…

3.建立本地仓库及常用命令

1.建立本地仓库 要使用Git对我们的代码进行版本控制&#xff0c;首先需要获得本地仓库 1&#xff09;在电脑的任意位置创建一个空目录&#xff0c;作为我们的本地Git仓库 2&#xff09;进入这个目录&#xff0c;右键点击Git Bash 窗口 3&#xff09;执行命令git init 4) 如果创…

Narya.ai正在寻找iOS工程师!#Mixlab内推

如果你对AI技术和iOS开发充满热情&#xff0c;这里有一个绝佳的机会加入一家专注于AI应用创新的初创公司。Narya.ai正在招聘iOS工程师&#xff0c;帮助他们开发下一代效率工具&#xff0c;旨在提升用户的日常生活效率与幸福感。 关于Narya.ai&#xff1a; 专注于AI应用层创新&a…

AI开发:生成式对抗网络入门 模型训练和图像生成 -Python 机器学习

阶段1&#xff1a;GAN是个啥&#xff1f; 生成式对抗网络&#xff08;Generative Adversarial Networks, GAN&#xff09;&#xff0c;名字听着就有点“对抗”的意思&#xff0c;没错&#xff01;它其实是两个神经网络互相斗智斗勇的游戏&#xff1a; 生成器&#xff08;Gene…

网络安全攻击和防范措施

常见的有四种网络安全攻击方式. 第一种是XSS跨站脚本攻击,往网页中插入恶意脚本代码以攻击用户. 防范措施有三种. 第一种是输入过滤,对用户的所有输入数据进行检测,过滤掉可能导致脚本的字符. 第二种是输出编码,使用工具对用户输入进行编码,使其中可能含有的HTML脚本变成普通…