Mybatis进阶(动态SQL)

文章目录

    • 1.动态SQL
        • 1.基本介绍
          • 1.为什么需要动态SQL
          • 2.基本说明
          • 3.动态SQL常用标签
        • 2.环境搭建
          • 1.新建子模块
          • 2.删除不必要的两个文件夹
          • 3.创建基本结构
          • 4.父模块的pom.xml
          • 5.jdbc.properties
          • 6.mybatis-config.xml
          • 7.MyBatisUtils.java
          • 8.MonsterMapper.java
          • 9.MonsterMapper.xml
          • 10.测试MonsterMapperTest.java
        • 3.动态SQL-if标签
          • 1.需求分析
          • 2.MonsterMapper.java添加@Param注解
          • 3.MonsterMapper.xml
          • 4.测试
        • 4.动态SQL-where标签
          • 1.需求分析
          • 2.MonsterMapper.java添加方法
          • 3.MonsterMapper.xml添加实现类
          • 4.测试
        • 5.动态SQL-choose标签
          • 1.需求分析
          • 2.MonsterMapper.java添加方法
          • 3.MonsterMapper.xml添加实现类
          • 4.测试
        • 6.动态SQL-foreach标签
          • 1.需求分析
          • 2.MonsterMapper.java添加方法
          • 3.MonsterMapper.xml添加实现类
          • 4.测试
        • 7.动态SQL-set标签(重点)
          • 1.需求分析
          • 2. MonsterMapper.java添加方法
          • 3.MonsterMapper.xml
          • 4.测试

1.动态SQL

1.基本介绍
1.为什么需要动态SQL

image-20240304161024014

2.基本说明

image-20240304161328438

3.动态SQL常用标签

image-20240304161355168

2.环境搭建
1.新建子模块

image-20240304161536794

2.删除不必要的两个文件夹

image-20240304161639688

3.创建基本结构

image-20240304162428796

4.父模块的pom.xml
<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>org.example</groupId>
  <artifactId>mybatis</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>pom</packaging>
  <name>Archetype - mybatis</name>
  <url>http://maven.apache.org</url>
  <modules>
    <module>mybatis_quickstart</module>
    <module>xml-mapper</module>
    <module>dynamic-sql</module>
  </modules>
  <dependencies>
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.49</version>
    </dependency>
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis</artifactId>
      <version>3.5.7</version>
    </dependency>
    <dependency>
      <groupId>junit</groupId>
      <artifactId>junit</artifactId>
      <version>4.12</version>
      <!--如果设置scope为test,则只能在test包下使用-->
      <scope>test</scope>
    </dependency>
  </dependencies>
  <!--在父模块中的pom.xml文件中配置在build的时候要扫描的文件,解决某些类型文件拷贝到target目录失败的问题-->
  <build>
    <resources>
      <resource>
        <directory>src/main/java</directory>
        <includes>
          <!--在java文件夹下的多级目录下的xml文件-->
          <include>**/*.xml</include>
        </includes>
      </resource>
      <resource>
        <directory>src/main/resources</directory>
        <includes>
          <!--在resources文件夹下的多级目录下的xml文件和properties文件-->
          <include>**/*.xml</include>
          <include>**/*.properties</include>
        </includes>
      </resource>
    </resources>
  </build>
</project>

5.jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://127.0.0.1:3306/mybatis?useSSL=false&amp;useUnicode=true&amp;characterEncoding=UTF-8
jdbc.username=root
jdbc.password=root

6.mybatis-config.xml
  • 配置com.sun.entity的类型别名
  • 引入com.sun.mapper里的Mapper.xml文件或者带注解的类
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
        PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <!--引入外部文件jdbc.properties-->
    <properties resource="jdbc.properties"/>

    <!--配置mybatis自带的日志,settings需要放到最前面-->
    <settings>
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>

    <!--配置类型别名-->
    <typeAliases>
        <!--方式二:这样配置完了在这个包下的所有类都可以直接使用类名表示-->
        <package name="com.sun.entity"/>
    </typeAliases>

    <environments default="development">
        <environment id="development">
            <!--配置事务管理器-->
            <transactionManager type="JDBC"/>
            <!--配置数据源-->
            <dataSource type="POOLED">
                <!--配置驱动-->
                <property name="driver" value="${jdbc.driver}"/>
                <!--配置连接url-->
                <!--
                1.jdbc:mysql:协议
                2.127.0.0.1:3306:指定连接mysql的ip+端口
                3.mybatis:连接的db
                4.useSSL:使用安全连接
                5.&amp;:表示&
                6.useUnicode=true:使用unicode,防止编码错误
                7.characterEncoding=UTF-8:字符集使用utf-8
                -->
                <property name="url" value="${jdbc.url}"/>
                <!--用户名-->
                <property name="username" value="${jdbc.username}"/>
                <!--密码-->
                <property name="password" value="${jdbc.password}"/>
            </dataSource>
        </environment>
    </environments>

    <mappers>
        <!--包的方式引入含有Mapper.xml文件的类-->
        <package name="com.sun.mapper"/>
    </mappers>

</configuration>

7.MyBatisUtils.java
package com.util;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.IOException;
import java.io.InputStream;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class MyBatisUtils {
    private static SqlSessionFactory sqlSessionFactory;

    //使用静态代码块初始化SqlSessionFactory
    static {
        try {
            //获取Mybatis配置文件的输入流
            String resource = "mybatis-config.xml";
            //默认是从类路径下获取资源,在maven中指的就是resources文件夹下,会映射到实际的工作目录
            InputStream resourceAsStream = Resources.getResourceAsStream(resource);
            //读取资源获取SessionFactory,可以理解为连接池
            sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    //编写方法返回SqlSession
    public static SqlSession getSqlSession() {
        return sqlSessionFactory.openSession();
    }
}

8.MonsterMapper.java
package com.sun.mapper;



/**
 * 这个接口用于声明操作monster表的方法
 *
 * @author 孙显圣
 * @version 1.0
 */
