springboot集成ActiveRecord、HikariCP、oracle

项目结构

image.png

pom文件

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.2.6.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.example</groupId>
	<artifactId>demo</artifactId>
	<version>1.0</version>
	<name>demo</name>
	<description>Demo project for Spring Boot</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>
	<repositories>
		<repository>
			<id>ali-maven</id>
			<url>http://maven.aliyun.com/nexus/content/groups/public</url>
			<releases>
				<enabled>true</enabled>
			</releases>
			<snapshots>
				<enabled>true</enabled>
				<updatePolicy>always</updatePolicy>
				<checksumPolicy>fail</checksumPolicy>
			</snapshots>
		</repository>
	</repositories>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>org.junit.vintage</groupId>
					<artifactId>junit-vintage-engine</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<!-- 热部署 -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<optional>true</optional>
			<scope>true</scope>
		</dependency>
		<!--oracle驱动 -->
        <dependency>
            <groupId>com.oracle</groupId>
            <artifactId>ojdbc6</artifactId>
            <version>11.2.0.3</version>
        </dependency>
        <!-- 数据库连接池-->
        <dependency>
            <groupId>com.zaxxer</groupId>
            <artifactId>HikariCP</artifactId>
        </dependency>
        <!--jdbc start -->
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-jdbc</artifactId>
		</dependency>
		<!--jdbc end -->
		<!--引入JFinal的activerecord -->
		<dependency>
			<groupId>com.jfinal</groupId>
			<artifactId>activerecord</artifactId>
			<version>4.8</version>
		</dependency>
		<!-- activerecord end -->
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>

数据库配置文件db.properties

driverClassName=oracle.jdbc.driver.OracleDriver
jdbcUrl=jdbc:oracle:thin:@localhost:1521:ORCL
#生产环境最好存秘钥,连接数据库时再解密处理
username=username
#连接密码
password=password

DataSourceConfig配置

package com.lwb.config;
import javax.sql.DataSource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.jdbc.datasource.TransactionAwareDataSourceProxy;

import com.jfinal.plugin.activerecord.ActiveRecordPlugin;
import com.jfinal.plugin.activerecord.CaseInsensitiveContainerFactory;
import com.jfinal.plugin.activerecord.dialect.OracleDialect;
import com.zaxxer.hikari.HikariConfig;
import com.zaxxer.hikari.HikariDataSource;

/**
 * @ClassName: DataSourceConfig.java
 * @Description: 数据库链接配置
 * @version: v1.0.0
 * @author: 小李子
 * @date: 2019年10月28日 下午3:24:52
 */
@Configuration
public class DataSourceConfig {
	private final Logger logger=LoggerFactory.getLogger(DataSourceConfig.class);
	/**
	 * 设置数据源代理
	 */	@Bean
	public TransactionAwareDataSourceProxy transactionAwareDataSourceProxy() {
		logger.info("设置数据源代理");
		TransactionAwareDataSourceProxy transactionAwareDataSourceProxy = new TransactionAwareDataSourceProxy();
		transactionAwareDataSourceProxy.setTargetDataSource(dataSource());
		return transactionAwareDataSourceProxy;
	}
    
	/**
	 * 设置事务管理
	 */	@Bean
	public DataSourceTransactionManager dataSourceTransactionManager() {
		logger.info("设置事务管理器");
		DataSourceTransactionManager dataSourceTransactionManager = new DataSourceTransactionManager();
		dataSourceTransactionManager.setDataSource(transactionAwareDataSourceProxy());
		return dataSourceTransactionManager;
	}
    
    @Bean    DataSource dataSource(){
        HikariConfig config = new HikariConfig("/db.properties");
        HikariDataSource dataSource = new HikariDataSource(config);
        return dataSource;
 
    }
	

	/**
	 * 设置ActiveRecord
	 */	@Bean
	public ActiveRecordPlugin activeRecordPlugin() {
		logger.info("设置ActiveRecord");
		ActiveRecordPlugin arp = new ActiveRecordPlugin(transactionAwareDataSourceProxy());
		arp.setDialect(new OracleDialect());
		arp.setShowSql(true);
		arp.setContainerFactory(new CaseInsensitiveContainerFactory(true));
		arp.start();
		return arp;

	}
}

启动文件DemoApplication

package com.lwb;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.transaction.annotation.EnableTransactionManagement;

@SpringBootApplication
@EnableTransactionManagement// 启注解事务管理,等同于xml配置方式的 <tx:annotation-driven />
public class DemoApplication {

	public static void main(String[] args) {
		SpringApplication.run(DemoApplication.class, args);
	}

}

事务使用还是直接@Transactional,已经配置成功

本项目并没有使用model,如果要使用model请自行创建_MappingKit等在activeRecordPlugin中映射

有一个小需求需要使用oracle数据库并且指定使用HikariCP连接池,配置的时候出了点小问题,现在配置成功,来这里分享一下

稍后会把redis缓存集成进来,还是这个帖子,我会追加到下面


