【Java】Mybatis

MyBatis

JavaEE三层框架:表现层、业务层、持久层。

现在开始学习持久层。持久层就是负责与数据库打交道的代码。

框架:就是一个半成品软件。在框架的基础上,可以更加高效地写出代码。

1、MyBatis快速入门

1、准备工作(创建springboot工程、导入mybatis和mysql的依赖、编写实体类、编写配置类)

2、注解开发:编写接口,使用注解编写sql语句(注解开发比较简单,先使用注解开发来进行)

3、测试。

2、数据库连接池

什么是数据库连接池?

  • 数据库连接池是个容器,负责分配、管理数据库连接( Connection )

  • 它允许应用程序重复使用一个现有的数据库连接/而不是再重新建立一个

  • 释放空闲时间超过最大空闲时间的连接/来避免因为没有释放连接而引起的数据库连接遗漏

如果没有数据库连接池会怎么样?每一次连接数据库都要创建一个数据库连接,用完后需要立刻销毁连接以免造成资源浪费。

数据库连接池的优势:

  • 资源重用
  • 提升系统响应速度
  • 避免数据库连接泄漏

sun公司在Java中提供了一个数据库连接池的标准接口,之后其他公司生产了不同的数据库连接池产品。C3P0和DBCP现在基本上也已经不用了,用的是德鲁伊和追光者Hikari。追光者是springboot默认使用的连接池。

在这里插入图片描述

切换druid连接池非常方便,导入依赖然后配置文件中改一下即可。

在这里插入图片描述

3、注解开发

就是直接在接口方法上写个注解,注解里直接写sql语句就可以了。但是,注解只适合简单的语句开发,如果想要复杂的功能的话,注解开发是非常麻烦的,这时候还是使用xml文件完成sql语句的编写更好。

在接口方法上的注解有以下几类:

  • @Select

    接口方法的返回值需要是一个实体,且实体的字段必须跟表字段一致。这样一来,查询到的结果会自动封装到实体之中。如果实体字段和表字段名字不一致,封装是不会成功的。然而问题来了,Java字段命名方式是小驼峰命名,mysql字段命名方式是下划线命名,总不能为了兼容强行把Java的字段名改成下划线命名或者强行把MySQL字段名改成小驼峰命名吧?

    解决方式有多种。

    第一种就是在@Select的sql语句中用as给MySQL表字段起别名,别名跟Java的实体字段名字一致。

    第二种是使用mybatis提供的@Results注解和@Result注解进行手动映射。

    在这里插入图片描述

    **第三种方式是最方便的。**在配置文件中写入配置让mybatis开启下划线和驼峰命名的映射。

    在这里插入图片描述

    另外,在进行条件查询时,会出现问题。

    在这里插入图片描述

    方法是使用字符串拼接函数concat

    在这里插入图片描述

  • @Delete

  • @Insert

    如果想要获得插入之后的主键,可以添加一个注解,让插入之后生成的主键赋值给实体的id属性。

    在这里插入图片描述

  • @Update

接口方法之中可以传入参数,注解中对应位置使用#{}进行代替。

Java会通过反射获取到接口方法上的注解中的sql语句,然后把sql语句发送给MySQL数据库执行。MySQL数据库接收到sql语句,会先去缓存中查找是否存在这条sql语句,如果是直接执行,如果否,先进行sql语法检查,然后对sql进行优化,然后编译sql,然后把编译好的sql存入缓存以便下次执行一样的sql语句时提高性能。这种方式称为预编译sql。预编译SQL语句的过程是将SQL语句的结构和参数分离,先将SQL语句编译为一个可执行的执行计划,然后在每次执行时只需传入参数,无需重新编译,从而减少了重复解析和编译的开销。

delete from emp where id = #{id}实际上传给MySQL的是delete from emp where id = ?以及id的值。如果直接传给MySQL的语句是delete from emp where id = id,那预编译sql就不起作用了。

预编译sql可以提高性能,另外,也可以防止sql注入攻击。