public interface MonsterMapper {

}

9.MonsterMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定该xml文件和哪个接口对应-->
<mapper namespace="com.sun.mapper.MonsterMapper">

</mapper>
10.测试MonsterMapperTest.java
package com.sun.mapper;

import com.sun.entity.Monster;
import com.util.MyBatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Before;
import org.junit.Test;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author 孙显圣
 * @version 1.0
 */
public class MonsterMapperTest {
    //两个属性
    private SqlSession sqlSession; //相当于连接
    private MonsterMapper monsterMapper;

    //编写方法完成初始化
    @Before //标注了Before之后表示了在执行目标测试方法前会执行该方法
    public void init() {
        //获取到sqlSession
        sqlSession = MyBatisUtils.getSqlSession();
        //获取到MonsterMapper对象
        monsterMapper = sqlSession.getMapper(MonsterMapper.class);
        System.out.println(monsterMapper.getClass());
    }
    @Test

    public void test() {
        System.out.println("ttt");
    }

}

image-20240304163252656

3.动态SQL-if标签
1.需求分析

image-20240304163531716

2.MonsterMapper.java添加@Param注解
package com.sun.mapper;


import com.sun.entity.Monster;
import org.apache.ibatis.annotations.Param;

import java.util.List;

/**
 * 这个接口用于声明操作monster表的方法
 *
 * @author 孙显圣
 * @version 1.0
 */
public interface MonsterMapper {
    //使用@Param("age")注解来使得动态sql的test域可以取出这个age
    public List<Monster> findMonsterByAge(@Param("age") Integer age);
}

3.MonsterMapper.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
        PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
        "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--指定该xml文件和哪个接口对应-->
<mapper namespace="com.sun.mapper.MonsterMapper">
    <!--public List<Monster> findMonsterByAge(Integer age);
        要求:当用户输入的值不大于0则输出所有妖怪
    -->
    <select id="findMonsterByAge" resultType="Monster" parameterType="Integer">
        select * from monster where 1 = 1
        <!--这里的age是在参数中使用@Param注解取出的-->
        <if test="age >= 0">
            and age > #{age}
        </if>
    </select>
</mapper>
4.测试
    @Test
    public void findMonsterByAge() {
        List<Monster> list = monsterMapper.findMonsterByAge(10);
        for (Monster monster : list) {
            System.out.println(monster);
        }
        //关闭sqlsession
        if (sqlSession != null) {
            sqlSession.close();
        }
    }
4.动态SQL-where标签
1.需求分析

image-20240304171800511

