实验三: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,一经查实,立即删除!

相关文章

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;…

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

&#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的证…

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…

039集——渐变色之:CAD中画彩虹()(CAD—C#二次开发入门)

&#xff08;来左边儿 跟我一起画个龙&#xff0c;在你右边儿 画一道彩虹 ~~~~~~~~~~~ &#xff09; 效果如下&#xff1a; 以下展示部分颜色源码&#xff1a; namespace AcTools {public class Class1{public Wform.Timer timer;//定时器需建在类下面public s…

C++知识整理day3类与对象(下)——赋值运算符重载、取地址重载、列表初始化、友元、匿名对象、static

文章目录 1.赋值运算符重载1.1 运算符重载1.2 赋值运算符重载 2.取地址重载2.1 const成员函数2.2 取地址运算符重载 3.类与对象的补充3.1 再探构造函数---初始化列表3.2 类型转换3.3 static成员3.4 友元3.5 内部类3.6 匿名对象3.7 对象拷贝时的编译器优化 1.赋值运算符重载 赋…

web vue 滑动选择 n宫格选中 九宫格选中

页面动态布局经常性要交给客户来操作&#xff0c;他们按时他们的习惯在同一个屏幕内显示若干个子视图&#xff0c;尤其是在医学影像领域对于影像的同屏显示目视对比显的更为重要。 来看看如下的用户体验&#xff1a; 设计为最多支持5行6列页面展示后&#xff0c;右侧的布局则动…

解决idea使用maven打包时无法将本地lib库文件和resource目录中的资源文件打包进jar文件的问题!!!

一、问题复现 1&#xff09;项目结构如下 我们看到项目中手动添加了本地lib资源&#xff0c;同时bootspring的配置文件和mapper文件也放在了resouces目录中。 2&#xff09;上述结构的项目在使用maven打包时&#xff0c;最终生成的jar文件中将不包含lib库文件&#xff0c;甚…

【短视频矩阵系统==saas技术开发】

在数字媒体领域&#xff0c;短视频的崛起已不可忽视。对于商业实体而言&#xff0c;掌握如何通过短视频平台有效吸引潜在客户并提高转化率&#xff0c;已成为一项关键课题。本文旨在深入剖析短视频矩阵系统的构成与作用机制&#xff0c;以期为企业提供一套系统化的策略&#xf…

C_字符串的一些函数

1.字符串输入函数 scanf("%s",数组名)&#xff1b; gets(数组名)&#xff1b; 区别&#xff1a; scanf(“%s”,数组名); 把空格识别为输入结束 #include <stdio.h>int main() {char a[10];printf("输入&#xff1a;");scanf("%s",a)…

JavaScript实现tab栏切换

JavaScript实现tab栏切换 代码功能概述 这段代码实现了一个简单的选项卡&#xff08;Tab&#xff09;切换功能。它通过操作 HTML 元素的类名&#xff08;class&#xff09;来控制哪些选项卡&#xff08;Tab&#xff09;和对应的内容板块显示&#xff0c;哪些隐藏。基本思路是先…

《网络聊天室项目:全面分析测试报告》

目录 一、项目介绍二、项目功能三、测试计划1. 编写测试用例2. 实际执行测试的部分操作步骤3. 自动化测试 四、项目bug&#xff08;1&#xff09;bug描述&#xff08;2&#xff09;bug描述 五、项目总结 一、项目介绍 网络聊天室项目实现了一个网络交流平台&#xff0c;用户在w…