sql注入攻击是怎么一回事呢?假设Java传给mysql的不是预编译sql形式的sql语句,而是一个拼接成的完整sql语句select count(*) from user where name='' and password='',以查询账号和密码进行登录操作。这时候,有人在表单中,随便写了个账号,但是密码写入'or '1'='1,传给MySQL的语句是select count(*) from user where name='fjewa;ofj' and password=''or '1'='1',这条sql语句永远会成功,用户无论是何种身份都可以登录。

预编译sql可以解决这个问题,因为它明确了where的字段只有name和password,不会有后面的or ‘1’ = ‘1’。

4、日志输出

为了更加方便查看执行什么sql语句以及执行的结果,需要查看日志。Mybatis默认是不打开日志的,需要在配置文件中进行配置。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

5、xml映射文件开发

注解开发虽然方便,但是只能执行简单的sql逻辑。想要执行复杂的sql逻辑,需要使用xml文件编写sql语句进行开发。xml映射文件有一些规范。

  • xml映射文件的名称与Mapper接口名称一致,并且将xml映射文件和mapper接口放置在相同包下(同包同名)。在maven项目中,最后编译之后,main包下的java和resource两个目录都会消失的。也就是说最后java和resource里面的文件都会在一个目录下。这样一来,就可以在resource下创建sql映射文件,在java里面创建接口,只要sql映射文件和接口文件的目录写成一样的,最后编译它们就会是一样的。注意,在resource下创建层次接口不能是“com.ghl”的形式,而是"com/ghl"的形式。
  • xml映射文件的namespace属性为Mapper接口全限定名一致。(方便映射)
  • xml映射文件中sql语句的id与mapper接口中的方法名一致,并保持返回类型一致。(方便映射)

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="com.iss.mapper.EmpMapper"><!--resultType:实体的全限定名,执行结果会封装到实体之中--><select id="selectEmp" resultType="com.iss.entity.Emp">select * from emp where id = #{id}</select>
</mapper>

想要调用接口中的方法来执行sql语句,接口中的方法肯定是没有这样的功能的,只有xml文件中才有sql语句。所以关键在于,如何将接口中的方法与xml文件进行映射。只要按照上边的规范正确地在xml文件中写内容,当调用接口中的方法时,mybatis会自动根据接口找到对应的xml文件,然后根据id找到方法对应的sql语句。

有一款插件可以挺方便根据接口跟xml文件的映射关系进行相互定位。MybatisX

在这里插入图片描述

查询

xml映射文件中使用select标签来进行查询。这个标签的最重要的属性有两个,一个是id(用来和接口方法进行对应的),一个是resultmap(用来把查询到的数据封装进实体类的)

准备工作:

  • 首先,由于在实体对象里,字段名使用驼峰命名,但是在数据库的字段名有时候并不是使用驼峰命名,所以有时候可能数据库的字段名与实体类的驼峰命名对应不上,这样会使得数据无法完成封装。解决方法是:在映射文件里的mapper标签里写一个resultmap标签,这个resultmap标签里面主要有两种小标签id和result。id主要用来进行主键进行映射,result主要用于对普通字段进行映射。两种小标签都有两个属性,分别是column(真正的字段名)和property(实体类的驼峰命名)。写完之后把resultmap作为查询标签的属性就可以进行映射了。

    在这里插入图片描述

  • 接着,查询语句里要有参数占位符用来指代接口方法传入的参数,有两种参数占位符:#{参数名},${参数名},前一种可以用来防止sql恶意注入(黑客攻击),后一种无法防止sql注入,安全性会差一点。

  • 注意,在核心配置文件里面,datasource标签里url那里一定要设置一个参数指定utf-8字符集,不然字符串字段查询到的内容总是null

跟普通的sql查询差不多。就是可能有参数占位符存在。

要注意一点,小于号要使用转义字符来写,因为在xml文件里边,小于号被认为是标签的起始,不会被认为是小于号。使用转义字符& lt ; (这里由于markdown自动识别成小于号了所以我直接这里加了两个空格进行处理)。