2.MonsterMapper.java添加方法
    public List<Monster> findMonsterByIdAndName(Monster monster);
3.MonsterMapper.xml添加实现类
    <!--public List<Monster> findMonsterByIdAndName(Monster monster);
        1.id小于0则不拼接,名字为空也不拼接
        2.where标签会自动清除没用的and
		3.如果传入的是对象,就不用使用@Param
    -->
    <select id="findMonsterByIdAndName" resultType="Monster" parameterType="Monster">
        SELECT * FROM monster
        <where>
            <if test="id >= 0">
                and id > #{id}
            </if>
            <if test="name != null and name != ''">
                and `name` = #{name}
            </if>
        </where>
    </select>
4.测试
    @Test
    public void findMonsterByIdAndName() {
        Monster monster = new Monster();
        monster.setId(4);
        monster.setName("牛魔王");
        List<Monster> monsters = monsterMapper.findMonsterByIdAndName(monster);
        for (Monster monster1 : monsters) {
            System.out.println(monster1);
        }
        //关闭sqlsession
        if (sqlSession != null) {
            sqlSession.close();
        }
    }

image-20240304185503494

5.动态SQL-choose标签
1.需求分析

当name不为空和id>0的时候有不同的操作

2.MonsterMapper.java添加方法
    public List<Monster> findMonsterByIdOrName_choose(Map<String, Object> map);
3.MonsterMapper.xml添加实现类
<!--    public List<Monster> findMonsterByIdOrName_choose(Map<String, Object> map);-->
    <select id="findMonsterByIdOrName_choose" parameterType="map" resultType="Monster">
        select * from `monster`
        <choose>
            <when test="name != null and name != ''">
                where `name` = #{name}
            </when>
            <when test="id > 0">
                where `id` = #{id}
            </when>
            <otherwise>
                where `salary` > 100
            </otherwise>
        </choose>
    </select>
4.测试
    @Test
    public void findMonsterByIdOrName_choose() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", 2);
        map.put("name", "");
        List<Monster> list = monsterMapper.findMonsterByIdOrName_choose(map);
        for (Monster monster : list) {
            System.out.println(monster);
        }
    }
6.动态SQL-foreach标签
1.需求分析

查询id为1,2,3的妖怪

2.MonsterMapper.java添加方法
public List<Monster> findMonsterById_forEach(Map<String, Object> map);
3.MonsterMapper.xml添加实现类
    <select id="findMonsterById_forEach" parameterType="map" resultType="Monster">
        select * from `monster`
        <if test="ids != null and ids != ''">
            <where>
                id in
                <!--
                    map中传入一个ids集合为[1,2,3]
                    目标:id in (1,2,3)
                    collection:要遍历的集合
                    item:遍历的数据项
                    open:开始标志
                    close:结束标志
                    separator:数据间隔
                -->
                <foreach collection="ids" item="id" open="(" separator="," close=")">
                    <!--  这里取出的是item里的id-->
                    #{id}
                </foreach>
            </where>
        </if>
    </select>
4.测试
    @Test
    public void findMonsterById_forEach() {
        Map<String, Object> map = new HashMap<String, Object>();
        List<Integer> ids = new ArrayList<Integer>();
        ids.add(1);
        ids.add(2);
        ids.add(3);
        //添加一个集合key为ids
        List<Monster> list = monsterMapper.findMonsterById_forEach(map);
        for (Monster monster : list) {
            System.out.println(monster);
        }
    }
7.动态SQL-set标签(重点)
1.需求分析

image-20240305144952009

2. MonsterMapper.java添加方法
    public void updateMonster_set(Map<String, Object> map);
3.MonsterMapper.xml
    <!--根据id来对表进行修改,如果没有传值则不修改那个字段-->
    <!--public void updateMonster_set(Map<String, Object> map);-->
    <!--UPDATE monster , birthday = '2020-1-2', email = 'libai@qq.com', gender = 1, name = '李白', salary = 12.2 WHERE id = 3-->
    <update id="updateMonster_set" parameterType="map">
        UPDATE monster
        <set>
            <if test="age != null and age != ''">
                 age = #{age},
            </if>
            <if test="birthday != null and birthday != ''">
                 birthday = #{birthday},
            </if>
            <if test="gender != null and gender != ''">
                 gender = #{gender},
            </if>
            <if test="name != null and name != ''">
                 name = #{name},
            </if>
            <if test="salary != null and salary != ''">
                 salary = #{salary},
            </if>
            <if test="salary != null and salary != ''">
                 salary = #{salary},
            </if>
        </set>
        where id = #{id}
    </update>
