Spring Cache整合Redis完成服務層簡單緩衝

來源:互聯網
上載者:User
設計目標

Service→緩衝→資料庫

初次查詢資料來自資料庫,重新查詢來自緩衝

有增刪改,令緩衝失效 項目結構

主要關註:service、jpadao、entity幾個源碼包和測試包

設定檔在resources下的-jpa檔案和cache目錄下的-redis檔案

建表語句在\showcase\src\test\resources\init-table-user.sql

日誌配置在\showcase\src\test\resources\logback-test.xml Spring Data JPA 完成Dao的編寫 依賴管理

<dependency>  <groupId>org.springframework.data</groupId>  <artifactId>spring-data-jpa</artifactId>  <version>1.11.7.RELEASE</version></dependency><!-- hibernate jpa--><dependency>  <groupId>org.hibernate</groupId>  <artifactId>hibernate-entitymanager</artifactId>  <version>4.3.7.Final</version></dependency><dependency>  <groupId>javax.el</groupId>  <artifactId>javax.el-api</artifactId>  <version>2.2.4</version></dependency>

當然還有其他依賴,如下面要用到的h2資料庫,spring的context等,讀者運行測試案例時缺什麼包再依賴什麼包吧。 實體類 org.lanqiao.showcase.entity.User

@Entity@Table(name = "t_user")public class User implements Serializable{  private Integer id;  private String username;  private String password;  private Integer status;  private Integer teamId;  @Id  @GeneratedValue(strategy =GenerationType.AUTO)  public Integer getId() {    return id;  }  @Column(name="team_id")  public Integer getTeamId() {    return teamId;  }  // 其餘略
sql:init-table-user.sql
CREATE TABLE IF NOT EXISTS t_user (  id       INT NOT NULL  AUTO_INCREMENT,  username VARCHAR(100),  password VARCHAR(100),  status   INT,  team_id INT,  PRIMARY KEY (`id`));INSERT INTO t_user (username, password, status,team_id) VALUES ('aaa','aaa',1,1);INSERT INTO t_user (username, password, status,team_id) VALUES ('bbb','aaa',1,1);INSERT INTO t_user (username, password, status,team_id) VALUES ('ccc','aaa',1,2);INSERT INTO t_user (username, password, status,team_id) VALUES ('ddd','aaa',1,2);CREATE  TABLE t_team(  id INT AUTO_INCREMENT,  name VARCHAR(100),  PRIMARY KEY (`id`));INSERT INTO t_team (name) VALUES ('蒙特內格羅老妖');INSERT INTO t_team (name) VALUES ('天山童母');
spring xml applicationContext-jpa.xml
<!-- Jpa Entity Manager 配置  entityManager是crud的API-->  <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">    <property name="dataSource" ref="dataSource"/>    <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>    <!--掃描實體@Entity-->    <property name="packagesToScan" value="org.lanqiao.showcase.entity"/>    <property name="jpaProperties">      <props>        <!-- 命名規則 My_NAME->MyName -->        <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>      </props>    </property>  </bean>  <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">    <!--設定方言-->    <property name="databasePlatform" value="org.hibernate.dialect.H2Dialect"/>  </bean>  <!-- Spring Data Jpa配置  尋找和裝配DAO-->  <jpa:repositories base-package="org.lanqiao.showcase.jpadao"                    transaction-manager-ref="transactionManager"                    entity-manager-factory-ref="entityManagerFactory"/>  <!-- Jpa 事務配置 -->  <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">    <property name="entityManagerFactory" ref="entityManagerFactory"/>  </bean>  <!-- 使用annotation定義事務 -->  <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true"/>  <jdbc:embedded-database id="dataSource" type="H2">    <jdbc:script location="classpath:init-table-user.sql"/>  </jdbc:embedded-database>  <bean id="userService" class="org.lanqiao.showcase.service.UserService"/>
DAO的編寫 org.lanqiao.showcase.jpadao.UserDao
import org.lanqiao.showcase.entity.User;import org.springframework.data.repository.CrudRepository;public interface UserDao extends CrudRepository<User,Integer> {}
單元測試 org.lanqiao.showcase.jpadao.UserDaoTest
package org.lanqiao.showcase.jpadao;import org.lanqiao.showcase.entity.User;import org.junit.Before;import org.junit.Test;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.test.context.ContextConfiguration;import org.springframework.test.context.junit4.AbstractTransactionalJUnit4SpringContextTests;import org.web2017.test.data.RandomData;import static org.assertj.core.api.Assertions.assertThat;@ContextConfiguration("classpath:applicationContext-jpa.xml")public class UserDaoTest extends AbstractTransactionalJUnit4SpringContextTests {  @Autowired  private UserDao userDao;  @Test  public void testFindAll() {    save();    // 初始化4條,上面又增一條    assertThat(userDao.findAll().iterator()).hasSize(5);  }  private void save(){    final User entity = new User();    entity.setUsername(RandomData.randomName("username"));    entity.setPassword(RandomData.randomName("password"));    userDao.save(entity);  }}
順便貼下logback-test.xml(test/resources目錄下)

用來查看sql列印:

<?xml version="1.0" encoding="UTF-8"?><configuration>    <appender name="console" class="ch.qos.logback.core.ConsoleAppender">        <encoder>            <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n            </pattern>        </encoder>    </appender>    <appender name="rollingFile"        class="ch.qos.logback.core.rolling.RollingFileAppender">        <file>/tmp/logs/fullstack.log</file>        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">            <fileNamePattern>/tmp/logs/fullstack.%d{yyyy-MM-dd}.log            </fileNamePattern>        </rollingPolicy>        <encoder>            <pattern>%date{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n            </pattern>        </encoder>    </appender>    <!-- project default level -->    <logger name="org.lanqiao" level="debug" />    <logger name="org.web2017" level="debug" />    <logger name="org.hibernate.SQL" level="debug"/>    <root level="warn">        <appender-ref ref="console"/>        <!-- 生產環境取消下行注釋        <appender-ref ref="rollingFile" level="error"/>        -->    </root></configuration>

主要是這一行<logger name="org.hibernate.SQL" level="debug"/> 小結

單元測試能跑通,說明持久層資料庫的訪問是沒有問題的 Spring Cache整合Redis完成服務層緩衝 redis串連資訊 cache/redis-config.properties

# Redis settings# server IPredis.host=your_redis_ip# server portredis.port=63799# server passredis.pass=your_redis_secret# use dbIndexredis.database=0# 控制一個pool最多有多少個狀態為idle(閒置)的jedis執行個體redis.maxIdle=300# 表示當borrow(引入)一個jedis執行個體時,最大的等待時間,如果超過等待時間(毫秒),則直接拋出JedisConnectionException;redis.maxWait=3000# 在borrow一個jedis執行個體時,是否提前進行validate操作;如果為true,則得到的jedis執行個體均是可用的redis.testOnBorrow=true
配置redisCacheManager並開啟cache註解驅動:cache/applicationContext-redis.xml
<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:cache="http://www.springframework.org/schema/cache"       xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"       xmlns:c="http://www.springframework.org/schema/c"       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/cache http://www.springframework.org/schema/cache/spring-cache.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">  <context:property-placeholder location="classpath:cache/redis-config.properties"/>  <!-- 啟用緩衝註解功能,這個是必須的,否則註解不會生效,另外,該註解一定要聲明在spring主設定檔中才會生效 -->  <cache:annotation-driven cache-manager="redisCacheManager"/>  <!-- redis 相關配置 -->  <bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">    <property name="maxIdle" value="${redis.maxIdle}"/>    <property name="maxWaitMillis" value="${redis.maxWait}"/>    <property name="testOnBorrow" value="${redis.testOnBorrow}"/>  </bean>  <bean id="JedisConnectionFactory"        class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory"        p:host-name="${redis.host}" p:port="${redis.port}" p:password="${redis.pass}"        p:pool-config-ref="poolConfig"/>  <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">    <property name="connectionFactory" ref="JedisConnectionFactory"/>    <property name="keySerializer" >      <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>    </property>    <property name="valueSerializer" >      <bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer"/>    </property>  </bean>  <!-- spring自己的緩衝管理器,這裡定義了緩衝位置名稱 ,即註解中的value -->  <bean id="redisCacheManager"        class="org.springframework.data.redis.cache.RedisCacheManager"        c:redisOperations-ref="redisTemplate"        p:usePrefix="true" >    <property name="cacheNames">      <list>        <value>userCache</value>        <value>teamCache</value>      </list>    </property>    <property name="cachePrefix">      <bean class="org.springframework.data.redis.cache.DefaultRedisCachePrefix"/>    </property>  </bean></beans>

這個網上都找得到,需要說明的是:redisTemplate中為了便於到redis伺服器去查驗資料,最好將key的序列化設定為字串序列化:

<property name="keySerializer" >      <bean class="org.springframework.data.redis.serializer.StringRedisSerializer"/>    </property>

value序列化用JDK內建對象序列化,所以要求我們的實體類實現Serializable介面 編寫Service完成簡單邏輯並使用Spring @Cache×××註解:

package org.lanqiao.showcase.service;import org.lanqiao.showcase.entity.User;import org.lanqiao.showcase.jpadao.UserDao;import org.springframework.beans.factory
相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.