当前位置: 首页 > news >正文

MyBatis操作数据库实现

说明:MyBatis是作用于三层架构开发,数据访问层(Data Access Object)的框架,用于访问数据库,对数据进行操作。

一、环境搭建

首先,创建一个SpringBoot模块,然后把MyBatis的环境搭建起来。因为MyBatis是作用于Dao层的,故先省去Service层,重点关注Dao层中与数据库的交流。

(1)创建Springboot模块

我这里是手动创建SpringBoot模块方式,在idea中创建一个SpringBoot模块,参考(http://t.csdn.cn/RJ2gu)

pom.xml文件中添加的继承和依赖

在这里插入图片描述

(2)添加MyBatis依赖

在SpringBoot模块基础上,添加MyBatis依赖和数据库的配置文件

添加MyBatis依赖

在这里插入图片描述

添加数据库的配置文件(application.properties)

放在 src/main/resources 目录下,注意 数据库链接(数据库端口号、数据库名)、用户名和密码
在这里插入图片描述

(3)添加其他依赖

启动项目,我们还需要一些额外的依赖(lombok、druid、test),方便开发和测试,另外数据库的配置文件也添加一些额外配置

pom.xml文件

lomhok:可以帮助我们一键生成javaBean的set()、get()、toString()方法;

druid:使用阿里巴巴提供的连接池;

test:方便测试功能;
在这里插入图片描述

数据库的配置文件(application.properties)

开启驼峰支持:Java和MySQL的命名规范不同,如createTime对应的是MySQL中的create_time,开启此设置,可以自动匹配;

SQL日志:可以将执行的SQL语句打印在控制台中,方便我们排查SQL语句是否执行错误;

在这里插入图片描述

(4)准备数据库

创建数据库,注意数据库名和上面application.properties中配置的数据库名要一致

创建表,添加一些数据

create database mybatis;use mybatis;create table tb_stu(id int auto_increment primary key comment '序列号',name varchar(10) comment '姓名',gender varchar(2) comment '性别',age tinyint comment '年龄',create_time date comment '创建日期'
) comment '学生表';insert into tb_stu values (null, '加缪', '男', 20, null),(null, '萨特', '男', 25, null),(null, '陀思妥耶夫斯基', '男', 30, '2023-06-08'),(null, '阿加莎克里斯蒂','女','27', null);

(5)创建类

创建学生类(Student)

@Data、@NoArgsConstructor、@AllArgsConstructor,相当于自动为类添加了set()、get()、toString()、无参和全参构造方法

package com.essay.domain;import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;import java.time.LocalDate;/*** 学生类*/
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {private Integer id;private String name;private String gender;private Integer age;private LocalDate createTime;
}

创建Mapper类

Mapper,是Dao层中,MyBatis的取名方式,也是Dao层的具体表现之一。

package com.essay.mapper;import org.apache.ibatis.annotations.Mapper;@Mapper
public interface StuMapper {/*** 访问数据库,处理数据*/}

创建启动类(Start)

package com.essay;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
public class Start {public static void main(String[] args) {SpringApplication.run(Start.class, args);}
}

创建测试类(MyTest),模拟Controller层。本来应该注入Service层依赖,因为是介绍MyBatis,我这里直接注入Mapper(Dao层)依赖

package com.essay;import com.essay.mapper.StuMapper;
import org.springframework.boot.test.context.SpringBootTest;@SpringBootTest
public class MyTest {// 注入Mapper依赖@Autowiredprivate StuMapper stuMapper;// 接收前端请求,响应数据
}

另外,还需要注意两点:

a. 测试类的目录要与main中的启动类平行

在这里插入图片描述

b. 测试类的类名,不要取名为Test,因为测试的注解也是Test(@Test)

至此,环境搭建完成,可以开始紧张又刺激的开发了。

二、注解方式

注解方式,是将对数据库进行操作的SQL语句,写在Dao层的各个方法上。

(1)查找所有:

在MyTest(Controller层)中接收请求

@SpringBootTest
public class MyTest {// 注入Mapper依赖@Autowiredprivate StuMapper stuMapper;/*** 查找所有*/@Testpublic void findAll(){List<Student> list = stuMapper.findAll();System.out.println(list);}
}

在StuMapper(Dao层)中访问数据库,返回数据

@Mapper
public interface StuMapper {/*** 查找所有*/@Select("select * from tb_stu")List<Student> findAll();
}

在这里插入图片描述

(2)添加数据:

在MyTest(Controller层)中接收请求

这里是我手动创建的对象,在正式业务中,数据会由前端传过来,封装成一个对象(需要使用@RequestParam注解),另外对象的创建时间会在Service层中设置,之后再传至Dao层写入数据库。

    /*** 添加记录*/@Testpublic void insertStu(){Student s = new Student();s.setName("伏尔泰");s.setGender("男");s.setAge(40);s.setCreateTime(LocalDate.now());stuMapper.insertStu(s);}

在StuMapper(Dao层)中访问数据库,添加数据

#{},表示对象s中的对应的属性值,所以一定要注意,#{}里面的名称是对象里面的属性名,而不是数据库里面的字段名

    /*** 添加记录*/@Insert("insert into tb_stu(name,gender,age,create_time) value(#{name},#{gender},#{age},#{createTime})")void insertStu(Student s);

在这里插入图片描述

(3)修改数据:

在MyTest(Controller层)中接收请求,同样,具体业务中,被修改的对象会被前端传过来,我这里是手动创建模拟修改

    /*** 根据ID修改记录*/@Testpublic void updateStu(){Student s = new Student();s.setId(1);s.setName("加缪——修改后");stuMapper.updateStu(s);}

在StuMapper(Dao层)中访问数据库,修改数据

    /*** 修改记录*/@Update("update tb_stu set name=#{name},gender=#{gender},age=#{age} where id=#{id}")void updateStu(Student s);

这里,问题出现了,除了name,其他字段也被修改成了。这是因为传进来的对象,仅设置了name,其他属性未设置默认是null。那有没有一种方案,修改时判断对象的属性值是否为空,不为空说明需要修改此字段,则修改数据库中的数据;为空说明不需要修改此字段,那么数据库中就不修改,在xml方式中可以解决此问题(在修改之前,根据ID把数据库中的对象值先找出来,然后在Service层做逻辑判断,是否也可以解决?)。

在这里插入图片描述

(4)删除数据:

在MyTest(Controller层)中接收请求,我这里模拟删除ID是为1的记录

    /*** 根据ID删除记录*/@Testpublic void deleteStu(){Integer id = 1;stuMapper.delete(id);}

在StuMapper(Dao层)中访问数据库,删除数据

    /*** 根据ID删除记录*/@Delete("delete from tb_stu where id=#{id}")void delete(Integer id);

在这里插入图片描述
在这里插入图片描述

小结

以上展现了使用注解方式,对数据库进行查找所有、添加数据、根据ID修改和删除操作,如果还需要做条件查找、删除所有记录等功能,可以先写好SQL语句,根据SQL语句所需要的参数,再设计好Controller层的代码。

三、xml方式

除了注解方式,MyBatis还提供了xml的方式,将方法对应的SQL语句配置到xml文件中,通过方法调用,实现对数据操作。首先,创建好Mapper类对应的xml文件。

创建xml文件

创建xml文件,需要注意以下两点:

a. xml文件需要和Mapper类平行同包同名

在这里插入图片描述

b. 在Resource文件夹中创建多级目录,不能使用点(.),要用斜杠(/)

在这里插入图片描述

在这里插入图片描述

以上两点至关重要,这是xml文件与Mapper类建立联系的过程,联系建立不起来,程序跑不起来。

文件创建好之后,首先在xml文件开头添加约束,不要手敲,建议从官网复制过来(https://mybatis.net.cn/getting-started.html)

Mybatis中文官网

约束添加后,敲一个mapper标签,属性namaspace为Mapper类的全类名。同样,也不要手敲,点击类文件,快捷键ctrl+alt+shift+c,复制粘贴过来。

在这里插入图片描述

(1)查找所有:

在xml文件中配置查找所有方法

StuMapper.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.essay.mapper.StuMapper"><!--1.查找所有--><select id="findAll" resultType="com.essay.domain.Student">select * from tb_stu;</select></mapper>

StuMapper类(前面写的注解删掉)

    /*** 查找所有*/List<Student> findAll();

需要注意以下两点:

a. xml文件中标签id要与StuMapper类中的对应的方法名一致

b. resultType为返回类型,即返回的数据,需要封装为对象的对象的类全名。

在这里插入图片描述

(2)添加数据:

在xml文件中配置添加数据方法

    <!--2.添加数据--><insert id="insertStu">insert into tb_stu(name,gender,age,create_time) value(#{name},#{gender},#{age},#{createTime})</insert>

StuMapper类(前面写的注解删掉)

    /*** 添加记录*/void insertStu(Student s);

MyTest(测试类)

    /*** 添加记录*/@Testpublic void insertStu(){Student s = new Student();s.setName("卢梭");s.setGender("男");s.setAge(20);s.setCreateTime(LocalDate.now());stuMapper.insertStu(s);}

在这里插入图片描述

(3)修改数据:

前文说过使用注解方式修改数据的问题,修改指定字段的数据,因为传入Dao层的是一个新建的javaBean对象,未设置的属性,是null,修改数据库时会覆盖原数据。导致欲修改的字段,修改成功;未设置的字段,因为修改被置空。

使用xml方式,可以解决这个问题。使用if标签,判断传入的属性值是否为空,不为空说明是前端请求需要修改的字段,就修改;为空,说明是前端不需要修改的字段,就不修改。

StuMapper.xml文件(注意不要漏掉最后的where语句)

    <!--3.修改数据--><update id="updateStu">update tb_stu<set><if test="name!=null and name!='' ">name=#{name},</if><if test="gender!=null and gender!='' ">gender=#{gender},</if>/*因为age是Integer类型,仅判断不为null就行,下面的时间格式也是*/<if test="age!=null" >age=#{age},</if><if test="createTime!=null ">create_Time=#{createTime},</if></set>where id=#{id}</update>

StuMapper类(前面写的注解删掉)

    /*** 修改记录*/void updateStu(Student s);

MyTest(测试类),测试只修改ID为1的姓名字段

    /*** 根据ID修改记录*/@Testpublic void updateStu(){Student s = new Student();s.setId(1);s.setName("加缪——修改后");stuMapper.updateStu(s);}

执行程序,达到了预期结果。

在这里插入图片描述

需要注意以下两点

a. 不要在set标签里面写注释,程序执行时会把注释也当做SQL语句的内容的,所以程序会报错;

在这里插入图片描述

b. set标签里面的每一个修改语句,末尾都要加一个英文逗号(,)

(4)删除数据:

StuMapper.xml文件

    <!--4.删除数据--><delete id="deleteStu">delete from tb_stu where id=#{id}</delete>

StuMapper类(前面写的注解删掉)

    /*** 根据ID删除记录*/void deleteStu(Integer id);

MyTest(测试类),测试删除ID为1的记录

    /*** 根据ID删除记录*/@Testpublic void deleteStu(){Integer id = 1;stuMapper.deleteStu(id);}

在这里插入图片描述
在这里插入图片描述

小结

使用xml方式的where(条件查找)、set、if标签,可以完成一些复杂的SQL语句,另外,使用include标签,可以将重复的SQL语句抽取出来,给其他的语句复用。

如我们查询所有语句,使用全字段id,name,gender,age,create_time比使用*效率高,我们就可以把这部分抽出来。

    <!--定义SQL片段--><sql id="selectAll">select id,name,gender,age,create_time</sql><!--1.查找所有--><select id="findAll" resultType="com.essay.domain.Student"><include refid="selectAll"></include>from tb_stu</select>

需要注意,写在sql片段内的SQL语句末尾不要加分号(建议xml内的所有语句末尾都不要加分号)。因为分号表示语句结束,加了分号被其他操作引用时,其他语句操作都会失效。
在这里插入图片描述

总结

(1)如果执行过程中出现以下异常,排查方向如下:

空指针异常:(1)检查数据库配置文件;(2)检查依赖注入和控制反转相关的注解

SQL异常:检查注解和xml文件中的SQL语句是否有错误

(2)关于注解方式和xml方式的选择,在MyBatis中文官网(https://mybatis.net.cn/getting-started.html)中有段话,值得参考。
在这里插入图片描述

相关文章:

MyBatis操作数据库实现

说明&#xff1a;MyBatis是作用于三层架构开发&#xff0c;数据访问层&#xff08;Data Access Object&#xff09;的框架&#xff0c;用于访问数据库&#xff0c;对数据进行操作。 一、环境搭建 首先&#xff0c;创建一个SpringBoot模块&#xff0c;然后把MyBatis的环境搭建…...

Git GitLab 使用及规范

Git 基本操作 Git安装配置及基本使用 从官网下载安装包&#xff0c;手动完成安装。打开Git Bash命令行工具&#xff0c;执行命令ssh-keygen -t rsa -C Email-Addresss生成一个密钥对。登录到GitLab&#xff0c;点击右上角你的用户头像&#xff0c;点击Edit Profile settings&…...

【SpringCloud——Sentinel】

一、什么是雪崩&#xff1f; 微服务调用链路中的某个服务发生故障&#xff0c;引起整个链路中的所有微服务都不可用&#xff0c;这就是雪崩。 二、解决雪崩问题的常见措施 1、超时处理 设定超时时间&#xff0c;请求超过一定时间没有响应就返回错误信息&#xff0c;不会无休…...

面试专题:计算机网络常见面试点总结

socket、tcp、udp、http 的认识及区别 socket、tcp、udp、http 的认识及区别​ 一、先来一个讲TCP、UDP和HTTP关系的 1、TCP/IP是个协议组&#xff0c;可分为三个层次&#xff1a;网络层、传输层和应用层。 在网络层有IP协议、ICMP协议、ARP协议、RARP协议和BOOTP协议。 在传…...

PageHelper失效问题

问题出现记录&#xff1a; 修改代码后&#xff0c;出现分页失效问题&#xff0c;原本的代码再设置了 PageHelper.startPage(pageNum, pageSize);后只有一个mysql查询&#xff0c;我在原本的业务查询前&#xff0c;新增了其他的Mysql查询&#xff0c;导致原需要分页的查询失效 …...

Linux常用命令——grep命令

在线Linux命令查询工具 grep 强大的文本搜索工具 补充说明 grep&#xff08;global search regular expression(RE) and print out the line&#xff0c;全面搜索正则表达式并把行打印出来&#xff09;是一种强大的文本搜索工具&#xff0c;它能使用正则表达式搜索文本&…...

学校热水供应系统方案

学校热水供应系统是现代化校园建设的重要组成部分。一套高效、可靠、安全、环保的热水供应系统&#xff0c;不仅能够满足学生、教职工的日常生活需求&#xff0c;也能提高学校形象和竞争力。 在设计学校热水供应系统方案时&#xff0c;需要考虑以下几个方面&#xff1a; 一、热…...

chatgpt赋能python:Python怎么写绝对值

Python怎么写绝对值 在Python编程语言中&#xff0c;有很多常用函数。其中包括求绝对值的函数。在这篇文章中&#xff0c;我们将介绍如何在Python中使用绝对值函数&#xff0c;并提供一些示例。 什么是绝对值函数&#xff1f; 绝对值函数是一个数学中常用的函数&#xff0c;…...

研发工程师玩转Kubernetes——Node亲和性requiredDuringSchedulingIgnoredDuringExecution几种边界实验

在《研发工程师玩转Kubernetes——使用Node特性定向调度Pod》中&#xff0c;我们提到requiredDuringSchedulingIgnoredDuringExecution只有在规则被满足的时候才能执行调度。本节我们将测试几种边界情况&#xff0c;看看Kubernetes的行为。 没有满足的条件 假设我们测试的Nod…...

OpenCV中的图像处理3.9(六)轮廓线特征与属性

目录 3.9 OpenCV中的轮廓线3.9.1 轮廓线&#xff1a;入门目标什么是轮廓线&#xff1f;如何绘制轮廓线&#xff1f;轮廓线逼近法 3.9.2 轮廓线的特征1. 矩2. 轮廓线面积3. 轮廓线周长4. 轮廓逼近5. 凸面体6. 检查凸性7. 边界矩形8. 最小包围圈9. 拟合椭圆10. 拟合直线 3.9.3 轮…...

burpsuite+xray实现联动测试(手动分析和自动化测试同时进行)

目的&#xff1a;安全测试过程中手动分析测试与xray自动化扫描测试结合&#xff0c;这样可以从多层保障安全测试的分析&#xff0c;针对平台业务接口量大的安全测试是十分有用的&#xff0c;可以实现双向测试同时开始。 xray简介 xray 是一款功能强大的安全评估工具&#xff…...

2023年专业连锁行业研究报告

第一章 行业概况 专业连锁行业是指以连锁经营模式运营的公司&#xff0c;其主要业务涵盖零售、餐饮、酒店、医疗、教育等领域。这些公司通过规模化、标准化的经营模式和供应链管理&#xff0c;提供专业化、高质量的产品和服务。专业连锁行业在全球范围内蓬勃发展&#xff0c;并…...

Mysql数据库(六):基本的SELECT语句

基本的SELECT语句 前言一、SELECT...二、SELECT ... FROM三、列的别名四、去除重复行五、空值参与运算六、着重号七、查询常数八、显示表结构九、过滤数据 前言 本博主将用CSDN记录软件开发求学之路上亲身所得与所学的心得与知识&#xff0c;有兴趣的小伙伴可以关注博主&#…...

在CentOS7环境中,实现使用openresty配置文件,达到jwt指定用户userid不能访问的效果

#在CentOS7环境中&#xff0c;实现使用openresty配置文件&#xff0c;达到jwt指定用户userid不能访问的效果。 首先&#xff0c;你需要安装 OpenResty 和 JWT 组件&#xff1a; 安装 OpenResty 参考 OpenResty 的官方安装文档&#xff0c;在终端执行如下命令&#xff1a; $…...

SpringBoot 源码分析初始化应用上下文(1)-createApplicationContext

前言&#xff1a;springBoot的版本是 2.2.4.RELEASE 一、入口 /*** Run the Spring application, creating and refreshing a new* {link ApplicationContext}.* param args the application arguments (usually passed from a Java main method)* return a running {link A…...

STM32队列

目录 什么是队列&#xff1f; 队列特点 1. 数据入队出队方式 2. 数据传递方式 3. 多任务访问 4. 出队、入队阻塞 队列相关 API 函数 1. 创建队列 参数&#xff1a; 2. 写队列 参数&#xff1a; 返回值&#xff1a; 3. 读队列 参数&#xff1a; 返回值&#xf…...

探索Beyond Compare:让文件比较和管理变得简单高效

在这个信息爆炸时代&#xff0c;我们的日常生活和工作中需要处理大量的数据和文档。在这个过程中&#xff0c;有时候我们会面临找出不同文件之间的差异、合并重复内容等需求。那么&#xff0c;有没有一款软件可以帮助我们轻松地完成这些任务呢&#xff1f;答案当然是肯定的&…...

动态网站Servelt基础

文章目录 一、Servlet基础&#xff08;一&#xff09;Servlet概述1、Servlet是什么2、Servlet容器3、Servlet应用程序的体系结构 &#xff08;二&#xff09;Servlet的特点1、功能强大2、可移植3、性能高效4、安全性高5、可扩展 &#xff08;三&#xff09;Servlet接口1、Servl…...

Docker 网络

Docker 网络实现原理 Docker使用Linux桥接&#xff0c;在宿主机虚拟一个Docker容器网桥(docker0)&#xff0c;Docker启动一个容器时会根据Docker网桥的网段分配给容器一个IP地址&#xff0c;称为Container-IP&#xff0c;同时Docker网桥是每个容器的默认网关。因为在同一宿主机…...

Tomcat的优化

Tomcat的优化 一、Tomcat 优化Tomcat 配置文件参数优化 二、系统内核优化三、Tomcat 配置 JVM 参数&#xff1a;参数含义 一、Tomcat 优化 Tomcat默认安装下的缺省配置并不适合生产环境&#xff0c;它可能会频繁出现假死现象需要重启&#xff0c;只有通过不断压测优化才能让它…...

web vue 项目 Docker化部署

Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段&#xff1a; 构建阶段&#xff08;Build Stage&#xff09;&#xff1a…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

linux 错误码总结

1,错误码的概念与作用 在Linux系统中,错误码是系统调用或库函数在执行失败时返回的特定数值,用于指示具体的错误类型。这些错误码通过全局变量errno来存储和传递,errno由操作系统维护,保存最近一次发生的错误信息。值得注意的是,errno的值在每次系统调用或函数调用失败时…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

【JVM】Java虚拟机(二)——垃圾回收

目录 一、如何判断对象可以回收 &#xff08;一&#xff09;引用计数法 &#xff08;二&#xff09;可达性分析算法 二、垃圾回收算法 &#xff08;一&#xff09;标记清除 &#xff08;二&#xff09;标记整理 &#xff08;三&#xff09;复制 &#xff08;四&#xff…...

什么是VR全景技术

VR全景技术&#xff0c;全称为虚拟现实全景技术&#xff0c;是通过计算机图像模拟生成三维空间中的虚拟世界&#xff0c;使用户能够在该虚拟世界中进行全方位、无死角的观察和交互的技术。VR全景技术模拟人在真实空间中的视觉体验&#xff0c;结合图文、3D、音视频等多媒体元素…...

解析两阶段提交与三阶段提交的核心差异及MySQL实现方案

引言 在分布式系统的事务处理中&#xff0c;如何保障跨节点数据操作的一致性始终是核心挑战。经典的两阶段提交协议&#xff08;2PC&#xff09;通过准备阶段与提交阶段的协调机制&#xff0c;以同步决策模式确保事务原子性。其改进版本三阶段提交协议&#xff08;3PC&#xf…...

加密通信 + 行为分析:运营商行业安全防御体系重构

在数字经济蓬勃发展的时代&#xff0c;运营商作为信息通信网络的核心枢纽&#xff0c;承载着海量用户数据与关键业务传输&#xff0c;其安全防御体系的可靠性直接关乎国家安全、社会稳定与企业发展。随着网络攻击手段的不断升级&#xff0c;传统安全防护体系逐渐暴露出局限性&a…...