4.测试
    @Test
    public void updateMonster_set() {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("id", 3);
        map.put("age", 22);
        map.put("gender", 1);
        monsterMapper.updateMonster_set(map);
    }

image-20240305160803238

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

第七篇:专家级指南:Python异常处理的艺术与策略

专家级指南&#xff1a;Python异常处理的艺术与策略 1 引言 在编程的世界中&#xff0c;异常处理是一门必修的艺术。它不仅涉及到程序的错误处理&#xff0c;更广泛地影响着软件的稳定性、健壮性和用户体验。本篇文章将深入探讨Python中的异常处理&#xff0c;展示如何通过精心…

Linux:服务器间同步文件的脚本(实用)

一、功能描述 比如有三台服务器&#xff0c;hadoop102、hadoop103、hadoop104&#xff0c;且都有atguigu账号 循环复制文件到所有节点的相同目录下&#xff0c;且脚本可以在任何路径下使用 二、脚本实现 1、查看环境变量 echo $PATH2、进入/home/atguigu/bin目录 在该目录下…

三. Django项目之电商购物商城 -- 校验用户名 , 数据入库

Django项目之电商购物商城 – 校验用户名 , 数据入库 需要开发文档和前端资料的可私聊 一. 路由匹配获得用户名 在注册时 , 用户输入用户名 , 通过ajax请求发送到服务器 , 在路由中设置对应url , 响应视图 , 将用户输入的用户名传入视图 , 与数据库进行校验检查用户名是否重…

信息技术内涵及意义

一、信息技术及其演进趋势 &#xff08;一&#xff09;信息技术概况概念 信息技术&#xff08;Information Technology&#xff0c;IT&#xff09;指“应用在信息加工和处理中的科学、技术与工程的训练方法与管理技巧&#xff1b;上述方法和技巧的应用&#xff1b;计算机及其…

linux高性能服务器--Ngix内存池简单实现

文章目录 内存模型&#xff1a;流程图内存对齐code 内存模型&#xff1a; 流程图 内存对齐 对齐计算 要分配一个以指定大小对齐的内存&#xff0c;可以使用如下公式&#xff1a; 假设要分配大小为n&#xff0c;对齐方式为x&#xff0c;那么 size(n(x-1)) & (~(x-1))。 举个…

【大模型系列】大模型的上下文长度解释与拓展

文章目录 1 什么是大模型的上下文长度&#xff1f;2 拓展大模型上下文长度的方式参考资料 1 什么是大模型的上下文长度&#xff1f; 大模型的上下文长度&#xff08;Context Length&#xff09;是指在自然语言处理&#xff08;NLP&#xff09;的大型语言模型&#xff08;Large…

自动的异地组网工具?

越来越多的企业和个人对远程访问和异地组网需求日益增加。为了满足这一需求&#xff0c;各种技术和服务也不断涌现。其中一项备受关注的技术就是自动的异地组网。本文将介绍这一技术的优势和特点。 【天联】组网的优势 天联组网技术以其卓越的性能和稳定性备受用户称赞。它的优…

数据结构:实验七:数据查找

一、 实验目的 &#xff08;1&#xff09;领会各种查找算法的过程和算法设计。 &#xff08;2&#xff09;掌握查找算法解决实际问题。 二、 实验要求 &#xff08;1&#xff09;编写一个程序exp8-1.cpp, 按提示输入10个任意的整形数据&#xff08;无序&#xff09;&…

数字旅游引领未来智慧之旅:科技应用深度重塑旅游生态,智慧服务全面升级打造极致高品质旅游体验

随着信息技术的飞速发展&#xff0c;数字旅游作为旅游业与科技融合的新兴业态&#xff0c;正以其独特的魅力和优势&#xff0c;引领着旅游业迈向智慧之旅的新时代。数字旅游不仅通过科技应用重塑了旅游生态&#xff0c;更通过智慧服务为游客带来了高品质的旅游体验。本文将深入…

从键入网址到网页显示,期间发生了什么?

