项目结构
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(); } }; } }
启动类中开启缓存
新增业务测试类
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中数据
默认存储时间是7天,可以在配置中自行修改
配置完成
缓存的其他注解使用方法请自行百度