新增两个依赖

                <dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-data-redis</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-cache</artifactId>
		</dependency>

配置文件application.properties

#指定缓存使用redis
spring.cache.type=redis
#使用redis的哪个库
spring.redis.database=0
#redis地址
spring.redis.host=127.0.0.1
#redis端口
spring.redis.port=6379
#redis密码  没有不写
spring.redis.password=
#超时时间
spring.redis.timeout=1000

redisConfig配置文件

package com.lwb.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
@Configuration
public class RedisConfig {
	@Bean
	@SuppressWarnings("all")
	public RedisTemplate<String, Object> redisTemplate(RedisConnectionFactory factory) {
		RedisTemplate<String, Object> template = new RedisTemplate<String, Object>();
		template.setConnectionFactory(factory);
		Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);
		ObjectMapper om = new ObjectMapper();
		om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
		om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
		jackson2JsonRedisSerializer.setObjectMapper(om);
		StringRedisSerializer stringRedisSerializer = new StringRedisSerializer();
		// key采用String的序列化方式
		template.setKeySerializer(stringRedisSerializer);
		// hash的key也采用String的序列化方式
		template.setHashKeySerializer(stringRedisSerializer);
		// value序列化方式采用jackson
		template.setValueSerializer(jackson2JsonRedisSerializer);
		// hash的value序列化方式采用jackson
		template.setHashValueSerializer(jackson2JsonRedisSerializer);
		template.afterPropertiesSet();
		return template;
	}
}

cacheConfig配置

package com.lwb.config;

import java.time.Duration;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.CacheManager;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.cache.RedisCacheConfiguration;
import org.springframework.data.redis.cache.RedisCacheManager;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializationContext;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.annotation.JsonAutoDetect;

@Configuration
public class CaCheConfig {
	@SuppressWarnings("all")
	@Bean
	public CacheManager cacheManager(@Autowired RedisConnectionFactory factory)
	{
	    RedisSerializer<String> redisSerializer = new StringRedisSerializer();
	    Jackson2JsonRedisSerializer jackson2JsonRedisSerializer = new Jackson2JsonRedisSerializer(Object.class);

	    //解决查询缓存转换异常的问题
	    ObjectMapper om = new ObjectMapper();
	    om.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.ANY);
	    om.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL);
	    jackson2JsonRedisSerializer.setObjectMapper(om);

	    //配置序列化(解决乱码的问题)
	    RedisCacheConfiguration config = RedisCacheConfiguration.defaultCacheConfig()
	            .entryTtl(Duration.ofDays(7))//默认的缓存天数
	            .serializeKeysWith(RedisSerializationContext.SerializationPair.fromSerializer(redisSerializer))
	            .serializeValuesWith(RedisSerializationContext.SerializationPair.fromSerializer(jackson2JsonRedisSerializer))
	            .disableCachingNullValues();

	    RedisCacheManager cacheManager = RedisCacheManager.builder(factory)
	            .cacheDefaults(config)
	            .build();
	    
	    return cacheManager;
	}
	
	//自定义缓存key生成策略
    @Bean(name = "keyGenerator")
    public KeyGenerator keyGenerator() {
        return new KeyGenerator(){
            @Override
            public Object generate(Object target, java.lang.reflect.Method method, Object... params) {
                StringBuffer sb = new StringBuffer();
                sb.append(target.getClass().getName());
                sb.append(method.getName());
                for(Object obj:params){
                    sb.append(obj.toString());
                }
                System.out.println("调用Redis生成key:"+sb.toString());
                return sb.toString();
            }
        };
    }
}

启动类中开启缓存

image.png

新增业务测试类

package com.lwb.service;


import com.lwb.config.ResultBean;

public interface TestService {
	
	ResultBean findAllUser()throws Exception;

}


package com.lwb.service;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import com.jfinal.plugin.activerecord.Db;
import com.jfinal.plugin.activerecord.Record;
import com.lwb.config.ResultBean;

@Service
public class TestServiceImpl implements TestService {

	@Override
	@Cacheable(cacheNames = "findAllUser")
	public ResultBean findAllUser() throws Exception {
		List<Record> find = Db.find("select * from t_user");
		List<Map<String, Object>> result=new ArrayList<>();
		for (Record record : find) {
			result.add(record.getColumns());
		}
		return ResultBean.success(result);
	}

}

测试controller

package com.lwb.controller;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.lwb.config.ResultBean;
import com.lwb.service.TestService;

@RestController
public class TestController {
	
	@Autowired
	private TestService testService;
	
	@RequestMapping("test")
	public ResultBean test() {
		try {
			return testService.findAllUser();
		} catch (Exception e) {
			e.printStackTrace();
			return null;
		}
	}
}

访问测试controller

第一次查库,第二次直接走的缓存

redis中数据

image.png

默认存储时间是7天,可以在配置中自行修改

配置完成

缓存的其他注解使用方法请自行百度

评论区

热门分享

扫码入社