SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

时间:2024-03-16 19:29:13

坑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配置的情况:

  • SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

      坑3:配置文件中配置数据库url路径的时候,请务必加前缀 jdbc:sqlite:  由于sqlite数据库是以xx.db的文件形式存在,所以无法通过IP去访问,类似访问图片一样,可以将其移动到项目resource目录下以相对路径的写法来访问,也可以放到某处以绝对路径的方式来访问,下面分别给出例子:

  1. 相对路径:jdbc:sqlite::resource:data.db 
  2. 绝对路径:jdbc:sqlite:/Users/fanyuanhang/Downloads/data.db

         为什么要前缀?我们看下源码:

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

我们找到依赖的jar包,我们可以在里面发现它支持的操作系统类型等数据,我们需要关注的是JDBC这个类:

首先这个类在被创建时默认调用静态方法来创建注册驱动:

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

其次,创建一个连接:

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

我们看到,创建连接的前置校验完成后会创建一个JDBC4的一个连接,那么我们很好理解url,prop是数据库路径和加载的配置文件,那么extractAddress(url)这个方法做了什么?

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

我们看到,这里主要是从给的路径来截取数据库的名称,那么这个前缀是什么?

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

懂了为什么我说一定要加前缀吗?网上很多乱七八糟的文章要么加,要么不加,但是声明加的人又不知道为什么一定要加,所以我在这里对照源码说明下,^_^。

 

  • 测试应用

建立对象:

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

建立mapper

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

单元测试

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

运行下

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

对比数据库

SpringBoot整合Sqlite3+mybatisPlus+Druid 以及整合过程中的坑

结束,^_^

 

总结:

  1. Sqlite区别于传统Mysql数据库,库以xx.db文件形式存在,所以无法通过IP去获取,只能通过相对or绝对路径读取
  2. Sqlite的SQL写法与Mysql基本无差异,复杂语法存在一些差异,详情参考菜鸟教程   https://www.runoob.com/sqlite/sqlite-tutorial.html
  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策略去找,也就是根据你变量名前声明的类去找,所以不会出错。

 

 

后面有小伙伴使用到这个数据库有不懂的可以来问我哦,一起学习。^_^