实验三:Mybatis-动态 SQL

news2024/12/23 13:07:27

目录:

一 、实验目的:

通过 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;
    }

    @Override
    public 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 mapper
        PUBLIC "-//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.Driver

jdbc.url=jdbc:mysql://localhost:3306/experience03

jdbc.username=root

jdbc.password=root

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

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//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 user
        where 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 user
        where 1=1
        <if test="username != null and username != ''">
            and username like '%${username}%'
        </if>
        <if test="sex != null and sex != ''">
            and sex = #{sex}
        </if>
    </select>

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

②实验效果

测试类:

@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();
    }

如上图所示,测试 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>

测试类:

@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();
    }

②实验效果


(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;
    }

    @Override
    public 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>

③测试方法如下图:

@Test
    public 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.coloradmin.cn/o/2255746.html

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

相关文章

NLP论文速读(斯坦福大学)|使用Tree将语法隐藏到Transformer语言模型中正则化

论文速读|Sneaking Syntax into Transformer Language Models with Tree Regularization 论文信息&#xff1a; 简介&#xff1a; 本文的背景是基于人类语言理解的组合性特征&#xff0c;即语言处理本质上是层次化的&#xff1a;语法规则将词级别的意义组合成更大的成分的意义&…

C++STL容器vector容器大小相关函数

目录 前言 主要参考 vector::size vector::max_size vector::resize vector::capacity vector::empty vector::reserve vector::shrink_to_fit 共勉 前言 本文将讨论STL容器vector中与迭代器相关的函数&#xff0c;模板参数T为int类型。 主要参考 cpluscplus.com 侯…

后端-编辑按钮的实现

编辑一共要实现两步&#xff1a; 1.点击编辑蹦出来一个弹窗&#xff0c;此时需要回显&#xff0c;根据id查出来这条数据 2.修改某些值之后点击保存的时候调用修改的接口 根据id查询的时候正常操作 修改值的时候要注意一些问题 mapper层的Employee和impl层的接收实体不一样

Spring Boot漫画之家:漫画爱好者的数字图书馆

2 系统开发环境 2.1 JAVA简介 JavaScript是一种网络脚本语言&#xff0c;广泛运用于web应用开发&#xff0c;可以用来添加网页的格式动态效果&#xff0c;该语言不用进行预编译就直接运行&#xff0c;可以直接嵌入HTML语言中&#xff0c;写成js语言&#xff0c;便于结构的分离&…

RISC-V 汇编语言

安装RISCV工具链 riscv-gnu-toolchain工具链和模拟器安装记录 - 知乎 (zhihu.com) riscv-gnu-toolchain工具链分elf-gcc、linux-gnu-gcc两个版本&#xff0c;以及对应的32位和64位版本。两个版本的主要区别是&#xff1a; riscv32-unknown-elf-gcc、riscv64-unknown-elf-gcc…

长沙市的科技查新机构有哪些

中南大学图书馆科技查新站&#xff1a; 中南大学图书馆科技查新站成立于2003年12月&#xff0c;中南大学图书馆科技查新站作为教育部首批批准的科技查新工作站之一&#xff0c;具备了在全国范围内开展科技查新工作的专业资质。 长沙理工大学科技查新工作站&#xff1a; 长沙理…

Spring Data Elasticsearch

简介说明 spring-data-elasticsearch是比较好用的一个elasticsearch客户端&#xff0c;本文介绍如何使用它来操作ES。本文使用spring-boot-starter-data-elasticsearch&#xff0c;它内部会引入spring-data-elasticsearch。 Spring Data ElasticSearch有下边这几种方法操作El…

【Web】AlpacaHack Round 7 (Web) 题解

Treasure Hunt flag在md5值拼接flagtxt的文件里&#xff0c;如 d/4/1/d/8/c/d/9/8/f/0/0/b/2/0/4/e/9/8/0/0/9/9/8/e/c/f/8/4/2/7/e/f/l/a/g/t/x/t 访问已经存在的目录状态码是301 访问不存在的目录状态码是404 基于此差异可以写爆破脚本 这段waf可以用url编码绕过 做个lab …

【数字电路与逻辑设计】实验五 4人表决器

文章总览&#xff1a;YuanDaiMa2048博客文章总览 【数字电路与逻辑设计】实验五 4人表决器 一、实验内容二、设计过程&#xff08;一&#xff09;设置变量&#xff08;二&#xff09;真值表&#xff08;三&#xff09;表达式 三、源代码&#xff08;一&#xff09;代码说明&…

解决Tomcat运行时错误:“Address localhost:1099 is already in use”

