Java注解实现增删改查CRUD

以前,我们都把对数据库的增删改查语句写在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表

Java注解实现增删改查CRUD_第1张图片

增(简单增)示例:

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

Java注解实现增删改查CRUD_第2张图片

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

 

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

Java注解实现增删改查CRUD_第3张图片

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

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

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

 

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

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

 

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

Java注解实现增删改查CRUD_第4张图片

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

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

 

删@Delete

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

Java注解实现增删改查CRUD_第5张图片

删(简单删)示例:

Java注解实现增删改查CRUD_第6张图片

 

 

改@Update

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

Java注解实现增删改查CRUD_第7张图片

 

改(简单改)示例:

Java注解实现增删改查CRUD_第8张图片

 

查@Select

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

Java注解实现增删改查CRUD_第9张图片

 

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

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

Java注解实现增删改查CRUD_第10张图片

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

Java注解实现增删改查CRUD_第11张图片

 

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

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

Java注解实现增删改查CRUD_第12张图片

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

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

如:

就说明idCard是主键。

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

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

 

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

 

简单查(以 Map 接收数据)示例:

Java注解实现增删改查CRUD_第13张图片

注:如果以Map来接收数据的话,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只存储一行数据。

法二:

Java注解实现增删改查CRUD_第14张图片

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

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

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

 

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

示例一:

Java注解实现增删改查CRUD_第15张图片

示例二:

Java注解实现增删改查CRUD_第16张图片

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

 

 

动态语句:

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

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

注:xxx为InsertUpdateDeleteSelect

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

 

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

 

动态增@InsertProvider

单个参数:

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

Java注解实现增删改查CRUD_第17张图片

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

 

给出逻辑处理方法示例:

Java注解实现增删改查CRUD_第18张图片

 

多个参数:

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

Java注解实现增删改查CRUD_第19张图片

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

 

给出逻辑处理方法示例:

Java注解实现增删改查CRUD_第20张图片

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

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

 

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

获得主键方式一:

Java注解实现增删改查CRUD_第21张图片

  

获得主键方式二:

Java注解实现增删改查CRUD_第22张图片

 

 

批量增:

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

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

Java注解实现增删改查CRUD_第23张图片

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

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

Java注解实现增删改查CRUD_第24张图片

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

 

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

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

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

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

Java注解实现增删改查CRUD_第25张图片

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

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

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

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

 

特别说明:

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

Mapper层中的方法

Java注解实现增删改查CRUD_第26张图片

处理SQL的方法

Java注解实现增删改查CRUD_第27张图片

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

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

 

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

Mapper层中的方法为:

Java注解实现增删改查CRUD_第28张图片

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

 

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

Java注解实现增删改查CRUD_第29张图片

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

 

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

Java注解实现增删改查CRUD_第30张图片

 

动态删@DeleteProvider

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

Java注解实现增删改查CRUD_第31张图片

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

给出逻辑处理方法示例:

Java注解实现增删改查CRUD_第32张图片

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

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

 

 

动态改@DeleteProvider

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

Java注解实现增删改查CRUD_第33张图片

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

给出逻辑处理方法示例:

Java注解实现增删改查CRUD_第34张图片

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

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

 

动态查@SelectProvider(示例一)

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

Java注解实现增删改查CRUD_第35张图片

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

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

 

给出逻辑处理方法示例:

Java注解实现增删改查CRUD_第36张图片

 

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

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

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

 

 

 

持有对象、集合:

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

 

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

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

 

动态查@SelectProvider(示例二)

数据访问层中的方法示例

Java注解实现增删改查CRUD_第37张图片

Sql代理方法为

Java注解实现增删改查CRUD_第38张图片

单元测试中的测试方法为

Java注解实现增删改查CRUD_第39张图片

 

xml示例(持有对象):

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

People实体类:

Java注解实现增删改查CRUD_第40张图片

people表:

Java注解实现增删改查CRUD_第41张图片

Idcard实体类:

Java注解实现增删改查CRUD_第42张图片

 

idcard表:

Java注解实现增删改查CRUD_第43张图片

 

xml文件位置:

数据访问层中的方法:

Java注解实现增删改查CRUD_第44张图片

xml中的相关配置为:

Java注解实现增删改查CRUD_第45张图片

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

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

mapper层中方法是这样的:

Java注解实现增删改查CRUD_第46张图片

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

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

 

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

Java注解实现增删改查CRUD_第47张图片

extractProviderMethodArguments方法是这样的:

Java注解实现增删改查CRUD_第48张图片

 

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

Java注解实现增删改查CRUD_第49张图片

对应的代理方法为

Java注解实现增删改查CRUD_第50张图片

注:由源码可知:时通过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

你可能感兴趣的:(Java知识大杂烩,MySQL)