基于ORM框架的适配
驱动及连接池配置
我们知道对于不同的数据库我们需要配置不同的数据库驱动,在springboot项目中,我们可以在application.yml中进行配置。如对于Mysql8.0版本,需要进行如下操作:
Step1:在pom.xml中导入依赖:
Step2:在application.yml中进行配置
驱动四要素即:driver、username、password以及url,这里使用的数据库连接池为默认连接池。
而对于vastbase,则需要导入vastbase的驱动,如下:
Step1:Maven本地导入vastbase-2.0依赖
Step2:在pom.xml中导入
Step3:配置数据源和驱动
同样只需要配置驱动四要素:driver、username、password以及url
而其中的com.alibaba.druid.pool.DruidDataSource是市面上较为流行的性能也相对较高的数据库连接池druid,除此之外还有C3P0,DBCP等主流数据库连接池。不同连接池共同的地方在于需要配置驱动四要素,尽管命名可能有略微不同。我们只需要根据其官方文档来进行命名配置即可。
而如上所示的druid连接池中我们还可以配置多个属性如initialSize等,可以根据项目的需要进行相关配置。
MyBatis
类名调整
Mybatis需要用到类名时,需要写入类的全路径,这样无疑耗费时间,如下例当我们需要使用cn.com.atlasdata.test.mapper包下的TestBooleanMapper类时,在Mapper中的写法如下:
也就是当我们的resultType或parameterType为实体类时,我们需要写这个类的全路径,否则将会报错如下:
Mybatis提供了一种简便的方法解决这一问题,也就是”扫描包变小写”
9 我们只需要在application.yml中配置这一段,在Mapper.xml中便可以使用类名小写来替换类名的全路径,如下:但是,在不断的尝试过程中,我发现这一方法并没有针对性得要求一定是小写,而是不区分大小写,也就是说这这里我们使用Testboolean、TESTBoolean都是可以的。
字段名称转换
由于Windows环境下数据库不区分大小写,因此我们对表名或字段名进行命名时通常使用下划线如user_id。但是,我们在Java开发中,为了遵守开发规范,命名一般为驼峰命名,如userId。这样,Mybatis就可能报错没有user_id的get和set方法。
如下例:
数据库的user表
Java的User类
此时,我们搭建好Mybatis并运行,便会出现如下情况:
因此,我们需要将数据库的下划线命名和Java开发的驼峰命名进行转换。解决这一问题有多种方法,但最简便的一种便是Mybatis提供的下划线驼峰命名转换。
(1)Mybatis提供了十分简便的解决方法,我们只需要在yml的配置中加入这一段,也就是配置下划线转驼峰,而后Mybatis便会自动将SQL中查出来的带下划线的字段转换为驼峰命名格式,再去匹配类中的属性,问题便得已解决。
(2)也可以通过给字段起别名的方式来解决
(3)用resultMap映射
字段值处理
Null值处理
一般而言,对于数据库中的字段,其值可能为null,因此在Java类中的属性类型设置时,我们应当使用包装类即Integer代替int等,使其可与数据库字段取值范围对应。
其他数据类型处理
在vastbase中,采用的是postgresql的语法,因此同样也支持postgresql的相关基本类型,这些数据类型与Java数据类型的对应关系如下
(1)数值类型
数据库基本类型 | Java类型 |
tinyint | Integer |
smallint | Integer |
integer | Integer |
bigint | Long |
numeric | BigDecimal |
real | Float |
smallserial | Integer |
serial | Integer |
bigserial | Long |
oid | Long |
(2)货币类型
数据库基本类型 | Java类型 |
money | BigDecimal |
注意货币类型Money对应的是Java类型中的BigDecimal而不是Float或者Double,原因在于Float和Double都是近似值,当用于金额的加减乘除时,可能会出错,这在金额的计算中显然是不被允许的,使用BigDecimal便能很好解决这一点。
(3)字符类型
数据库基本类型 | Java类型 |
char | Charater或String(前端传参需要注意字符数只能为1) |
bpchar | Charater或String(前端传参需要注意字符数只能为1) |
varchar | String |
nvarchar2 | String |
text | String |
name | String |
(4)时间类型
数据库基本类型 | Java类型 |
timestamp | Timestamp |
timestampz | Timestamp |
date | Date |
time | Time |
timez | Time |
smalldatetime | Timestamp |
注:在Mybatis操作数据库的过程中,时间类型较为特殊,如下例:
数据库中的字段定义如下:
Java类中的属性定义如下:
需要在Java属性中加入如图所示的@JsonFormat的注解
(5)位类型
数据库基本类型 | Java类型 |
bit | Integer |
bytea | byte[] |
这里同样需要注意的是,百度上以及各资料都显示bit对应的Java类型应当是boolean,理由在于:boolean的true和false映射到数据库时会变化为0,1。但经过实际验证,发现此做法并不可取,无法适配。因此使用Integer,用户在前端传递参数时将参数设置为只能是0或1即可。
而bytea对应的便是byte[],也就是byte数组。
且这两个类型存在特殊之处,由于在postgresql语法中,对这两个类型的数据插入操作如下:
也就是强制类型转换。因此,在Mybatis增删改查时,同样需要进行一定处理,以插入数据操作为例:
(6)其它类型
数据库基本类型 | Java类型 |
json | Object |
point | Object |
这两个类型可以直接用Object类型进行处理。
在传入参数时,point类型注意传入的应为:(1.0,2.0)这样的”点”;
而json数据与bit以及bytea同理,需要进行特殊处理
结果集封装
Map封装
mybatis在将结果集封装成resultType=“map”的时候,key值为小写,客户应用中在处理map中的数据时,都默认为大写。
解决方案:
Step1:自定义Map包装器MapKeyUpperWrapper继承MapWrapper,重写findProperty()方法:
Step2:自定义Map包装器工厂类MapWrapperFactory,实现ObjectWrapperFactory接口,并实现接口方法:
Step3:由于Mybatis与SpringBoot不提供用反射机制来构建对象的converter,但是SpringBoot提供了允许自定义的converter来进行转换,所以这里需要构建一个自定义的converter:
Step4:最后一步,在配置文件中,对自定义的MapWrapperFactory进行配置:
动态SQL
在实际应用中,可能存在传进来的参数为一个或者多个的情况,这时候动态sql是一个很好的帮手,通过动态sql,Mybatis便可以根据对应的参数进行相关条件的数据查询等操作。如下简单例子
存储过程及函数
Vastbase语法方面
(1)带参数带返回的函数
test_int表:
函数:
返回类型为表时:
返回类型为字段时:
其中test_int为表名,当我们的函数带有返回类型时,需要使用”returns setof+类型”的形式表明返回类型,且返回语句的语法为return query…,如上图所示。
(2)带参数无返回的函数
无返回时,与Java语法类似的,我们需要returns void
(3)不带参数带返回的函数
return next 1;即返回一个int类型的数据1
(4)不带参数无返回的函数
带参数时,即在函数名后加上”参数名 参数类型”,带返回值时则需要注意returns setof +返回类型以及 return query返回语句。不带返回类型时需注意returns void
函数与MyBatis结合使用
首先在TestIntMapper接口中定义相关方法
而后使用即可
注:这里的<![CDATA[ ]]>代表执行函数或存储过程
MyBatisPlus
MybatisPlus的数据库连接问题
问题产生:在使用代码自动生成器时,报错找不到表格,但实际在数据库中该表格存在
解决方法:在数据库连接的配置中加上currentSchema的配置,如下图,否则在使用代码自动生成器的过程中会默认是找public下的表,自然就会报错。
设置数据库表中的创建时间字段和更新时间字段的自动插入
(1)数据库表的字段
(2)在字段上使用注解
(3)配置自动插入和更新
(4)配置完毕后在对表进行数据的插入或更新时,则会对这两个字段进行进行时间的插入或更新
乐观锁和逻辑删除字段的配置
逻辑删除字段
(1)设计思想
即在数据库表中新设置一个字段,这里为deleted。这一字段的设置思想为:当deleted=1时,该条记录对于用户不可见,但其在数据库中依然存在。本质上就是在查询的SQL语句中加上 and deleted=0;如下:
执行delete
查看数据库表,此时数据还在,但是deleted字段变为1
执行查询操作,可以看到SQL后面加上了and deleted=0,查询的结果为空
(2)逻辑删除字段的配置
首先在字段上添加注解
到application.yml中配置mybatis-plus的逻辑删除字段
乐观锁字段
乐观锁的设计思路为:新建一个字段version,取出记录时,获取当前的version,更新时带上这个vesion,执行
set version=newVersion where version=oldVersion
配置:
注意在乐观锁使用时,需要先查询出数据,而后更新时带上这个version
如下例:
先查询
后修改
查看数据库,可以观察到version值更新
分页配置(MybatisPlus分页插件的使用)
使用分页的原因
数据库表中的数据可能非常巨大,如果不进行分页处理,一次性查询全部数据可能导致许多问题如查询效率低等,MybatisPlus提供了分页插件
分页插件的本质
分页插件的本质为在SQL语句后加上limit ? offet ?
分页插件的配置和使用
按照官网配置即可
而后使用MybatisPlus自身封装的方法即可
测试,可以看到本质便是加上限制条件
特殊类型的字段后端传递参数
几何类型point
数据库中字段类型为point,Java中使用Object作为其类型,在后端传参时,使用PGpoint进行传参。
数据库中的point
Java中使用Object
后端传递,使用PGpoint
Json类型、bit类型以及bytea类型
这三个类型都无法使用MybatisPlus封装的方法进行插入操作,因此需要我们自定义插入的方法,编写Mysql语句,如下:
数据库表test_char里面的字段json、bytea、bit
在Mapper中定义函数
Mapper.xml实现
即类型转换,也可通过调用函数的方式实现上述操作
其它类型与mybatis的操作一致
MybatisPlus封装的方法
Mapper crud接口
在Vasebase数据库中,各种基本数据类型对于Mapper的各种crud接口都是适配的。其中,一些特殊字段的处理如2.3.5所示。
Service crud接口
在Vasebase数据库中,各种基本数据类型对于Service的各种crud接口都是适配的。其中,一些特殊字段的处理如2.3.5所示。
函数和存储过程
MybatisPlus封装的方法并无法解决函数和存储过程的问题,因此对于函数和存储过程,操作与Mybatis一致
Hibernate
Hibernate配置数据库的连接
(1)配置数据库连接,这部分与Mybatis和MybatisPlus一致,同样也需要Vastbase的依赖
(2)配置jpa
实体类需要注意的事项
注意点1:实体类上需要有注解@Entity
注意点2:id字段需要有注解@Id
持久层Repository需要注意的事项
注意点1:类上需要有对应实体类注解如@Table(name=“testInt”)
注意点2:持久层注解标志@Repository(“TestIntRepository”)
注意点3:持久类继承JpaRepository
注意点4:Hibernate执行默认是HQL语句,而使用nativeQuery=true则将其转变为SQL语句语法
注意点5:更新删除等操作时需要加上注解@Transactional,执行事务操作
注意点6:@Modifying+@Query 定义个性化更新操作
各种基本类型的操作
时间类型
整型
字符类型
Hibernate操作存储过程
(1)首先我们需要在数据库定义一个函数
注意点1:将该函数定义到对应的模式下,否则后续会报错找不到函数
注意点2:在函数的参数中,应该加上in,如 in id1 int,表明这是一个徐娅传入的参数
(2)而后在程序中调用
步骤1:定义EntityManager
步骤2:由EntityManager创建查询
步骤3:查询的参数传递应先”注册”,即如图所示,第一个参数为Integer类型且是一个传入的参数
步骤4:设置参数,而后执行即可
注:若需要查看参数返回值等,需要在query.execute()之前,如下: