【JavaEE】Spring Boot MyBatis详解(二)

一.解决数据库字段名和对象属性名冲突的问题.

  • 产生这个问题的本质原因就是Java 属性名和数据库字段的命名规范不同. 这个问题的本质就是查询数据库返回了字段,但是不知道和Java对象的哪个属性相对应

1.注解的解决方法

  • 注解的解决方式有三种:
    • 方式一:给数据库字段起别名.== 本质上就是通过给数据库字段起别名的方式,让数据库的字段能供和Java对象的属性的对应关系能够对应的上.==
    • 方式二:指定结果映射. 数据返回了,但是不知道和谁对应,这个方式就是用映射的方式来指定数据间的对应关系.
    • 方式三:自动驼峰转换.

1.1 给数据库字段起别名的具体实现.

  • mapper层代码实现:
@Select("select id,username,delete_flag as deleteFlag,create_time as createTime,update_time as updateTime from userInfo")List<UserInfo> selectUserInfo();
  • 生成对应的测试代码,运行结果:
    在这里插入图片描述

1.2 指定结果映射的具体实现.

  • mapper层代码实现:
	@Results(id = "resultMap", value = {@Result(column = "delete_flag", property = "deleteFlag"),@Result(column = "create_time", property = "createTime"),@Result(column = "update_time", property = "updateTime")})@Select("select * from userInfo")List<UserInfo> selectUserInfo2();
  • 生成对应的测试代码,运行结果:
    在这里插入图片描述

配置一次之后下一次就可以直接使用这个对应关系.

@ResultMap("resultMap")@Select("select * from userInfo")public List<UserInfo> getUserInfoAll();

此处的参数和指定结果映射中的id相对应.

1.3 自动驼峰转换的具体实现.(更推荐使用这种方式)

  • 在yml中配置如下信息:
mybatis:configuration:map-underscore-to-camel-case: true  #自动驼峰转换

2.XML配置文件的解决方法

  • XML配置文件的解决方式和注解的方式相同也是以上三种方式:
    • 方式一:给数据库字段起别名.(跟注解的方式一样这里就不做详细的叙述了)
    • 方式二:指定结果映射.
    • 方式三:自动驼峰转换. (跟注解的方式一样这里就不做详细的叙述了)

2.1指定结果映射的具体实现

  • mapper层代码实现.
List<UserInfo> selectAll2();
  • 对应的XML配置文件.
	<resultMap id="BaseMap" type="com.tuanzi.ssm.springmybatis.model.UserInfo"><id column="id" property="id"/><result column="delete_flag" property = "deleteFlag"/><result column = "create_time" property = "createTime"/><result column = "update_time" property = "updateTime"/></resultMap><select id="selectAll2" resultMap="BaseMap">select * from userInfo</select>
  • 生成对应的测试代码,运行结果:
    在这里插入图片描述

二.#{}和${}的区别和联系.

1.#{}和${}的使用.

  • mapper层代码:
	@Select("select * from userinfo where id=#{id}")List<UserInfo> getUserInfoById(Integer id);@Select("select * from userinfo where id=${id}")List<UserInfo> getUserInfoById2(Integer id);   
  • #{}运行结果:
    在这里插入图片描述
    我们输入的参数并没有在后面拼接,id的值是使用 ? 进行占位. 这种SQL 我们称之为"预编译SQL", 预编译SQL的本质类似于买火车票的占位行为, 显示出来这个位置已经有人了,但具体是谁,这个人高矮胖瘦,是男是女,都不重要,那个位置已经被他预定了. 然后根据传的参数来确定这个参数的具体类型并赋值.
  • ${}运行结果:
    在这里插入图片描述

从${}的运行结果我们可以看出此时的传参变成了直接拼接字符串.并会不跟据传入参数的类型来进行灵活转化.

2.#{}和${}参数解析之间的区别

  • mapper层代码:
	@Select("select * from userinfo where username = #{userName}")List<UserInfo> getUserInfoByUsername(String userName);@Select("select * from userinfo where username = ${userName}")List<UserInfo> getUserInfoByUsername2(String userName);
  • #{}运行结果:
    在这里插入图片描述
    此时代码正常执行,正确执行的sql语句为: select * from userinfo where username = ‘admin’

  • ${}运行结果:

在这里插入图片描述
此时代码执行会报错, 报的是SQLSyntaxErrorException, 由上述的图片我们可以看出直接拼接的内容与正确的sql的差别, 缺少’'/“”

#{} 使用的是预编译SQL, 通过 ? 占位的方式, 提前对SQL进行编译, 然后把参数填充到SQL语句中. #{} 会根据参数类型, 自动拼接引号 ‘’ .${} 会直接进行字符替换, 一起对SQL进行编译. 如果参数为字符串, 需要加上引号 ‘’

3.#{} 和 ${}区别

1. #{}的性能更高

  • 绝大多数情况下, 某⼀条 SQL 语句可能会被反复调用执行, 或者每次执行的时候只有个别的值不同(比如 select 的 where 子句值不同, update 的 set 子句值不同,insert 的 values 值不同). 如果每次都需要经过上面的语法解析, SQL优化、SQL编译等,则效率就明显不行了.
  • 预编译SQL,编译一次之后会将编译后的SQL语句缓存起来,后面再次执行这条语句时,不会再次编译(只是输入的参数不同), 省去了解析优化等过程, 以此来提高效率

2.#{}更安全可以防止sql注入(最重要的区别)

  • SQL注入:是通过操作输入的数据来修改事先定义好的SQL语句,以达到执行代码对服务器进行攻击的方法。

由于没有对用户输入进行充分检查,而SQL又是拼接而成,在用户输入参数时在参数中添加⼀些SQL关键字,达到改变SQL运行结果的目的,也可以完成恶意攻击。

  • sql注入的代码: ' or 1='1
  • 举个例子:
@Test
void queryByName() {List<UserInfo> userInfos = userInfoMapper.queryByName("' or 1='1");System.out.println(userInfos);
}

在这里插入图片描述

可以看出来, 查询的数据并不是自己想要的数据. 假设如果这是用户的登录,那么即使在不知道用户密码的情况下,也可以通过sql注入进行登录所以用于查询的字段,尽量使用 #{} 预查询的方式. SQL注入是⼀种非常常见的数据库攻击手段, SQL注入漏洞也是网络世界中最普遍的漏洞之一.

3.排序功能(${}可以实现而#{}不可以实现)

  • mapper层代码:
	@Select("select * from userInfo order by id #{order} ")List<UserInfo> selectUserInfoOrder(String order);//也存在sql注入的问题,解决方法,可以使用穷举的方式进行校验.//也可以定义两个接口直接写死@Select("select * from userInfo order by id ${order} ")List<UserInfo> selectUserInfoOrder2(String order);
  • #{}的运行结果:
    在这里插入图片描述
    运行结果会报错,报错的原因是因为SQL错误, 与正确的SQL相比,desc是不需要加’'的.
  • ${}的运行结果:
    在这里插入图片描述

4.like查询.

  • 如果使用#{}
@Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +"from userinfo where username like '%#{key}%' ")
List<UserInfo> queryAllUserByLike(String key);

此时代码执行会报错,很明显多了一个’', 如果把#{}改成${}可以解决问题,但会出现SQL注入的风险,解决方法是使用concat函数来解决问题