从键入网址到网页显示&#xff0c;期间发生了什么&#xff1f; 孤单小弟【HTTP】真实地址查询【DNS】指南帮手【协议栈】可靠传输【TCP】远程定位【IP】两点传输【MAC】出口【网卡】送别者【交换机】出境大门【路由器】互相扒皮【服务器与客户端】相关问答 不少小伙伴在面试过程…

浅谈Agent AI智能体的未来

Agent AI智能体的未来非常广阔和潜力巨大。随着技术的发展和应用场景的不断拓展&#xff0c;我们可以期待以下几个方面的发展&#xff1a; 更加智能化&#xff1a;Agent AI智能体将会变得越来越智能&#xff0c;具备更强大的学习、推理和决策能力。它们可以通过大数据和机器学习…

java序列化和反序列化基础学习

一、前言 前文分析了java的反序列化的DNSURL利用链&#xff0c;但是对于java反序列化的一些过程不是很了解&#xff0c;这篇主要记录下学习java反序列基础知识 二、原理 概念 1、什么是序列化和反序列化 &#xff08;1&#xff09;Java序列化是指把Java对象转换为字节序列…

【C++】一篇文章带你深入了解stack、queue 和 priority_queue

目录 一、stack的介绍和使用1.1 stack的介绍1.2 stack的使用1.2.1.1 [stack对象的构造](https://legacy.cplusplus.com/reference/stack/stack/stack/)1.2.1.2 stack对象的容量操作1.2.1.2.1 [empty()函数](https://legacy.cplusplus.com/reference/stack/stack/empty/)1.2.1.2…

周三多《管理学原理》第3版/考研真题/章节练习题

普通高等教育“十一五”国家级规划教材《管理学原理》&#xff08;第3版&#xff0c;周三多、陈传明、龙静编著&#xff0c;南京大学出版社&#xff09;是我国高校广泛采用的管理学权威教材之一&#xff0c;也被众多高校&#xff08;包括科研机构&#xff09;指定为考研考博专业…

UDP/TCP

udp/tcp特征 udp&#xff1a; 无连接不可靠传输面向数据包全双工 tcp&#xff1a; 有连接可靠传输面向字节流全双工 解释&#xff1a; 有连接/无连接&#xff1a;发送消息时&#xff0c;对方是否必须要在线 比如我们聊天程序&#xff0c;我们给对方发送消息&#xff0c;是不管现…

C++笔试练习笔记 【2】: 数字统计 BC153 两个数组的交集 NC313 点击消除 AB5

文章目录 数字统计分析题目代码部分 两个数组的交集题目分析代码部分 点击消除题目解析代码部分 数字统计 分析题目 这个题涉及到两个知识点&#xff0c;就是枚举和数字的拆分 那么我的思路是进行遍历&#xff0c;拆分数字判断二的个数&#xff0c;枚举进行计数 那么数字的拆分…

C++协程库封装

操作系统&#xff1a;ubuntu20.04LTS 头文件&#xff1a;<ucontext.h> 什么是协程 协程可以看作轻量级线程&#xff0c;相比于线程&#xff0c;协程的调度完全由用户控制。可以理解为程序员可以暂停执行或恢复执行的函数。将每个线程看作是一个子程序&#xff0c;或者…

java同步大量数据到本地数据库方法总结

最近在做一个需求&#xff0c;就是我需要对三方接口调用的数据存放到本地的数据库里的数据表里面。那么一开始我就是直接一条一条save&#xff0c;结果发现耗时非常严重&#xff0c;后面我就进行了改进。就是分批次去同步或者分批次去异步。 现在我直接贴出我写的代码&#xf…

《MySQL对数据库中表的结构的操作》

文章目录 一、建表二、查看表结构所有能查看到数据库&#xff0c;表的操作痕迹的本质都是服务器保存下来了这些操作记录。 三、修改表1.改表名字2.添加表记录3.添加表的更多字段4.修改表的字段5. 删除表的字段 总结 以下的数据库表的操作全是基于user_db这个数据库操作的&#…

maven聚合,继承等方式

需要install安装到本地仓库&#xff0c;或者私服&#xff0c;方可使用自己封装项目 编译&#xff0c;测试&#xff0c;打包&#xff0c;安装&#xff0c;发布 parent: <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://mav…