动态查询/动态sql

有这么多个字段,怎么知道用户想要查询哪个字段或者想要查询哪些字段呢?当然可以把所有可能全部写一遍,但是这样如果字段太多,会显得非常愚蠢。所以可以使用一种比较好的方法:动态查询。来实现动态查询多个字段的功能。

  • 使用if标签(配合where标签使用)来实现动态查询

要实现动态查询,其实就是在每一个条件上加上一个判断,只要判断传入的参数不为空,就使用这个参数进行查询就可以了。

所以使用if标签把条件给括起来(逻辑符也要)就可以了。但是if标签有一个问题,就是如果传入的第一个参数为空,这个参数恰好在第一个条件,那么会变成 where and 字段名 = 参数2 这样的形式,这不符合sql语法要求。**可以直接在where关键字的第一个条件写上1=1,这样就不会出现这样的问题。不过mybatis提供了一个where标签,直接使用where标签来代替where关键字就不会出现问题了,**这个标签会自动处理。where标签只会在子元素有内容的情况下才会插入子句,而且会自动去除子句开头的and和or。

if标签有一个属性test,要在test里面写判断,在标签体里写查询条件。

添加、修改和删除

  • 添加

使用insert标签进行数据添加。里面直接写insert into语句进行添加就可以了。

一个小细节。如果主键是默认自增,而且在执行接口方法的时候传入了一个没有定义主键的实体对象去添加,数据库里产生了主键,然而如何知道主键是什么呢?这个问题的解决方法可以在insert标签里设置两个属性来解决。两个属性配置上,实体中的主键字段在数据库添加完毕之后就会自动被赋值。

在这里插入图片描述

  • 修改

使用update标签进行修改。

调用接口方法传入一个实体对象,会根据实体对象的主键值和实体对象中每一个对象对应的值对对应记录的值进行修改。

动态修改:如果按照上边那种方法来写的话,那么每一次必定是修改数据库表中的全部字段。如果只想要修改某一些字段的话,就可以使用动态修改。即在set关键字下方写上if标签。这里同样会有一些bug出现,所以要将set关键字换成set标签。mybatis会自动解决bug冲突。

  • 删除

**删除单条记录:**写在delete标签里面。同样地如果想要动态删除,使用where标签和if标签。

删除多条记录:

这里如果不在xml文件里实现的话,其实可以定义一个数组,将要删除的记录的主键全部放到数组里边去,然后遍历数组,将数组里的元素一个一个传入接口方法里边就行。

不过mybatis对于这个东西有一个标签可以完成删除多条记录的功能。即foreach标签。这个标签用在where后边。

foreach有三个属性,collection用于接收接口方法传入的数组,mybatis会自动把这个数组放到一个map的值里边,键是array。所以collection属性里直接写array就可以了。item属性就是要遍历的字段,写上主键字段的名称就可以了。separator属性和open和close属性都是用来规范sql语法的。因为in后要有括号,括号中的每一个字段之间要有逗号隔开。

在这里插入图片描述

两个标签:sqlinclude。这两个标签是配套使用的。

在一个xml文件中,如果出现了大量的重复sql片段,可以使用这两个标签来解决。

<select id="selectAll" resultMap="BrandResultMap">select id,brand_name,enterprise_name,sort,introduction,statusfrom brand;
</select>
<select id="selectById" resultMap="BrandResultMap">select id,brand_name,enterprise_name,sort,introduction,statusfrom brandwhere id = #{id};
</select>

使用这两个标签过后,会变为:

<!--id就是用来标识这段sql代码的-->
<sql id="commonSql">select id,brand_name,enterprise_name,sort,introduction,status
</sql>
<select id="selectAll" resultMap="BrandResultMap">/*把sql的id填入refid*/<include refid="commonSql"/>from brand;
</select>
<select id="selectById" resultMap="BrandResultMap">/*把sql的id填入refid*/<include refid="commonSql"/>from brandwhere id = #{id};
</select>

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

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

相关文章

【大模型】快速体验百度智能云千帆AppBuilder搭建知识库与小助手

