Java注解实现增删改查CRUD

2023-11-09

以前,我们都把对数据库的增删改查语句写在xml文件中(详见:《程序员成长笔记(一)》第三部分,第四章,第四节)。

由于Java注解的简洁高效,在Java注解的思想(干掉xml)下,现在越来越多的人使用java注解来进行增删改查操作。

而且MyBatis3也支持并鼓励我们使用Java注解来进行CRUD操作。

注:CRUD即:增Create、查Retrive、删Delete、改Update。

 

下面以示例进行说明

本例子的软硬件环境:

     Windows7、Eclipse(Oxygen.3a Release)、Jdk1.8、MyBatis(3.4.5)、SpringBoot(2.0.1.RELEASE)、MySQL。

一级颜色:绿色    二级颜色:黄色     注意事项:红色      插入说明:蓝

 

增@Insert

先给出MySQL数据库中的相关employee表

增(简单增)示例:

数据访问层中的查询语句示例:

注:如果参数只有一个,那么可以直接#{属性名}进行属性值获取,如果有多个参数,必须使用@Param指明。

 

增(同时获取主键)方式一:

注:如果只有一个参数的话,那么可以不使用@Param,此时#{xxx}keyProperty = “xxx”中的xxx可以直接写实体类模型的属性名

注:如果有多个参数,那么我们需要使用@Param来进行指明,当然也推荐一个参数时也使用@Param注解。如果使用@Param指明参数了,且在注解中使用到了该参数的某些值时,一定要指明是该参数的。

如:这里的keyProperty = “e.id”是可以的;而keyProperty = “id”不可以。

 

增(同时获取主键)方式二:

注:方式二的注意事项与方式一一样。

 

增(既有实体参数,又有普通参数):

注:使用注解CRUD时,可以多个参数,这些参数可以是普通参数,也可以是复杂参数。

注:使用自动获取主键@Options或@SelectKey能正常获取到该对象插入数据库表中后的主键。

 

删@Delete

先给出MySQL数据库中的相关employee表

删(简单删)示例:

 

 

改@Update

先给出MySQL数据库中的相关employee表

 

改(简单改)示例:

 

查@Select

先给出MySQL数据库中的相关employee表

 

简单查(以“一般”类型 接收数据)示例:

 数据访问层中的查询语句示例一:

数据访问层中的查询语句示例二:

 

简单查(以 对象模型 接收数据)示例:

数据访问层中的查询语句示例:

注:如果没有任何数据,那么返回的Employy对象为null。 

注:id = true出现在哪里,就说明那个参数是主键。

如:

就说明idCard是主键。

注:如果接收查询结果的,是一个对象模型,那么程序是通过对应的有参构造或则无参构造+setter方法,将结果放进实体类模    型的。

   即:这就要求我们,在创建实体类模型时,一定要创建有对应的有参构造或无参构造+setter方法。

 

注:如果column名字与property不一致,那么需要在Result中指出来。

 

简单查(以 Map<String, Object> 接收数据)示例:

注:如果以Map<String, Object>来接收数据的话,MyBatis其实默认是以Map接口的HashMap实现来接收
       数据的;我们知道HashMap是无序的,比如SELECT e.id,e.e_name,e.e_gender,e.e_age …… 时,
       将map结果进行toString的话,就会观察到输出的字段的顺序不一定是id、e_name、e_gender、e_age;
       此时,如果我们想使map中的数据顺序是SQL语句指定的字段顺序的话,那么可以使用LinkedHashMap
       来接收查询出来的数据。

注:上图中的此写法只能接收一条(一行)数据内容。如果想接收多条(多行)数据内容,那么可以:

法一:以形如List<Map<String, Object>>这样的来接收多行数据。一个Map<String, Object>只存储一行数据。

法二:

   每一行数据专门拿一个对象模型来接收,并指定以该模型的哪一个属性作为key。

注:法一是List的每一个Map中只有一条数据;法二是多条数据都放在同一个Map中,以不同的key来对应不同的行。

注:法二依赖于对象模型,且法二在选择以对象的什么属性作为key时,要考虑是否会重复(如果作为key的属性的属性
     值可能会重复,那么在Map里可能发生数据覆盖的情况)。

 

简单查(以 集合类型 接收数据)示例:

示例一:

示例二:

注:如果查询结果横跨多个实体模型,那么我们使用List来接收数据。

 

 

动态语句:

我们都知道如何在xml中处理动态的SQL语句,那么使用Java注解如何处理呢?需要使用@xxxProvider,并指定(经过逻辑处理后)返回SQL语句的方法,以及该方法所在的类

