MySQL的增删查改
前言:本文基于若依前后端分离版本(Spring Boot 3.3.0 + Vue 3 + Activiti 8.1.0)进行改造,相关教程可以在网上找到。在撰写此博客期间,笔者刚刚开始接触 Java Web,本系列下的文章内容包含大量“个人初期”视角,注意鉴别。
概述
暂不考虑MySQL的一些底层实现,仅从基本的增删查改功能来看,我们似乎要使用大量的sql语句去实现这些功能,使用JDBC(Java Database connect)?这个实在是太麻烦了,要手动建立连接,写sql语句传值,小项目凑活一下应该问题不大,但是复杂项目就比较麻烦了,笔者没有试过跑JDBC,在这里贴一段GPT给出的插入数据的代码,当属性变多的时候,这代码就显得有些麻烦了。
1 | import java.sql.Connection; |
所以有没有一种方法,让我们把对数据库的操作变得更简单?函数形参直接传入实体类,函数自己去匹配字段插入数据库。这似乎就是MyBatis的作用:通过XML描述符把对象与存储过程用SQL语句关联起来。听着有些抽象,我第一次看见也觉得抽象。
举个例子
XML文件
现阶段我倾向于将MySQL中的每一张表等同于domain层的一个类,比如档案管理中:档案类&&档案表,进行增删查改时的对象应该是:一个对象&&一行记录,先不管怎么写入数据库的事,类和表之间应该存在一些预定义的关系,比如:private Long ID
可以对应 `id` bigint(20) NOT NULL COMMENT '档案ID'
。
基于这个前提,我们就需要准备实体类与对应表的详细映射关系,这些关系就保存在XML文件中。 比如(挑了个稍微短一些的):
type="FormTemplates"
是我们定义的实体类,property
是对应的类成员变量,column
是表中列的名字,这个对应关系叫他:FormTemplatesResult
1 | <resultMap type="FormTemplates" id="FormTemplatesResult"> |
一般情况下,查找操作似乎比较频繁,比如打开MySQL Workbench 中任意一张表的时候,默认执行了SELECT * FROM tb_form_templates;
,那么一个自然的想法,我们在xml中也可以设定一个可以复用的组件,专门保存上面这一句sql的结果?一些条件查询的语句可以在此基础上添加。同时给这个复用片段加id,下次可调用它。
1 | <sql id="selectFormTemplatesVo"> |
我们现在有了:类成员与表属性之间的映射关系、可复用的片段(从表中查全部数据)。现在尝试使用上面两个条件,实现:根据ID查找数据:selectFormTemplatesById。
我们可以给这个方法起个名字:selectFormTemplatesById
,我们还需要指定要查询的条件的类型private Long ID
的Long
。
我们提前准备了一段可复用的sql片段,它已经把我们要查找的全部数据拿了出来,我们在它的基础上根据id
进行筛选,使用它的方式就是把他include
进来,后一段继续增加条件,#{id}
是一个占位符,外部调用这个方法时,形参列表需要有一个叫id
的变量。
最终的查找结果,将会通过 最开始的代码块中我们指定的映射关系绑定到(所以是resultMap)FormTemplates
对象(也可以是对象列表)。
1 | <select id="selectFormTemplatesById" parameterType="Long" resultMap="FormTemplatesResult"> |
到这为止,我们基本指定了xml文件中的核心部件:
- 对象属性与表属性之间的对应关系
- 整体查找且可复用的sql片段
- 利用可复用片段 + ID查找对应数据的方法。
但是,我们如何让Java代码去访问这些方法呢?我们应该在最开就给他定义好,跟外面的某个Java接口绑定在一起,让:接口中的方法名 == xml中方法的id,具体来说就是接口中有selectFormTemplatesById
,xml文件中就得实现selectFormTemplatesById
方法。
那么到底怎么对应关系呢?xml文件最开始就要声明:
1 | <mapper namespace="com.iams.activiti8.mapper.FormTemplatesMapper"> |
就是我们外部定义的接口,外部的其他服务如果要操作数据库,也要通过这个接口。
FormTemplatesMapper
外部接口:mapper
感觉得多啰嗦两句(现阶段的理解):domain层与数据表对应,mapper层使用domain中的类,通过XML文件,去对应数据表
FormTemplatesMapper.java 使用 domain/FormTemplates.java && FormTemplatesMapper.xml 增删查改 tb_form_templates
domain/FormTemplates.java,作为数据传输整体贯穿其中(暂不考虑DTO)
现在来看接口,接口与实现对应,只不过这个实现是在xml中实现的。所以只要添加新的方法,对应也要在xml文件中添加新实现。
1 | public interface FormTemplatesMapper |
看这里的Long id
,是不是解释了上面按照id
查找数据的#{id}
占位符。
具体来怎么用?(我猜的,毕竟没怎么深入了解bean:)mapper中的每一个接口似乎被看作一个bean,通过类型自动注入,调用的方法嘛,非常的朴实无华,注意返回值就行。
1 |
|
MySQL语法
上面只是根据ID进行查找,那么如果进行一些其他的sql操作呢?所以这一个part主要记录一下sql语法。
增
1 | <insert id="insertFormTemplates" parameterType="FormTemplates" useGeneratedKeys="true" keyProperty="id"> |
useGeneratedKeys="true"
:表示使用自动生成的主键。keyProperty="id"
:指定将自动生成的主键值设置到 FormTemplates 对象的 id 属性中。insert into tb_form_templates
指定要插入的数据表<trim prefix="(" suffix=")" suffixOverrides=",">
构建列名<trim prefix="values (" suffix=")" suffixOverrides=",">
构建列名对应的值if test
语句用于条件判断,仅在属性不为空时才将对应的列名添加到插入语句中。
也就是通过上述元素,构建了一个sql语句,
1 | INSERT INTO tb_form_templates (form_key, template_path, created_time) |
删
1 | <delete id="deleteFormTemplatesById" parameterType="Long"> |
查
1 | <select id="selectFormTemplatesList" parameterType="FormTemplates" resultMap="FormTemplatesResult"> |
这里的目的是查找一个数据列表,似乎我们直接返回<include refid="selectFormTemplatesVo"/>
的结果就可以,但是这里又添加了一些其他的if test
的语句,而且注意这个方法是需要参数传入的:parameterType="FormTemplates"
。
- 如果传入的对象属性全是null,那么返回的就是全部数据。
- 如果存在某个值不为null,就会根据where构建条件查询,返回的也就是筛选过后的数据。
这样也就不需要按照每个属性单独写查询条件了。下面的修改操作也是如此。
改
1 | <update id="updateFormTemplates" parameterType="FormTemplates"> |