文章目录 前言千帆AppBuilder什么是千帆AppBuilderAppBuilder能做什么 体验千帆AppBuilderJava知识库高考作文小助手 总结 前言 前天&#xff0c;在【百度智能云智算大会】上&#xff0c;百度智能云千帆AppBuilder正式开放服务。这是一个AI原生应用开发工作台&#xff0c;可以…

【C++入门到精通】互斥锁 (Mutex) C++11 [ C++入门 ]

阅读导航 引言一、Mutex的简介二、Mutex的种类1. std::mutex &#xff08;基本互斥锁&#xff09;2. std::recursive_mutex &#xff08;递归互斥锁&#xff09;3. std::timed_mutex &#xff08;限时等待互斥锁&#xff09;4. std::recursive_timed_mutex &#xff08;限时等待…

【沁恒蓝牙mesh】CH58x DataFlash 详解

本文主要介绍了 沁恒蓝牙芯片 CH58x 的 DataFlash 分区以及读写操作以及原理 &#x1f4cb; 个人简介 &#x1f496; 作者简介&#xff1a;大家好&#xff0c;我是喜欢记录零碎知识点的小菜鸟。&#x1f60e;&#x1f4dd; 个人主页&#xff1a;欢迎访问我的 Ethernet_Comm 博…

CUMT--Java复习--JDBC编程

目录 一、JDBC简介 二、数据库访问 1、加载数据库驱动 2、建立数据连接 3、创建Statement对象 4、执行SQL语句 5、访问结果集 三、MetaData接口 1、DatabaseMetaData接口 2、ResultSetMetaData接口 四、事务 1、JDBC中的事务 2、保存点 3、批量更新 一、JDBC简…

韵达快递查询入口,一键将退回件筛选出来

批量查询韵达快递单号的物流信息&#xff0c;并将退回件一键筛选出来。 所需工具&#xff1a; 一个【快递批量查询高手】软件 韵达快递单号若干 操作步骤&#xff1a; 步骤1&#xff1a;运行【快递批量查询高手】软件&#xff0c;并登录 步骤2&#xff1a;点击主界面左上角的…

CSS-SVG-环形进度条

线上代码地址 <div class"circular-progress-bar"><svg><circle class"circle-bg" /><circle class"circle-progress" style"stroke-dasharray: calc(2 * 3.1415 * var(--r) * (var(--percent) / 100)), 1000" …

影响晶振频率稳定性的因素及解决方法

晶振作为电子设备中的核心元件&#xff0c;其频率稳定性对设备的性能和可靠性具有重要影响。晶发电子将介绍影响晶振频率稳定性的因素&#xff0c;并探讨相应的解决方法。 一、影响晶振频率稳定性的因素 频率&#xff1a;晶振的频率是影响其性能的最重要因素之一。在选择晶振…

初识Docker-什么是docker

Docker是一个快速交付应用、运行应用的技术 目录 一、Docker 二、运用场景 一、什么是Docker&#xff1f;它的作用是什么&#xff1f; Docker如何解决大型项目依赖关系复杂&#xff0c;不同组件依赖的兼容性问题? Docker允许开发中将应用、依赖、函数库、配置一起打包&…

基于SSM的勤工助学系统的设计与实现论文

勤工助学系统设计 摘要 随着信息互联网购物的飞速发展&#xff0c;一般企业都去创建属于自己的电商平台以及购物管理系统。本文介绍了勤工助学系统的开发全过程。通过分析企业对于勤工助学系统的需求&#xff0c;创建了一个计算机管理勤工助学系统的方案。文章介绍了勤工助学系…

SpringBoot访问外部接口的常见方式

文章目录 SpringBoot访问外部接口模拟服务接口RestTemplatepom.xmlRestTemplateConfigClientTestRestTemplateController.java结果 WebClientpom.xmlClientTestWebClientController.java结果 HttpClientpom.xmlClientTestHttpClientController.java结果 OkHttppom.xmlClientTes…

LeetCode Hot100 295.数据流的中位数