注:使用@xxxProvider时,就不要使用@Param了,否者容易出错。

注:xxx为InsertUpdateDeleteSelect

注:这些(代理)方法最好不要重载,避免不必要的问题。

 

注:我们可以单独创建一个package、创建一个类来放置这些方法,如:

 

动态增@InsertProvider

单个参数:

数据访问层中的方法示例:

注:@InsertProvider需要指定(经过逻辑处理后)返回SQL语句的方法,以及该方法所在的类

 

给出逻辑处理方法示例:

 

多个参数:

数据访问层中的方法示例:

注:@InsertProvider需要指定(经过逻辑处理后)返回SQL语句的方法,以及该方法所在的类

 

给出逻辑处理方法示例:

注:如果数据访问层中的对应的方法有多个参数时,那么此方法的参数类型必须为Map<String,Object>;

注:此方法需要返回一个SQL字符串。

 

同时获得主键(获得主键的方式和@Insert是一样的):

获得主键方式一:

  

获得主键方式二:

 

 

批量增:

提示:批量增也能同时获取到主键,与上面的单个增的自动获取主键方式一样;这里就不再演示了

数据访问层中的方法示例:

注:@InsertProvider需要指定(经过逻辑处理后)返回SQL语句的方法,以及该方法所在的类

给出逻辑处理方法示例一(直接循环拼接sql语句):

注:使用#{}防止sql注入

 

注:在拼接的sql字符串中,用的直接是map中的key(即:上图Map中的key为listTest),而不是我们新new的集合对象(我们新new一个集合来获取map中对应key的集合的目的是:帮助我们知道集合的长度,进而进行逻辑判断)。

   调用上图的方法,传过去的是这个:

注:由于我们的目的只是利用新new的集合来获取对应key的集合的长度,所以,即使我们不使用泛型,直接使用Map<String,Object>,(经测试)也是可以的。

给出逻辑处理方法示例二(采用MessageFormat拼接sql语句):

注:MessageFormat模板中的{0}即为第一个占位符。

注:使用#{}防止sql注入

注:和方式一一样,参数可以直接Map<String, Object>也行。

     拼接sql字符串时,用的直接是map中的key(即:上图Map中的key为listTest),而不是我们新new的集合对象。

 

特别说明:

在数据访问层(即:Mapper层)调用SQL的代理方法时,我们也可以直接传递List过去,代理方法用Map接收,如:

Mapper层中的方法

处理SQL的方法

注:此时Mapper中的方法里的参数前,务必要有@Param,其值将被作为Map中的key;否者就要严格按照源码中的arg0之类的作为key了,最下面会讲到。

注:Provider中接收时,可以在接收参数时,就指定对应的泛型;也可以用Map<String, Object>接收后,再拆箱。

 

如果我们是将连库操作的数据放在Map<String ,Object>中项数据库表中插入的话,我们可以这么获取主键

Mapper层中的方法为:

注:这里以@Options为例的,使用@SelectKey获取主键也是一样的。

 

我们在调用dynamicInsertMultiParam这个方法时,在传过去的Map参数中,多放一个key,来接收新增后查询出来的id,如:

注意:key要和@Options注解中的keyProperty对应。

 

可以看见,获取到了新增后的id:

 

动态删@DeleteProvider

数据访问层中的方法示例:

注:@InsertProvider需要指定(经过逻辑处理后)返回SQL语句的方法,以及该方法所在的类

给出逻辑处理方法示例:

注:此方法需要返回一个SQL字符串。

注:当需要传递多个参数时,处理方式与@InsertProvider一样。

 

 

动态改@DeleteProvider

数据访问层中的方法示例:

注:@InsertProvider需要指定(经过逻辑处理后)返回SQL语句的方法,以及该方法所在的类

给出逻辑处理方法示例:

注:此方法需要返回一个SQL字符串。

注:当需要传递多个参数时,处理方式与@InsertProvider一样。

 

动态查@SelectProvider(示例一)

数据访问层中的方法示例:

注:@InsertProvider需要指定(经过逻辑处理后)返回SQL语句的方法,以及该方法所在的类

注:@InsertProvide与@Insert一样,如果column与property不一致,那么需要使用@Results指明对应关系。

 

给出逻辑处理方法示例:

 

注:因为参数没有放入一个实体类或Map中,所以这里#{}无法使用;因此建议:如果是使用了xxxProvider注解,那么参数都尽量放入实体类或Map中进行传参。

注:此方法需要返回一个SQL字符串。

注:当需要传递多个参数时,处理方式与@InsertProvider一样。

 

 

 

持有对象、集合:

声明:在分布式集群项目中,我们一般都会尽量避免显示的主外键关系、持有对象、持有集合等情况,目的是:降低耦合,方便程序的扩展以及后期维护等

 

注:如果遇见了持有对象持有集合等情况,如果多次查询能够解决问题,那么就尽量避免一次性全部查询;如果非要一次查询解决持有对象持有集合的问题,那么需要引入xml文件,在xml文件中配置映射。

注:虽然@Result注解有@One、@Many注解,但是目前来说个人感觉并不那么好用。

 

动态查@SelectProvider(示例二)

数据访问层中的方法示例

Sql代理方法为

单元测试中的测试方法为

 

xml示例(持有对象):

说明:一个people持有一个身份证idcard对象

People实体类:

people表:

Idcard实体类:

 

idcard表:

 

xml文件位置:

数据访问层中的方法:

xml中的相关配置为:

注:更多关于xml中配置sql映射的内容,详见《程序员成长笔记(一)》第三部分,第四章,第四节。

直接使用注解执行脚本示例:

mapper层中方法是这样的:

注:此方式和xml的方式几乎一致。

注:此方式只不过是将一些逻辑交给ibatis来处理了;当然我们也可以自己处理,如使用@SelectProvider等
        注解来处理这些逻辑。

 

Mapper接口中,调用方法时,参数是这么与sqlProvider中的形参匹配的(这是源码)

extractProviderMethodArguments方法是这样的:

 

所以,其实我们的mapper中的方法里,可以有多个形参,代理方法中也可以有多个形参如:

对应的代理方法为

注:由源码可知:时通过key来进行参数的匹配的。我们可以通过使用@Param来指定参数的key为多少,这样就能准确地匹配了。

 

注:参数前其实不使用@Param也是可以的。但是不建议这么做,因为如果我们不使用@Param来指定key的话,那么程序就会按照参数的顺序依次以arg0、arg1、arg2……来作为Map中的key;所以如果我们在mapper中对应的方的参数前不写key的话,那么在sqlProvider中的对应的方法的形参的顺序就要和传入时参数的顺序一致。而使用@Param的话,则没有此顾忌。

 

注:如果Mapper层中的方法传递多参数时,部分参数前使用了@Param()注解(或sqlProvider中对应方法的部分形参前使用了@Param()注解),那么其会顶替原来默认的key;以Mapper中的方法为例:

那么key依次为map1 和 arg1,即:map1取代了arg0作为key。对应sqlProvider中就要以相应的key取值。

 

注:更多细节上的使用,这里就不再一一说明了。感兴趣的话,可以去看下对应的源代码。

 

^_^ demo项目托管链接
             https://github.com/JustryDeng/PublicRepository

^_^ 如有不当之处,欢迎指正

^_^ 本文已经被收录进《程序员成长笔记(二)》,作者JustryDeng

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java注解实现增删改查CRUD 的相关文章

