SpringBoot中整合使用jFinal的ActiveRecord并支持多数据源和事务

在一些特殊场景,我们用到了Spring Boot,数据ORM层并没有使用流行的hibernate或mybatis,而采用了国内开源的jFinal中的ActiveRecord。不要问为什么不直接使用jFinal,就是这么个特殊需求。

在我们的需求中,需要使用多个数据源,并支持事务,下面是配置的详细过程。

依赖包的版本:

springboot 2.3.0.RELEASE

jFinal ActiveRecord 4.8

mysql connector java 5.1.20

druid 1.1.22

一、spring boot 整合jFinal的ActiveRecord

1.1 pom.xml中的包依赖:

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <springboot.version>2.3.0.RELEASE</springboot.version>
        <jfinal.activerecord.version>4.8</jfinal.activerecord.version>
        <mysql.version>5.1.20</mysql.version>
        <druid.version>1.1.22</druid.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.jfinal</groupId>
            <artifactId>activerecord</artifactId>
            <version>${jfinal.activerecord.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-dependencies</artifactId>
            <version>${springboot.version}</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${springboot.version}</version>
            <exclusions>
                <!-- 移除 tomcat 以使用 undertow -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-tomcat</artifactId>
                </exclusion>
                <!-- 去掉logback配置 -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- 使用实务 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
            <version>${springboot.version}</version>
            <exclusions>
                <!-- 去掉logback配置 -->
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-starter-logging</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-undertow</artifactId>
            <version>${springboot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-log4j2</artifactId>
            <version>${springboot.version}</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${springboot.version}</version>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>${mysql.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>${druid.version}</version>
        </dependency>
    </dependencies>

1.2 新建 JfinalActiveRecordConfig java文件:

如下:

@Configuration
public class JfinalActiveRecordConfig {
    /**
     * 主数据源名称
     */
    private static final String MAIN_DATA_SOURCE_CONFIG = "main";


    @Bean
    @ConfigurationProperties("spring.datasource.main")
    public DruidDataSource masterDataSource(){
        return new DruidDataSource();
    }

    /**
     * 主数据源
     * @return
     */
    @Bean
    public ActiveRecordPlugin initMainActiveRecord() {
        ActiveRecordPlugin arp = new ActiveRecordPlugin(MAIN_DATA_SOURCE_CONFIG, masterDataSource());

        arp.addMapping("emp", Emp.class);

        arp.start();

        return arp;
    }
}

1.3 在application.yml配置文件里增加

spring:
  # 数据源配置
  datasource:
    main: #主数据源
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/csdn1
      username: root
      password: 123456

至此已经完成了spingboot和activerecord的整合,接下来加入多数据源的支持。

二、多数据源支持

2.1 在application.yml增加第二个数据源

spring:
  # 数据源配置
  datasource:
    main: #主数据源
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/csdn1
      username: root
      password: 123456
    biz: #业务数据源
      driverClassName: com.mysql.jdbc.Driver
      url: jdbc:mysql://localhost:3306/csdn2
      username: root
      password: 123456

2.2 修改JfinalActiveRecordConfig,加入第二个数据源的支持

/**
     * 主数据源名称
     */
    private static final String MAIN_DATA_SOURCE_CONFIG = "main";

    /**
     * 业务数据源名称
     */
    private static final String BIZ_DATA_SOURCE_CONFIG = "biz";

    @Bean
    @ConfigurationProperties("spring.datasource.main")
    public DruidDataSource masterDataSource(){
        return new DruidDataSource();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.biz")
    public DruidDataSource bizDataSource(){
        return new DruidDataSource();
    }

    /**
     * 主数据源
     * @return
     */
    @Bean
    public ActiveRecordPlugin initMainActiveRecord() {
        ActiveRecordPlugin arp = new ActiveRecordPlugin(MAIN_DATA_SOURCE_CONFIG, masterDataSource());

        arp.addMapping("emp", Emp.class);

        arp.start();

        return arp;
    }

    /**
     * 业务数据源
     * @return
     */
    @Bean
    public ActiveRecordPlugin initBizActiveRecord() {
        ActiveRecordPlugin arp = new ActiveRecordPlugin(BIZ_DATA_SOURCE_CONFIG, bizDataSource());
// 第二个数据源如何和第一个数据有相同的表,则不需要重复映射,只需要在调用时指定数据源即可
//        arp2.addMapping("emp", Emp.class);

        arp.start();

        return arp;
    }

2.3 调用不同数据源的方式:

// 默认使用主数据源
Emp emp = Emp.dao.findById(1);
System.out.println(emp.getStr("name"));

// 调用其他数据源
Emp emp3 = new Emp().use("biz").findById(1);
System.out.println(emp3.getStr("name"));

// 也可以这样
Record emp2 = Db.use("biz").findFirst("select * from emp where id = 1");
System.out.println(emp2.getStr("name"));

三、数据库的事务支持

(注意:只支持同一数据源的事务)

修改JfinalActiveRecordConfig

@Configuration
public class JfinalActiveRecordConfig {
    /**
     * 主数据源名称
     */
    private static final String MAIN_DATA_SOURCE_CONFIG = "main";

    /**
     * 业务数据源名称
     */
    private static final String BIZ_DATA_SOURCE_CONFIG = "biz";

    @Bean
    @ConfigurationProperties("spring.datasource.main")
    public DruidDataSource masterDataSource(){
        return new DruidDataSource();
    }

    @Bean
    @ConfigurationProperties("spring.datasource.biz")
    public DruidDataSource bizDataSource(){
        return new DruidDataSource();
    }

    /**
     * 主数据源
     * @return
     */
    @Bean
    public ActiveRecordPlugin initMainActiveRecord() {
        ActiveRecordPlugin arp = new ActiveRecordPlugin(MAIN_DATA_SOURCE_CONFIG, masterTransactionAwareDataSourceProxy());

        arp.addMapping("emp", Emp.class);
        arp.addMapping("emp_balance", EmpBalance.class);

        arp.start();

        return arp;
    }

    /**
     * 业务数据源
     * @return
     */
    @Bean
    public ActiveRecordPlugin initBizActiveRecord() {
        ActiveRecordPlugin arp = new ActiveRecordPlugin(BIZ_DATA_SOURCE_CONFIG, bizTransactionAwareDataSourceProxy());

//        arp2.addMapping("emp", Emp.class);

        arp.start();

        return arp;
    }

    /**
     * 设置数据源代理
     */
    @Bean
    public TransactionAwareDataSourceProxy masterTransactionAwareDataSourceProxy() {
        TransactionAwareDataSourceProxy transactionAwareDataSourceProxy = new TransactionAwareDataSourceProxy();
        transactionAwareDataSourceProxy.setTargetDataSource(masterDataSource());
        return transactionAwareDataSourceProxy;
    }

    @Bean
    public TransactionAwareDataSourceProxy bizTransactionAwareDataSourceProxy() {
        TransactionAwareDataSourceProxy transactionAwareDataSourceProxy = new TransactionAwareDataSourceProxy();
        transactionAwareDataSourceProxy.setTargetDataSource(bizDataSource());
        return transactionAwareDataSourceProxy;
    }

    /**
     * 设置事务管理
     */
    @Bean(name="mainDataSourceTransactionManager")
    public DataSourceTransactionManager masterDataSourceTransactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(masterTransactionAwareDataSourceProxy());
        return dataSourceTransactionManager;
    }

    @Bean(name="bizDataSourceTransactionManager")
    public DataSourceTransactionManager bizDataSourceTransactionManager() {
        DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
        dataSourceTransactionManager.setDataSource(bizTransactionAwareDataSourceProxy());
        return dataSourceTransactionManager;
    }
}

之前的 ActiveRecordPlugin arp = new ActiveRecordPlugin(MAIN_DATA_SOURCE_CONFIG, masterDataSource());

换成了 

ActiveRecordPlugin arp = new ActiveRecordPlugin(MAIN_DATA_SOURCE_CONFIG, masterTransactionAwareDataSourceProxy());

接着在service中加入注解 @Transactional(transactionManager="mainDataSourceTransactionManager", rollbackFor = Exception.class)

如下:

@Service
public class EmpBalanceService {

    @Transactional(transactionManager="mainDataSourceTransactionManager", rollbackFor = Exception.class)
    public void addBalance() {
        // 这个应该不能保存进表中才对
        new EmpBalance().set("emp_id", 1)
                .set("balance", 10).save();

        Emp emp = Emp.dao.findById(1);

        // 这里故意写错,以测试实务
        emp.set("name", "超出长度的字符串用于测试错误").update();
    }
}

 

四、源码下载

源码的test里面有测试用例,sql文件夹下有建表语句,下载地址:https://github.com/Liamliu/spring-jfinal-activerecord

 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
首先需要在pom.xml文件添加jfinaljfinal-ext依赖: ```xml <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal</artifactId> <version>4.9.12</version> </dependency> <dependency> <groupId>com.jfinal</groupId> <artifactId>jfinal-ext</artifactId> <version>4.9.12</version> </dependency> ``` 然后,在Spring Boot配置JFinal: ```java @Configuration public class JFinalConfig { @Bean public JFinalPlugin jFinalPlugin() { DruidPlugin druidPlugin = new DruidPlugin("jdbc:mysql://localhost:3306/db", "username", "password"); ActiveRecordPlugin activeRecordPlugin = new ActiveRecordPlugin(druidPlugin); activeRecordPlugin.addMapping("table", "id", Model.class); return new JFinalPlugin(druidPlugin, activeRecordPlugin); } } ``` 其,“table”是数据库表名。 接下来,我们可以定义一个Controller来进行增删改查操作: ```java @RestController @RequestMapping("/demo") public class DemoController { @Autowired private JFinalPlugin jFinalPlugin; @GetMapping("/{id}") public Object getById(@PathVariable("id") Integer id) { jFinalPlugin.start(); Model model = Model.findById("table", id); jFinalPlugin.stop(); return model; } @PostMapping public Object add(@RequestBody Model model) { jFinalPlugin.start(); model.save(); jFinalPlugin.stop(); return "success"; } @PutMapping public Object update(@RequestBody Model model) { jFinalPlugin.start(); model.update(); jFinalPlugin.stop(); return "success"; } @DeleteMapping("/{id}") public Object delete(@PathVariable("id") Integer id) { jFinalPlugin.start(); Model.deleteById("table", id); jFinalPlugin.stop(); return "success"; } } ``` 其,getById方法根据id查询数据,add方法添加数据,update方法更新数据,delete方法删除数据。 最后,启动Spring Boot应用程序,访问相应的API即可进行增删改查操作。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值