题目&#xff1a; 中位数是有序整数列表中的中间值。如果列表的大小是偶数&#xff0c;则没有中间值&#xff0c;中位数是两个中间值的平均值。 例如 arr [2,3,4] 的中位数是 3 。例如 arr [2,3] 的中位数是 (2 3) / 2 2.5 。 实现 MedianFinder 类: MedianFinder() 初始…

移动SEO:如何针对任何设备优化您的网站

您快速进行 Google 搜索并阅读一堆结果。然后&#xff0c;您会发现一些网站具有您正在寻找的答案。 但是你从SERP中选择的第一个&#xff0c;也是最有前途的网站&#xff0c;在你最喜欢的移动设备上无法正常工作。 所以&#xff0c;你关闭它&#xff0c;看看下一个网站是否有…

【Linux驱动】pinctrl 和 gpio子系统(一)—— pinctrl 节点解析,引入gpio子系统

裸机开发时&#xff0c;如果要点亮一个 LED&#xff0c;我们要做如下内容&#xff1a; 初始化时钟设置引脚复用为哪个功能&#xff0c;配置引脚的电气属性设置引脚的 IO 方向、初始值 有了设备树以后&#xff0c;我们可以通过 pinctrl 和 gpio 子系统来配置上述内容。 pinct…

基于深度学习的森林火焰烟雾检测系统(含UI界面,yolov8、Python代码,数据集)

项目介绍 项目中所用到的算法模型和数据集等信息如下&#xff1a; 算法模型&#xff1a;     yolov8 yolov8主要包含以下几种创新&#xff1a;         1. 添加注意力机制&#xff08;SE、CBAM等&#xff09;         2. 修改可变形卷积&#xff08;DySnake-主干c…

听GPT 讲Rust源代码--src/tools(18)

File: rust/src/tools/rust-analyzer/crates/ide-ssr/src/from_comment.rs 在Rust源代码中的from_comment.rs文件位于Rust分析器&#xff08;rust-analyzer&#xff09;工具的ide-ssr库中&#xff0c;它的作用是将注释转换为Rust代码。 具体来说&#xff0c;该文件实现了从注…

Django(二)

1.django框架 1.1 安装 pip install django3.21.2 命令行 创建项目 cd 指定目录 django-admin startproject 项目名mysite ├── manage.py [项目的管理工具] └── mysite├── __init__.py├── settings.py 【配置文件&#xff0c;只有一部分…

基于SpringBoot的考研专业课程管理系统 JAVA简易版

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 数据中心模块2.2 考研高校模块2.3 高校教师管理模块2.4 考研专业模块2.5 考研政策模块 三、系统设计3.1 用例设计3.2 数据库设计3.2.1 考研高校表3.2.2 高校教师表3.2.3 考研专业表3.2.4 考研政策表 四、系统展示五、核…

【krita】实时绘画 入门到精通 海报+电商+装修+修复手部

安装插件 首先打开comfyUI&#xff0c;再打开krita&#xff0c;出现问题提示&#xff0c; 打开 cd custom_nodes 输入命令 安装控件 git clone https://github.com/Acly/comfyui-tooling-nodes.git krita基础设置 设置模型 设置lora &#xff08;可设置lora强度 增加更多…

网站使用https认证

随着网络的普及和依赖程度的增加&#xff0c;网站安全性问题也日益凸显。为了确保用户和网站之间的数据传输安全&#xff0c;采用HTTPS认证已经变得至关重要。 1.数据安全是首要任务 在互联网上&#xff0c;信息传输是网站运作的基础。然而&#xff0c;未加密的传输容易受到中…

嵌入式中的基本定时器

学习目标 理解基本定时器的作用掌握定时器开发流程掌握基本定时器中断处理的操作流程掌握AHB和APB时钟查询方式理解周期,分频系数,周期计数,分频计数。掌握调试策略学习内容 基本定时器 只能用于定时计时操作,没有输出引脚通道的定时器,在GD32中, TIMER5和TIMER6为基本…