随机推荐

  • Servlet+JDBC实战开发书店项目讲解第三篇:商品查询实现

    Servlet JDBC实战开发书店项目讲解第三篇 商品查询实现 本篇博客将介绍如何在Servlet JDBC实战开发书店项目中实现商品查询功能 我们将从设计数据库表结构和实体类开始 一步一步详细讲解代码实现过程 包括前端页面的设计和后端S
  • 使用 MCGS 脚本实现开机页面倒数三秒跳转功能

    创建窗口及组件 新建两个窗口 窗口0 与窗口1 其中 窗口0为欢迎界面 窗口1为跳转后界面 在窗口0界面中 添加一个输入框 以方便观看数据的计时情况 实际工程中 是插入图片 以显示欢迎界面 在窗口1 中 添加文本 跳转成功 创建变量 在实时
  • 【 VScode上配置c++编译环境出现报错】

    VScode上配置c 编译环境出现报错 在写好launch json代码 tasks json代码 c cpp properties json代码之后 点击运行第一个 HelloWorld cpp 代码 却出现 No such file o
  • Maven高级

    回顾 1 文件上传 fileupload MultipartFile 将上传的文件保存到硬盘上 获取文件名 2 restful url书写的一种风格 http localhost user 1 springmvc支持restful Post
  • 最小二乘法的拟合原理

    一 最小二乘法的拟合原理 根据 数学指南 书中的解释 图2 数学指南 中对最小二乘法的解释 上面这段话 枯燥且无趣 大家不用厌恶 数学向来这个样子 现在 我们来慢慢认识上面这段话的意思 这句话的意思是说 拟合有两个前提 1 要有N个不同的点
  • 机械手臂c语言如何编程,一种串联机械手臂的示教编程方法

    一种串联机械手臂的示教编程方法 技术领域 0001 本发明涉及一种串联机械手臂的示教编程方法 具体的说是通过体感设备和数据手套检测人的手臂的姿态变化 并且通过计算转换为机器人手臂关节角度的变化 并保存关节角度 完成示教编程 属于机器人及控制
  • idea的使用技巧

    idea的使用技巧 一 断点调试 1 源断点 要输出每一次的参数信息 System out print不应该使用它 它是一个同步方法 是线程安全 过多时会挤占线程 占用资源 内部实现 public void println int x sy
  • java word转pdf

    这里找了三种比较简单的工具 poi jacob和aspose poi 注意 版本不太高 版本太高有报错 依赖
  • axios 使用总结

    功能简介 axios是第三方封装库 作用是在框架中使用数据请求 安装 npm install axios S 在Vue 项目文件中的main js 文件 定义axios请求类的全局引用 核心代码如下 特点 1 它在浏览器中创建的是浏览器对象
  • IDEA查看某个类的某个方法或该类在哪里被调用或引用

    1 方法的话鼠标定位到该方法名 右键Find Usages 或直接快捷键 Alt F7 这样的话就会显示 2 类的话 也是定位到文件夹下的Java类文件 或者定位到 public class 类名这里 右键Find Usages
  • keil勾选Use MicroLIB 的作用

    MicroLib是一个针对用C编写的基于ARM的嵌入式应用程序的高度优化的库 与包含在ARM编译器工具链中的标准C库相比 MicroLib提供了许多嵌入式系统所需的代码大小的显著优势 下图对使用标准库和使用微库代码大小进行了对比 Micro
  • 联想原装系统OEM系统联想出厂系统联想原装系统 Lenovo ThinkPad ThinkBook拯救者出厂预装系统原厂系统

    系统镜像是在联想服务器下载 百分百的出厂预装正版系统 驱动完善 自带预装Office 自带一键恢复 联网即可激活系统 根据个人电脑配对的型号配置下载恢复 安装完恢复隐藏分区 带一键还原功能 和出厂时的系统状态一致 文件地址https pan
  • python好用的第三方库_如何学习使用第三方库

    如何学习使用第三方模块 得益于python强大的开源社区 我们在使用python开发项目时 可以几乎可以做到全程拿来主义 需要什么 就百度好了 总会有人已经实现了你需要的功能模块 你所需要做的仅仅是使用pip命令安装他们 虽然你不必重复造轮
  • 改变金融贷款市场营销方式 ---- 运营商大数据精准获客

    与传统的企业网络营销相比 最常见的是网络推广和硬广告推广 一些企业无法找到可靠准确的数据来源 也无法找到一些未知的总数据 这些数据大多存在持续时间长 准确性差的缺点 企业在将这些数据信息应用于商品在线营销时往往会遇到不足 在当前的数据和信息
  • 搜索引擎的小技巧:site,+,- 等指令的使用

    1 把搜索范围限定在网页标题中 intitle 网页标题通常是对网页内容提纲挈领式的归纳 把查询内容范围限定在网页标题中 有时能获得良好的效果 使用的方式 是把查询内容中 特别关键的部分 用 intitle 领起来 例如 找林青霞的写真 就
  • java springboot 项目打包成 exe应用

    前期准备 将项目打成jar包 将jdk目录中的jre和jar包放到同一个目录下 如果没有jre则需要去官网下载一份 地址 https www oracle com java technologies javase javase8u211 l
  • netty的介绍和架构设计

    转自尚硅谷 黑马和各位大神的文章 netty是什么 Netty 是一个异步的 基于事件驱动的网络应用框架 用于快速开发可维护 高性能的网络服务器和客户端 Netty 高性能架构设计 线程模型基本介绍 不同的线程模式 对程序的性能有很大影响
  • 以太坊nonce详解

    文章目录 1 nonce 是什么 2 如何使用 nonce 3 加速和取消以太坊的交易 4 异常处理 5 nonce 使用的几条规则 6 参考资料 1 nonce 是什么 A scalar value equal to the number
  • 第7章作业

    在安装的窗口输入 pip install scrapy user i http pypi douban com simple trusted host pypi douban com cd 你的文件夹路径 py m scrapy start
  • Java注解实现增删改查CRUD

    以前 我们都把对数据库的增删改查语句写在xml文件中 详见 程序员成长笔记 一 第三部分 第四章 第四节 由于Java注解的简洁高效 在Java注解的思想 干掉xml 下 现在越来越多的人使用java注解来进行增删改查操作 而且MyBati