目录 背景: 过程&#xff1a; 报错的原因&#xff1a; 解决的方法&#xff1a; 总结&#xff1a; 直接结束Java.exe进程&#xff1a; 使用neststat -aon | findstr 1099 命令&#xff1a; 选择建议&#xff1a; 背景: 准备运行Tomcat服务器调试项目时&#xff0c;程序下…

【C++】刷题强训(day13)--牛牛冲钻五、最长无重复字数组、重排字符串

目录 1、牛牛冲钻五 1. 题目 1.2 思路 1.3 代码实现 2、最长无重复子数组 2.1 题目 2.2 思路 2.3 程序实现 3、重排字符串 3.1 题目 3.2 思路 3.3 代码实现 刷题汇总&#xff1a;传送门&#xff01; 1、牛牛冲钻五 1. 题目 1.2 思路 由题可知&#xff0c;赢一局则…

Kafka单机及集群部署及基础命令

目录 一、 Kafka介绍1、kafka定义2、传统消息队列应用场景3、kafka特点和优势4、kafka角色介绍5、分区和副本的优势6、kafka 写入消息的流程 二、Kafka单机部署1、基础环境2、iptables -L -n配置3、下载并解压kafka部署包至/usr/local/目录4、修改server.properties5、修改/etc…

在做题中学习(78):数组中第K个最大元素

解法&#xff1a;快速选择算法 说明&#xff1a;堆排序也是经典解决topK问题的算法&#xff0c;但时间复杂度为&#xff1a;O(NlogN) 而将要介绍的快速选择算法的时间复杂度为: O(N) 先看我的前两篇文章&#xff0c;分别学习&#xff1a;数组分三块&#xff0c;随机选择基准…

学习记录,正则表达式, 隐式转换

正则表达式 \\&#xff1a;表示正则表达式 W: 表示一个非字&#xff08;不是一个字&#xff0c;例如&#xff1a;空格&#xff0c;逗号&#xff0c;句号&#xff09; W: 多个非字 基本组成部分 1.字符字面量&#xff1a; 普通字符&#xff1a;在正则表达式中&#xff0c;大…

加载内核映像文件

将kernel转换成elf文件格式&#xff0c;不能直接从loader直接跳转到0x100000&#xff0c;需要解析&#xff0c;提取出代码和数据出来&#xff0c;放到0x10000&#xff08;64kb&#xff09;的位置&#xff0c;1M的位置只是存放elf文件的位置。 4.10加载内核映像文件2 common/el…

11.27-12.5谷粒商城

目录 新增商品 1.上线会员服务 2. 获取分类关联的品牌 3.获取选定分类下的属性分组和属性 4.新增商品vo 5.保存商品信息 6.Spu检索 7.Sku商品检索 新增商品 1.上线会员服务 将会员服务注册到nacos注册中心&#xff0c;启用服务注册发现EnableDiscoveryClient。 同时新增…

【硬件接口】UART接口

本文章是笔者整理的备忘笔记。希望在帮助自己温习避免遗忘的同时&#xff0c;也能帮助其他需要参考的朋友。如有谬误&#xff0c;欢迎大家进行指正。 一、UART接口概要 UART接口&#xff0c;即通用异步接收器/发送器&#xff0c;是一种常用的串行通信协议&#xff0c;广泛应用…

python | print() 函数常被忽略的几点用法

在 python 编程中&#xff0c;print() 是最为基础和常用的函数。 也正因如此&#xff0c;print() 函数的一些基础用法常常被我们初学者所忽略&#xff0c;典型的有&#xff1a;换行问题、间隔符使用及格式化输出等。 一、print() 换行问题 1、默认情况下&#xff0c;每一个 …

VTK编程指南<五>:VTK中的坐标系统、空间变换及VTK矩阵详解

1、坐标系统 计算机图形学里常用的坐标系统主要有 4 种&#xff0c;分别是 Model 坐标系统、World 坐标系统、View坐标系统和 Display坐标系统(这些名词在不同的书里的中文表述均有所差别&#xff0c;所以直接使用英文名词表示)&#xff0c;此外还有两种表示坐标点的方式&#…

MaxEnt模型在物种分布模拟中如何应用?R语言+MaxEnt模型融合物种分布模拟、参数优化方法、结果分析制图与论文写作

目录 第一章 以问题导入的方式&#xff0c;深入掌握原理基础 第二章 常用数据检索与R语言自动化下载及可视化方法 第三章 R语言数据清洗与特征变量筛选 第四章 基于ArcGIS、R数据处理与进阶 第五章 基于Maxent的物种分布建模与预测 第六章 基于R语言的模型参数优化 第七…