SpringBoot整合Sqlite3+mybatisPlus+Druid以及整合过程中的
坑
坑1:【此处使⽤sqlite3,因为低版本不⽀持JDK1.8】
依赖引⼊
此处仅贴出sqlite3的依赖,其他根据⾃⼰项⽬的结构去引⼊对应的依赖即可
<!-- sqlite3驱动包 -->
<dependency>
<groupId&ial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.27.2.1</version>
</dependency>
配置⽂件
# 数据库相关配置
druid连接池配置详解datasource:
url: jdbc:sqlite:/Users/fanyuanhang/Downloads/data.db
username:
password:
driver-class-name: org.sqlite.JDBC
type: com.alibaba.druid.pool.DruidDataSource
# druid相关配置
druid:
# 连接池初始化⼤⼩
initial-size: 8
# 最⼤活跃连接数
max-active: 20
# 最⼩空闲连接数
min-idle: 1
# 获取连接等待超时的时间
max-wait: 60000
# 间隔多久才进⾏⼀次检测,检测需要关闭的空闲连接,ms
time-between-eviction-runs-millis: 60000
validation-query: select 'x'
# 配置过滤器,github/alibaba/druid/wiki/%E5%86%85%E7%BD%AEFilter%E7%9A%84%E5%88%AB%E5%90%8D
filters: stat,slf4j,config
坑2:此处在配置⽂件中需要注意,配置filters时,请去掉防⽕墙的配置(wall) 即:filters:
stat,slf4j,wall,config → stat,slf4j,config 若不去除,启动项⽬时会报不⽀持的数据库类型错误,如下图:
带有wall配置的情况:
坑3:配置⽂件中配置数据库url路径的时候,请务必加前缀 jdbc:sqlite: 由于sqlite数据库是以xx.db的⽂件形式存在,所以⽆法通过IP 去访问,类似访问图⽚⼀样,可以将其移动到项⽬resource⽬录下以相对路径的写法来访问,也可以放到某处以绝对路径的⽅式来访问,下⾯分别给出例⼦:
1. 相对路径:jdbc:sqlite::resource:data.db
2. 绝对路径:jdbc:sqlite:/Users/fanyuanhang/Downloads/data.db
为什么要前缀?我们看下源码:
我们到依赖的jar包,我们可以在⾥⾯发现它⽀持的操作系统类型等数据,我们需要关注的是JDBC这个类:
⾸先这个类在被创建时默认调⽤静态⽅法来创建注册驱动:
其次,创建⼀个连接:
我们看到,创建连接的前置校验完成后会创建⼀个JDBC4的⼀个连接,那么我们很好理解url,prop是数据库路径和加载的配置⽂件,那么extractAddress(url)这个⽅法做了什么?
我们看到,这⾥主要是从给的路径来截取数据库的名称,那么这个前缀是什么?
懂了为什么我说⼀定要加前缀吗?⽹上很多乱七⼋糟的⽂章要么加,要么不加,但是声明加的⼈⼜不知道为什么⼀定要加,所以我在这⾥对照源码说明下,^_^。
测试应⽤
建⽴对象:
建⽴mapper
单元测试
运⾏下
对⽐数据库
结束,^_^
总结:
1. Sqlite区别于传统Mysql数据库,库以xx.db⽂件形式存在,所以⽆法通过IP去获取,只能通过相对or绝对路径读取
2. Sqlite的SQL写法与Mysql基本⽆差异,复杂语法存在⼀些差异,详情参考菜鸟教程
3. Sqlite配置路径的时候⼀定要加前缀,否则解析数据库时会报错
4. Sqlite根据JDK版本不同要选择不同的驱动版本
5. Sqlite可以整个mybatisPlus⼀起使⽤,相⽐对JAP、JDBC更加便捷
6. 注意整合时版本引发的依赖冲突问题
7. Sqlite⽀持⾃动装配,但是没有默认的配置⽂件,所以需要我们进⾏配置使⽤
申引问题(坑4):
在实际研究过程中还发现了另外⼀个问题值得注意,我们看下例⼦:
A实现类中我们通过@Resource注解注⼊了B服务类,并且变量名为 b;
B实现类中我们通过@Resource注解注⼊了C服务类,并且变量名为 b;
现在我们启动项⽬你会发现出错了。
Caused by: org.springframework.beans.factory.BeanNotOfRequiredTypeException: Bean named 'equipmentLogMapper' is expected to be of type 'com.runlion.ims.smp.service.bill.IPurchaseBillService' but was actually of type
'com.sun.proxy.$Proxy186'
不是所期望的类型,我们希望的equipmentLogMapper 变量应该对应的是 com.runlion.ims.smp.service.bill.IPurchaseBillService 这个实现类才对,可是实际上却是⼀个代理对象。并且我们确实是没有注⼊错对象啊,这个是怎么回事呢?
仔细思考下:
我们不同的服务类,在不同的调⽤类中,变量名称⼀样,难道!没错,是Spring代理区分不了了,你到底要哪个实现类呢?
我们简单的看下@Resource的作⽤是什么:由JSR-250规范定义的注解
@Resource有两个属性是⽐较重要的,分是name和type,Spring将@Resource注解的name属性解析为bean的名字,⽽type属性则解析为bean的类型。所以如果使⽤name属性,则使⽤byName的⾃动注⼊策略,⽽使⽤type属性时则使⽤byType⾃动注⼊策略。如果既不指定name也不指定type属性,这时将通过反射机制使⽤byName⾃动注⼊策略。
@Resource装配顺序
1. 如果同时指定了name和type,则从Spring上下⽂中到唯⼀匹配的bean进⾏装配,不到则抛出异常
2. 如果指定了name,则从上下⽂中查名称(id)匹配的bean进⾏装配,不到则抛出异常
3. 如果指定了type,则从上下⽂中到类型匹配的唯⼀bean进⾏装配,不到或者到多个,都会抛出异常
4. 如果既没有指定name,⼜没有指定type,则⾃动按照byName⽅式进⾏装配;如果没有匹配,则回退为⼀个原始类型进⾏匹配,如果匹配则⾃动装配;
看了后是否明⽩为什么出错了?确实如我所想,没有指定name和type,根据变量type去,结果到了两个,就报错了。
如何解决?
1. 最简单的,指定type,或者指定不同的name;
2. 更换@Resource注解为@Autowired注解
说到这⾥了,提⼀下@Autowired吧:
@Autowired是根据类型进⾏⾃动装配的。如果当Spring上下⽂中存在不⽌⼀个UserDao类型的bean时,就会抛出
BeanCreationException异常;如果Spring上下⽂中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使⽤@Qualifier配合@Autowired来解决这些问题。
可以看到,@Autowired注解默认type策略去,也就是根据你变量名前声明的类去,所以不会出错。
后⾯有⼩伙伴使⽤到这个数据库有不懂的可以来问我哦,⼀起学习。^_^
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论