@Select("select id, username, age, gender, phone, delete_flag, create_time, 
update_time " +"from userinfo where username like concat('%',#{key},'%')")
List<UserInfo> queryAllUserByLike(String key);

三.数据库连接池.

  • 数据库连接池: 是用于管理数据库连接的一种技术,它允许应用程序重复使用现有的数据库连接,而不是为每次操作重新建立连接。

  • 数据库连接池通过维护一定数量的数据库连接,对外提供获取和返回连接的方法,避免了频繁创建和释放数据库连接所带来的性能开销。在多用户网络应用中,数据库连接是一种关键的、昂贵的资源。如果每次操作都打开一个物理连接,并在使用后关闭,会导致系统性能低下。为了解决这个问题,连接池技术被提出和应用.

  • 连接池的工作原理

    • 连接池的建立:系统初始化时,根据配置建立一定数量的数据库连接,放入连接池中备用。
    • 连接的使用管理:当客户请求数据库连接时,连接池会分配空闲连接给客户使用;若无空闲连接且未达到最大连接数限制,则创建新连接;若已达到最大连接数,则请求需排队等待。释放连接时,连接不会被真正关闭,而是返回给连接池供其他客户使用。
    • 连接池的关闭:应用程序退出时,关闭所有连接并释放相关资源。
  • 连接池的注意事项

    • 并发问题:必须考虑多线程环境下的并发问题,确保线程安全。
    • 性能监控:利用连接池提供的监控功能,跟踪连接池状态和SQL执行情况,以便及时优化。
    • 防SQL注入:一些数据库连接池如Druid提供了防SQL注入的功能。
  • SpringBoot默认使用的是hikari数据库连接池
    在这里插入图片描述

  • 常见的数据库连接池

    • C3P0:是一个开源的数据库连接池,稳定性良好。
    • DBCP:Apache提供的数据库连接池,速度快但存在已知BUG。
    • Druid:阿里巴巴提供的数据库连接池,集成了多种优点,并提供强大的监控功能。
  • Druid的maven依赖:

		<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-3-starter</artifactId><version>1.2.21</version></dependency>

此时的运行结果:
在这里插入图片描述

四.动态SQL

1.标签

  • 思考一种情况,当添加用户的时候,有些情况某些值是非必填的选项,如果某一项或某几项没有传的时候该如何根据输入的具体参数处理SQL. 这个处理过的SQl称为动态SQL.
  • 接口定义:
Integer insertUserByCondition(UserInfo userInfo);

Mapper.xml实现:

<insert id="insertUserByCondition">INSERT INTO userinfo (username,`password`,age,<if test="gender != null">gender,</if>phone)VALUES (#{username},#{age},<if test="gender != null">#{gender},</if>#{phone})
</insert>

2.trim标签.

  • 标签的相关属性
    • prefix:表示整个语句块,以prefix的值作为前缀
    • suffix:表示整个语句块,以suffix的值作为后缀
    • prefixOverrides:表示整个语句块要去除掉的前缀
    • suffixOverrides:表示整个语句块要去除掉的后缀
<insert id="insertUserInfoByCondition">insert into userinfo<trim prefix="(" suffix=")" prefixOverrides=","><if test="username!=null">username</if><if test="password!=null">,password</if><if test="age!=null">,age</if><if test="gender!=null">,gender</if></trim>values<trim prefix="(" suffix=")" prefixOverrides=","><if test="username!=null">username</if><if test="password!=null">,password</if><if test="age!=null">,age</if><if test="gender != null">,#{gender}</if></trim>
</insert>
  • 在以上 sql 动态解析时,会将第一个部分做如下处理:
    • 基于 prefix 配置,开始部分加上 (
    • 基于 suffix 配置,结束部分加上 )
    • 多个组织的语句都以 , 结尾,在最后拼接好的字符串还会以 , 结尾,会基于
      suffixOverrides 配置去掉最后一个 ,注意 中的 username 是传入对象的属性

在这里插入图片描述
此时就可以根据传的值来动态调整SQL语句了.

3.where标签.

<select id="queryUserInfoByCondition" resultType="com.tuanzi.ssm.springmybatis.model.UserInfo">select * from userinfo<where><if test="age!=null">age = #{age}</if><if test="gender!=null">and gender = #{gender}</if><if test="deleteFlag!=null">and delete_flag = #{deleteFlag}</if></where></select>

只会在子元素有内容的情况下才插入where子句,而且会自动去除子句开头的AND或OR 以上标签也可以使用 替换, 但是此种情况下, 当子元素都没有内容时, where关键字也会保留

4.标签

<update id="updateUserInfoByCondition">update userInfo<set><if test="password!=null">password = #{password}</if><if test="age!=null">,age = #{age}</if><if test="gender!=null">,gender = #{gender}</if></set>whereid = #{id}</update>
  • :动态的在SQL语句中插入set关键字,并会删掉额外的逗号. (用于update语句中)以上标签也可以使用 替换。

5.标签

  • 对集合进行遍历时可以使用该标签。标签有如下属性:
    • collection:绑定⽅法参数中的集合,如 List,Set,Map或数组对象
    • item:遍历时的每⼀个对象
    • open:语句块开头的字符串
    • close:语句块结束的字符串
    • separator:每次遍历之间间隔的字符串
	<delete id="batchDeleteByIds">delete from userinfo where id in<foreach collection="ids" open="(" close=")" item="id" separator=",">#{id}</foreach></delete>

6.标签

  • 在xml映射文件中配置的SQL,有时可能会存在很多重复的片段,此时就会存在很多冗余的代码
    在这里插入图片描述
  • 我们可以对重复的代码片段进行抽取,将其通过 标签封装到⼀个SQL片段,然后再通过 标签进行引用
  • sql标签定义可重用的SQL片段
  • include标签通过属性refid,指定包含的SQL片段
 	<sql id="selectAllUserInfo">select * from userInfo</sql><select id="selectAll" resultType="com.tuanzi.ssm.springmybatis.model.UserInfo"><include refid="selectAllUserInfo"></include></select>

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

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

相关文章

kubesphere踩过的坑,持续更新....

踩过的坑 The connection to the server lb.kubesphere.local:6443 was refused - did you specify the right host… 另一篇文档中 dashboard 安装 需要在浏览器中输入thisisunsafe,即可进入登录页面 ingress 安装的问题 问题描述&#xff1a; 安装后通过命令 kubectl g…

电脑上使用备忘录怎么查看编辑时间?能显示时间的备忘录

在快节奏的生活中&#xff0c;很多人喜欢使用备忘录来记录日常事项和重要信息。备忘录不仅能帮助我们捕捉灵感&#xff0c;还能确保重要任务不被遗漏。然而&#xff0c;有时候我们需要知道某条记录的编辑时间&#xff0c;以便于回溯和整理信息。如果备忘录不能显示编辑时间&…

JavaEE进阶----SpringBoot快速入门

文章目录 前言一、了解Maven1.1 Maven功能- 项⽬构建- 管理依赖 1.2Maven仓库 二、第一个SpringBoot项目总结 前言 Spring Boot是一个用于构建快速、简单和可扩展的生产级应用程序的框架。它基于Spring框架&#xff0c;提供了开发微服务和独立的应用程序所需的一切。 一、了解…

逆旅热闹如花盛放

热闹 未及十五&#xff0c;月亮的清辉已可穿透厚厚的云层铺撒人间。 几颗星星点缀着夜空&#xff0c;偶尔一架飞机闪烁着光芒。 很难得的晴夜。 近两个月以来的雨&#xff0c;像电影上的蒙太奇画帧&#xff0c;一幕接一幕&#xff0c;只是单调的灰色&#xff0c;困乏人心。 …

1994年美国人口普查数据 分类预测与集成学习

对于分类预测学习任务&#xff0c;从指定的数据源读取数据&#xff0c;对数据进行必要的处理&#xff0c;选取合适的特征&#xff0c;构造分类模型&#xff0c;确定一个人的年收入是否超过50K。 数据来源&#xff1a;1994年美国人口普查数据库。数据存放在data目录中&#xff0…

AD使用快捷键

1、如何实现元器件旋转45放置 在Preferences >> PCB Editor >> General中将Rotation Step&#xff08;旋转的步进值&#xff09;由90改为45&#xff0c;这样以后每次按空格键旋转器件时旋转角度为45。 2、显示网络、隐藏网络 N 3、对齐 2、设置DRC检查选项&#xf…

SAP-应付暂估核对

前言 本篇前面是应付暂估核对的核对逻辑&#xff0c;后面是核对过程中发现的问题&#xff0c;拿出来大家参考一下。 需求实现 一、采购订单收货暂估凭证 采购订单情况&#xff1a;采购订单号码5300000048 采购单价PBXX总价是含税单价&#xff0c;不含税单价是3,539.82 订单计…

数据可视化在智慧社区中的关键应用

数据可视化能够在智慧社区中发挥重要作用&#xff0c;通过直观和交互的方式将复杂的数据呈现出来&#xff0c;提升社区管理效率&#xff0c;优化居民生活体验&#xff0c;促进社区的可持续发展。在智慧社区中&#xff0c;数据可视化的应用涵盖了安全、环境、能源、交通和公共服…

CFA官网资料说明

进入到资料后台你就会发现&#xff0c;分了三个板块&#xff0c;分别是Study, Prepare和The Exam。 Study板块 主要提供备考重要资料&#xff0c;包括教材下载、自学习系统 Prepare板块 主要帮助考生准备考试&#xff0c;提供了一些小工具、包括机考软件指南 The exam板块…

秋招突击——第六弹——Java的SSN框架快速入门——MyBatisPlus

文章目录 引言正文入门案例整和MybatisPlus的相关内容 概述标准数据层开发分页查询DQL编程控制条件查询——NULL值处理 查询投影查询条件设定等于操作范围查询模糊查询分组查询 字段映射和表名映射 DML编程控制——增删改查相关操作添加操作id生成策略控制 删除操作多数据删除逻…

【物联网】物联网操作系统简介

目录 一、物联网操作系统概述 1.1内存占用 1.2 内存管理 二、物联网操作系统构成 三、物联网操作系统关键特性 3.1 调度方式 3.2 I/O操作方式 3.3 网络服务 3.3.1 TinyOS网络协议栈 3.3.2 LiteOS网络协议栈 一、物联网操作系统概述 物联网操作系统是支撑物联网大规模…

电商还存在错位竞争空间吗?

“上链接试了&#xff0c;十几分钟&#xff0c;成本5块的东西卖1块5了。”今年618前期&#xff0c;某个电商平台上线了自动跟价功能&#xff0c;有一个卖家尝试了一会儿之后赶紧关了。 又一个618&#xff0c;平台、商家、消费者们又迎来了一次狂欢。只是与往年不同的是&#x…

20240620每日后端---------Spring Boot中的 5 大设计模式最佳实践和示例 这些是我经常使用的设计模式并且非常喜欢

在本文中&#xff0c;我们将深入探讨五种基本设计模式&#xff0c;并探讨在 Spring Boot 项目中有效应用它们的最佳实践。每个模式都将附有一个实际示例来演示其实现。 单例模式 Singleton 模式确保一个类只有一个实例&#xff0c;并提供对它的全局访问点。这对于管理资源&am…

绝地求生PUBG联名补偿奖励来了 补偿奖励介绍详情解析

《绝地求生》(PUBG) 作为一款战术竞技型射击类沙盒游戏&#xff0c;从上线以来就深受玩家小伙伴们的喜爱&#xff0c;即便是没有玩过的小伙伴&#xff0c;对“吃 鸡”二字想必也是很耳熟的&#xff0c;这正是《绝地求生》(PUBG) 的别称。 在北京时间6月12日&#xff0c;由于绝…

通过注解@ConfigurationProperties和全局配置文件中配置数据绑定

1、创建创建出两个JavaBean&#xff1a;User和Address 2、在User类上加注解 Component // 标记为组件&#xff0c;放到spring的ioc容器里 ConfigurationProperties(prefix "user") // 和配置文件绑定&#xff0c;可以从配置文件中的注入数据 public class User {…

性能工具之 JMeter 常用组件介绍(七)

文章目录 一、后置处理器1、Regular Expression Extractor(正则表达式提取器)2、JSON Extractor(JSON表达式提取器)3、Regular Expression Extractor(正则表达式提取器) 二、小结 本文主要介绍JMeter主流后置处理器的功能 一、后置处理器 从上面可以看出后置处理可以插件挺多&a…

CASS界址点顺序重排

1、绘制一个宗地&#xff0c;如下&#xff1a; 2、注记界址点号&#xff0c;如下 3、【地籍】--【调整宗地内界址点顺序】&#xff0c;如下&#xff1a; 重排完成后&#xff0c;点击工具栏的【重】按钮&#xff0c;即可刷新标注。

C++的动态内存分配

使用new/delete操作符在堆中分配/释放内存//使用new操作符在堆中分配内存int* p1 = new int;*p1 = 2234;qDebug() << "数字是:" << *p1;//使用delete操作符在堆中释放内存delete p1;在分配内存的同时初始化//在分配内存的时初始化int* p2 = new int(100…

Mybatis Plus 详解 IService、BaseMapper、自动填充、分页查询功能

结构直接看目录 前言 MyBatis-Plus 是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 愿景 我们的愿景是成为 MyBatis 最好的搭档&#xff0c;就像 魂斗罗 中的 1P、2P&#xff0c;基友搭配&#xff0c;效…

电子期刊制作教程:跟着步骤轻松学会制作

随着数字时代的快速发展&#xff0c;电子期刊以其独特的便捷性和互动性&#xff0c;已经成为信息传播的重要载体。你是否也想掌握制作电子期刊的技能呢&#xff1f;今天&#xff0c;就让我来为你一步步解析电子期刊的制作过程&#xff0c;带你轻松学会制作属于自己的电子期刊。…