本示例是基于maven的项目
(1)需要添加的maven依赖
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.11.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>5.1.0.Final</version>
</dependency>
<dependency>
<groupId>net.sf.ehcache</groupId>
<artifactId>ehcache-core</artifactId>
<version>2.4.3</version>
</dependency>
(2)在applicationContext.xml中启用二级缓存
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="packagesToScan" value="com.hongtu"/>
<property name="jpaProperties">
<props>
<!--命名策略-->
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<!--基本配置-->
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<!--使用JPA的二级缓存-->
<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
<property name="sharedCacheMode" value="ENABLE_SELECTIVE"/>
</bean>
(3)在实体类上添加缓存功能
package com.hongtu.entity;
import org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
import javax.persistence.*;
import java.io.Serializable;
/**
* 用户实体类
*
* @author LIUTAO
* @version 2017/5/11
* @see
* @since
*/
@Cache(usage = CacheConcurrencyStrategy.READ_ONLY)
@Cacheable(true)
@Entity
public class User implements Serializable {
private static final long serialVersionUID = -8081225022334946487L;
private String name; //用户名
private Integer age; //年龄
private String password; //用户密码
private int id; //用户Id
public User() {
}
public User(String name, Integer age, String password, int id) {
this.name = name;
this.age = age;
this.password = password;
this.id = id;
}
@Basic
@Column(name = "name")
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Basic
@Column(name = "age")
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Basic
@Column(name = "password")
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Id
@Column(name = "id")
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
if (id != user.id) return false;
if (name != null ? !name.equals(user.name) : user.name != null) return false;
if (age != null ? !age.equals(user.age) : user.age != null) return false;
if (password != null ? !password.equals(user.password) : user.password != null) return false;
return true;
}
@Override
public int hashCode() {
int result = name != null ? name.hashCode() : 0;
result = 31 * result + (age != null ? age.hashCode() : 0);
result = 31 * result + (password != null ? password.hashCode() : 0);
result = 31 * result + id;
return result;
}
@Override
public String toString() {
return "User{" +
"name='" + name + '\'' +
", age=" + age +
", password='" + password + '\'' +
", id=" + id +
'}';
}
}
(4)在dao上使用缓存
package com.hongtu.dao;
import com.hongtu.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.QueryHints;
import javax.persistence.QueryHint;
import java.util.List;
/**
* 用户jpa持久层
*
* @author LIUTAO
* @version 2017/5/11
* @see
* @since
*/
public interface UserDao extends JpaRepository<User,Integer> {
/**
* 获取用户
* @param id
* @return
*/
@QueryHints({ @QueryHint(name = "org.hibernate.cacheable", value ="true") })
User findUserById(int id);
}
(5)进行单元测试
@Test
public void testFindUserByIdOfJpa(){
logger.debug("this user was found by jpa is "+userDao.findUserById(1));
logger.debug("this user was found by jpa is "+userDao.findUserById(1));
}
以下是运行结果:
2017-05-12 15:45:32.381 [main] DEBUG org.mybatis.spring.SqlSessionFactoryBean - Parsed mapper file: 'file [E:\MySelf\SpringDemo_hongtu_01\target\classes\mapper\UserMapper.xml]'
Hibernate:
select
user0_.id as id1_0_,
user0_.age as age2_0_,
user0_.name as name3_0_,
user0_.password as password4_0_
from
User user0_
where
user0_.id=?
2017-05-12 15:45:34.036 [main] DEBUG com.hongtu.test.TestUser - this user was found by jpa is User{name='张三丰', age=45, password='zsf123', id=1}
2017-05-12 15:45:34.040 [main] DEBUG com.hongtu.test.TestUser - this user was found by jpa is User{name='张三丰', age=45, password='zsf123', id=1}
Process finished with exit code 0
从上面的运行结果可以看出,进行了两次查询,但是最终仅仅和数据库进行了一次数据交互。
项目代码参考gitHub地址:jpa二级缓存使用