mybatis快速入门高级篇-动态sql(if、where、chose、set、foreach)-解决数据库字段名与实体类属性名不匹配、多表查询

动态 SQL

动态 SQL 语句是在应用程序运行时被编译和执行的,如,一个客户一个 web 网站,输入姓名,手机号
等…条件名称 访问数据库的时候,用户输入的 SQL 语句是不确定性的,因此 SQL 语句只能被动态地编译。动态
SQL 的应用的场景很多,因此应用程序都使用动态 SQL来操作。(根据不同的条件需要执行不同的 SQL 命令)

If

使用动态 SQL 最常见情景是根据条件包含 where 子句的一部分

dao层

 /**
     * 动态sql
     * 当字段值不为空以字段查询条件,当字段值为空查询所有
     * @param bookModel
     * @return
     */
    List<BookModel> getBookListByIf(BookModel bookModel);

mapper

	<select id="getBookListByIf" parameterType="model.BookModel" resultType="model.BookModel">
        select * from book where 1=1
        <!-- 如果name条件为空,下面语句不会执行,只会执行上面语句 -->
        <if test="name != null and name != ''">
            and name = #{name}
        </if>
    </select>

测试

//main方法中调用
 		BookModel bookModel = new BookModel();
 		//不设置书的名称,查询所有数据
 		//设置书的名称,只查询书名的数据
        bookModel.setName("大头儿子小头爸爸");
        getBookListByIf(bookModel);
//方法
public static void getBookListByIf(BookModel bookModel) throws Exception{
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<BookModel> bookListByIf = mapper.getBookListByIf(bookModel);
        for (BookModel book : bookListByIf){
            System.out.println(book);
        }

    }

动态sql模糊匹配

dao层

/**
     * 模糊查询所有数据
     * @param bookModel 根据name模糊查询
     * @return
     */
    List<BookModel> getBookListByLikeName(BookModel bookModel);

mapper

 	<select id="getBookListByLikeName" parameterType="model.BookModel" resultType="model.BookModel">
        select * from book where 1=1
        <if test="name != null and name != ''">
            and name like concat('%',#{name},'%')
        </if>
    </select>

测试

//main方法中调用
	getBookListByLikeName("小");

//方法
public static void getBookListByLikeName(String name) throws Exception{
        BookModel bookModel = new BookModel();
        bookModel.setName(name);
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<BookModel> bookList = mapper.getBookListByLikeName(bookModel);
        for (BookModel book : bookList){
            System.out.println(book);
        }
    }

where

where 有内容会则生成 where 关键字,如果没有内容则不生成 where 关键字

dao层

	/**
     * where查询
     * @param bookModel
     * @return
     */
    List<BookModel> getBookListByWhere(BookModel bookModel);

mapper

	<select id="getBookListByWhere" parameterType="model.BookModel" resultType="model.BookModel">
        select * from book
            <where>
            	<!-- 如果name不为空 -->
            	<!--  select * from book where name like '%nameValue%' -->
                <if test="name != null and name !=''">
                    name like concat('%',#{name},'%')
                </if>
                <!-- 如果price不为空 -->
                <!--  select * from book where name like '%name%' and price = priceValue -->
                <if test="price != null and price != ''">
                    and price = #{price}
                </if>
            </where>
    </select>

测试

//main方法中调用
	getBookListByWhere("大");

//方法
 public static void getBookListByWhere(String name) throws Exception{
        BookModel bookModel = new BookModel();
        bookModel.setName(name);
        //添加price,判断两个条件
        //bookModel.setPrice(211.0);
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<BookModel> bookList = mapper.getBookListByWhere(bookModel);
        for (BookModel book : bookList){
            System.out.println(book);
        }
    }

choose,when,otherwise

有时候,我们不想使用所有的条件,而只是想从多个条件中选择一个使用。针对这种情况,MyBatis 提供了 choose 元素,它有点像 Java 中的 switch 语句。

dao层

	/**
     * choose,when,otherwise
     * 只要三者中有一个成立,其他都不执行。
     * @param bookModel
     * @return
     */
    List<BookModel> getBookListByChoose(BookModel bookModel);

mapper

	<select id="getBookListByChoose" parameterType="model.BookModel" resultType="model.BookModel">
        select * from book
        <where>
            <choose>
            	<!-- 如果name不为空 -->
            	<!-- select * from book where name like '%nameValue%' -->
                <when test="name != null and name != ''">
                    name like concat('%',#{name},'%')
                </when>
                <!-- 如果name为空 price不为空 -->
                <!-- select * from book where price = priceValue -->
                <when test="price != null and price != ''">
                    price = #{price}
                </when>
                 <!-- 如果name为空 price为空 -->
                  <!-- select * from book where 1=1 -->
                <otherwise>
                    1=1
                </otherwise>
            </choose>
        </where>
    </select>

测试

//main中调用
	getBookListByChoose("大");

//方法
	public static void getBookListByChoose(String name) throws Exception{
        BookModel bookModel = new BookModel();
        bookModel.setName(name);
        //虽然添加了price,但是只会执行name的查询条件,如果都没有条件执行,执行最后的otherwise里的条件,相当于switch
        //bookModel.setPrice(211.0);
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<BookModel> bookList = mapper.getBookListByChoose(bookModel);
        for (BookModel book : bookList){
            System.out.println(book);
        }
    }

set

dao层

/**
     * 动态修改信息
     * @param bookModel
     * @return
     */
    int updateBookBySqlSet(BookModel bookModel);

mapper

<update id="updateBookBySqlSet" parameterType="model.BookModel">
        update book
        <set>
            <!-- 如果java测试类的name,price都不写入,注释掉,然后mapper的<set>自然两个if都不
            进入,sql就会出现问题,因此加入id=#{id} -->
            id = #{id},
            <if test="name != null and name != ''">
                name=#{name},
            </if>
            <!-- 如果添加额外的修改条件,却没给赋值,会赋值默认值 -->
            <!-- 如果没有添加额外的修改条件,数据库本身的值不变,把下面的if注释掉,看看数据库的两种情况 -->
            <if test="price != null and price != null">
                price=#{price},
            </if>
        </set>
        where id = #{id}
    </update>

测试

//main中调用
	updateBookBySqlSet();

//方法
 public static void updateBookBySqlSet() throws Exception{
        BookModel bookModel = new BookModel();
        bookModel.setName("假如给我三天光明");
        bookModel.setId(9);
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        int i = mapper.updateBookBySqlSet(bookModel);
        sqlSession.commit();
        System.out.println(i > 0 ? "修改成功" : "修改失败");

    }

foreach

  • 使用场景是对集合进行遍历(尤其是在构建 IN 条件语句的时候)
  • foreach 元素的功能非常强大,它允许你指定一个集合,声明可以在元素体内使用的集合项(item)和索引(index)变量。它也允许你指定开头与结尾的字符串以及集合项迭代之间的分隔符。这个元素也不会错误地添加多余的分隔符。
  • 你可以将任何可迭代对象(如 List、Set 等)、Map 对象或者数组对象作为集合参数传递给 foreach。当使用可迭代对象或者数组时,index 是当前迭代的序号,item 的值是本次迭代获取到的元素。当使用 Map 对象(或者 Map.Entry 对象的集合)时,index 是键,item 是值

dao层

    /**
     * 根据指定id查询,比如查询id为5,6,7的数据
     * @param ids
     * @return
     */
    List<BookModel> getBookByIn(int[] ids);

mapper

	<select id="getBookByIn" resultType="model.BookModel">
        select * from book where id in
        <foreach collection="array" item="id" index="i" open="(" separator="," close=")">
            #{id}
        </foreach>
    </select>

测试

//main方法中调用
  getBookByIn();
  
//方法
public static void getBookByIn() throws Exception{
        int[] ids = {5,6,7};
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);

        List<BookModel> books = mapper.getBookByIn(ids);
        for (BookModel book : books) {
            System.out.println(book);
        }
    }

resultMap(解决数据库字段与实体类属性名不匹配问题)

mapper.xml文件

<!-- 如果数据库字段名和实体类的属性名一致,可以不用配置resultMap,mybatis会隐式自动的创建一个 ResultMap -->
<!-- 结果映射 -->
	<!-- id: resultMap的别名,唯一标识,由数据库操作调用 -->
	<!-- type: 指定类型 -->
    <resultMap id="book" type="model.BookModel">
    	<!-- id:指定和数据表主键字段对应的标识属性 -->
    	<!-- property:property表示实体类的属性 -->
    	<!-- column:数据库的字段名 -->
    	<!-- result:指定结果集字段和实体类属性的映射关系 -->
        <id property="id" column="t_id" />
        <result property="name" column="t_name"/>
        <result property="price" column="t_price"/>
        <result property="num" column="t_num"/>
    </resultMap>
	
	<!-- resultMap:引入resultMap的id,作为返回值类型 -->
    <select id="findAll" resultMap="book">
        select * from book;
    </select>

第二种解决数据库字段名与实体类属性名不匹配方法

	<!-- 我们可以在sql语句中直接设置别名,mybtais会自动隐式映射 -->
 <select id="findAll" resultMap="book">
        select 	
        	t_id as id,
        	t_name as name,
        	t_price as price,
        	t_num as num
		from book;
    </select>

多表查询

dao层

List<Map<String,Object>> findPurBooMap();

mapper

<select id="findPurBooMap" resultType="map">
	select p.id,p.`name`,p.bid,b.id `book.id`,b.bookName `book.bookName`,b.auth
	`book.auth`,b.price `book.price`,b.publish `book.publish` 
	from purchaser p LEFT JOINbook b 
	ON b.id = p.id
</select>

测试

    public static void findPurBooMap() throws Exception{
        SqlSession sqlSession = JDBCUtil.getSqlSession();
        BookDao mapper = sqlSession.getMapper(BookDao.class);
        List<Map<String,Object>> maps = mapper.findPurBooMap();
        for (Map<String, Object> map : maps) {
            for (Object string : map.keySet()){
                System.out.println(string+":"+map.get(string));
            }
        }
    }

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

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

相关文章

el-image组件预览图片同时操作页面

背景&#xff1a;el-image组件打开预览效果不能滑动页面。 Q:那么如何才能在打开遮罩层后还能操作页面呢&#xff1f; A:改变遮罩层的大小。CSS3有一个属性width&#xff1a;fit-content&#xff1b;可以解决这个问题。 打开F12看看饿了么的原生样式如下 加上width&#xff1…

R可视化:ggplot2绘制双y轴图

介绍 ggplot2绘制双y轴图加载R包 knitr::opts_chunk$set(message = FALSE, warning = FALSE) library(tidyverse) library(readxl)# rm(list = ls()) options(stringsAsFactors = F) options(future.globals.maxSize = 10000 * 1024^2)Importing data 下载Underdetection of c…

网页自动跳转到其他页面,点击浏览器返回箭头,回不到原来页面的问题

背景&#xff1a;今天产品提个需求&#xff0c;需要从index页面自动触发跳转到下一页面的事件&#xff0c;从而不做任何操作&#xff0c;直接跳转到test页面。 代码是这样的&#xff1a; index.vue: <template><div style"width:500px;height:600px;background-…

(三)Servlet教程——Tomcat安装与启动

首先打开浏览器在浏览器地址栏中输入清华大学开源软件镜像站地址&#xff0c;地址如下 https://mirrors.tuna.tsinghua.edu.cn/ 输入地址后回车会出现如下图所示的界面 在该界面找tomcat不是很好找&#xff0c;在搜索框中输入apache然后回车&#xff0c;输入apache后并回车后出…

WebSocket的原理、作用、API、常见注解和生命周期的简单介绍,附带SpringBoot示例

文章目录 原理作用客户端 API服务端 API生命周期常见注解SpringBoot示例 WebSocket是一种 通信协议 &#xff0c;它在 客户端和服务器之间建立了一个双向通信的网络连接 。WebSocket是一种基于TCP连接上进行 全双工通信 的 协议 。 WebSocket允许客户端和服务器在 单个TCP连接上…

AI道路交通违章智能抓拍系统解决方案

项目概述 背景 目前&#xff0c;XX市市全市民用汽车保有量94.62万辆&#xff0c;比上年末增长15.9%&#xff0c;其中私人汽车保有量35.48万辆&#xff0c;减少0.01%。轿车保有量39.45万辆&#xff0c;增长82.1%&#xff0c;其中私人轿车38.65万辆&#xff0c;增长82.1%。电动自…

【项目实战】基于高并发服务器的搜索引擎

【项目实战】基于高并发服务器的搜索引擎 目录 【项目实战】基于高并发服务器的搜索引擎搜索引擎部分代码index.htmlindex.hpplog.hppparser.cc&#xff08;用于对网页的html文件切分且存储索引关系&#xff09;searcher.hpputil.hpphttp_server.cc&#xff08;用于启动服务器和…

免费https证书申请

HTTPS证书&#xff0c;也称为SSL证书&#xff08;Secure Sockets Layer&#xff09;或TLS证书&#xff08;Transport Layer Security&#xff09;&#xff0c;是一种数字证书&#xff0c;用于在互联网通信中确保数据传输的安全性、完整性和真实性。它是基于公钥基础设施&#x…

VirtualFlow亮相核反应堆技术全国重点实验室2024学术年会

为加强先进核能技术领域科技创新与应用&#xff0c;核反应堆技术全国重点实验室及先进核能技术全国重点实验室2024年学术年会在四川成都启幕&#xff0c;9名院士和近百家科研院所、高校和企业等近700名专家学者齐聚一堂&#xff0c;聚焦和探讨核反应堆及先进核能重大基础理论和…

RAG开山之作:结合参数化与非参数化记忆的知识密集型NLP任务新解法

20年RAG刚提出时的论文&#xff1a;Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks&#xff0c;也算是RAG的开山之作之一了。 摘要&#xff1a;检索增强生成&#xff08;RAG&#xff09;方法结合了预训练语言模型与基于检索的非参数化记忆&#xff0c;通过…

正整数的性质:和与根

目录 数字和 数字和介绍 数字和简单应用 哈沙德数 最小元素各数位之和 数字根 数字根介绍 数字根简单应用 数字和 数字和介绍 简单来说&#xff0c;数字和即一个整数数字每一位数值相加求和所得的值&#xff0c;数字和可以为任意正整数&#xff0c;使用代码获取一个数值的数字和…

Git笔记-配置ssh

Git在Deepin中的ssh配置 一、环境二、安装1. 查看GitHub账户2. 配置 git3. 生成 ssh key 三、配置 一、环境 系统&#xff1a; Deepin v23 Git仓库&#xff1a;GitHub 二、安装 1. 查看GitHub账户 在设置界面看到自己的邮箱&#xff0c;这个邮箱就是后面会用到的邮箱 2. …

在Java中使用XxlCrawler时防止被反爬的几种方式

目录 前言 一、常见的反爬措施 1、User-Agent识别 2、Referer识别 3、频率限制 4、IP限制 二、XxlCrawer的应对之道 1、User-Agent应对 2、频率限制 3、IP限制 三、XxlCrawler执行解析 1、XxlCrawler对象 2、启动对象 3、信息爬取线程 总结 前言 众所周知&#x…

LAMMPS单层石墨烯建模

本文主要介绍两种晶胞建模方式。 一、Z形晶胞 晶胞分析&#xff1a;a1沿水平x轴方向&#xff0c;a2沿垂直y轴方向。石墨烯是二维结构&#xff0c;a3取小于单层石墨烯厚度。假设石墨烯键长L1.421&#xff0c;则a13L&#xff0c;a21.732L&#xff0c;a32L&#xff08;低于3.35即…

IDEA离线安装插件

1、下载地址 https://plugins.jetbrains.com/idea 如果去其他编辑器&#xff0c;点击下拉&#xff0c;选择即可。 2.搜索 在输入框输入关键词&#xff0c;按照提示选择即可&#xff0c;点击搜索按钮&#xff0c;查看结果。 3、选择版本 按照自己的版本选择合适的版本 4、安…

探索比特币符文热:市场趋势与持续性分析

在加密货币世界中&#xff0c;比特币一直是备受关注的焦点之一。然而&#xff0c;近年来&#xff0c;随着DeFi&#xff08;去中心化金融&#xff09;的兴起&#xff0c;一种新的潮流开始崭露头角——比特币符文。本文将探讨比特币符文的兴起&#xff0c;分析市场趋势&#xff0…

FTP与SMB深度对比:文件传输协议谁更胜一筹?

在数字化时代&#xff0c;文件传输已成为日常工作中不可或缺的一部分。 FTP&#xff08;文件传输协议&#xff09;和SMB&#xff08;服务器消息块&#xff09;是两种最为常见的文件传输协议。它们各自在文件传输领域拥有独特的优势和特点&#xff0c;但同时也存在一些差异。 今…

【学习】软件测试自动化,是未来的趋势还是当前的必需

在当今快速迭代的软件开发周期中&#xff0c;速度和质量成为了企业生存的关键。随着DevOps实践的普及和持续集成/持续部署&#xff08;CI/CD&#xff09;流程的标准化&#xff0c;软件测试自动化已经从未来的趋势转变为当前的必要性。本文将探讨自动化测试的现状、必要性以及其…

C基础语法速览

叠甲&#xff1a;以下文章主要是依靠我的实际编码学习中总结出来的经验之谈&#xff0c;求逻辑自洽&#xff0c;不能百分百保证正确&#xff0c;有错误、未定义、不合适的内容请尽情指出&#xff01; 文章目录 1.数据类型1.1.数据类型的常见分类1.2.数据类型的符号修饰1.3.数据…

W801学习笔记十一:掌机进阶V3版本之硬件改造

经由前面的笔记&#xff0c;我们打造出了一款游戏掌机。 W801学习笔记十&#xff1a;HLK-W801制作学习机/NES游戏机(总结) 然而&#xff0c;考虑到后续的游戏开发&#xff0c;总是忧心容量不足。故而&#xff0c;在正式展开软件开发工作以前&#xff0c;最终进行一下升级改造…
最新文章