坑1:【此处使用sqlite3,因为低版本不支持JDK1.8】
-
依赖引入
此处仅贴出sqlite3的依赖,其他根据自己项目的结构去引入对应的依赖即可<!-- sqlite3驱动包 -->
<dependency>
<groupId>org.xerial</groupId>
<artifactId>sqlite-jdbc</artifactId>
<version>3.27.2.1</version>
</dependency> -
配置文件
# 数据库相关配置 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' # 配置过滤器,https://github.com/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目录下以相对路径的写法来访问,也可以放到某处以绝对路径的方式来访问,下面分别给出例子:
- 相对路径:jdbc:sqlite::resource:data.db
- 绝对路径:jdbc:sqlite:/Users/fanyuanhang/Downloads/data.db
为什么要前缀?我们看下源码:
我们找到依赖的jar包,我们可以在里面发现它支持的操作系统类型等数据,我们需要关注的是JDBC这个类:
首先这个类在被创建时默认调用静态方法来创建注册驱动:
其次,创建一个连接:
我们看到,创建连接的前置校验完成后会创建一个JDBC4的一个连接,那么我们很好理解url,prop是数据库路径和加载的配置文件,那么extractAddress(url)这个方法做了什么?
我们看到,这里主要是从给的路径来截取数据库的名称,那么这个前缀是什么?
懂了为什么我说一定要加前缀吗?网上很多乱七八糟的文章要么加,要么不加,但是声明加的人又不知道为什么一定要加,所以我在这里对照源码说明下,^_^。
-
测试应用
建立对象:
建立mapper
单元测试
运行下
对比数据库
结束,^_^
总结:
- Sqlite区别于传统Mysql数据库,库以xx.db文件形式存在,所以无法通过IP去获取,只能通过相对or绝对路径读取
- Sqlite的SQL写法与Mysql基本无差异,复杂语法存在一些差异,详情参考菜鸟教程 https://www.runoob.com/sqlite/sqlite-tutorial.html
- Sqlite配置路径的时候一定要加前缀,否则解析数据库时会报错
- Sqlite根据JDK版本不同要选择不同的驱动版本
- Sqlite可以整个mybatisPlus一起使用,相比对JAP、JDBC更加便捷
- 注意整合时版本引发的依赖冲突问题
- 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去找,结果找到了两个,就报错了。
- 如何解决?
- 最简单的,指定type,或者指定不同的name;
- 更换@Resource注解为@Autowired注解
- 说到这里了,提一下@Autowired吧:
@Autowired是根据类型进行自动装配的。如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。我们可以使用@Qualifier配合@Autowired来解决这些问题。
可以看到,@Autowired注解默认type策略去找,也就是根据你变量名前声明的类去找,所以不会出错。
后面有小伙伴使用到这个数据库有不懂的可以来问我哦,一起学习。^_^