Spring使用系列--JPA二级缓存的使用

本文介绍如何在基于Maven的项目中实现JPA二级缓存。通过添加必要的Maven依赖、配置applicationContext.xml文件、在实体类和DAO层添加缓存注解,最后通过单元测试验证缓存的有效性。

本示例是基于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二级缓存使用
 

<think>我们被要求回答三个部分: 1. 新建Spring Boot工程并配置Hibernate(使用spring-data-jpa) 2. 解释Hibernate是什么 3. 解释为什么要配置Hibernate 4. 解释spring-data-jpa是什么 同时,在回答的最后,必须按照格式要求提出3-5个相关问题,以“§§相关问题§§”开头,且禁止换行分散。 注意:用户的问题中提到了三个小问题,我们需要依次回答。 步骤: 1. 首先解释Hibernate是什么。 2. 然后解释为什么要配置Hibernate。 3. 接着解释spring-data-jpa是什么。 4. 然后给出新建Spring Boot工程并配置Hibernate(使用spring-data-jpa)的步骤。 由于是新建Spring Boot工程,我们可以通过Spring Initializr来创建,并添必要的依赖。 配置Hibernate实际上在Spring Boot中通过配置spring-data-jpa(它底层默认使用Hibernate)就可以实现。 具体步骤: a) 新建Spring Boot工程: 使用Spring Initializr(start.spring.io)或IDE(如IntelliJ IDEA)的Spring Initializr向导。 选择依赖:Spring Web, Spring Data JPA, 以及数据库驱动(例如H2、MySQL等)。 b) 配置数据源和JPA属性:在application.properties或application.yml中配置数据库连接和JPA(Hibernate)属性。 c) 创建实体类(使用JPA注解)和Repository接口(继承JpaRepository)。 这样,Hibernate就会自动配置,并且我们可以通过spring-data-jpa进行数据库操作。 下面详细说明: </think>### 关于 Hibernate 与 Spring Data JPA 的解析及配置指南 #### 1. **Hibernate 是什么?** Hibernate 是一个开源的 Java **对象关系映射(ORM)框架**,它实现了 JPA (Java Persistence API) 规范。核心功能: - 将 Java 对象(实体类)映射到数据库表 - 自动处理 SQL 生成与结果集转换 - 提供缓存、事务管理、延迟载等高级特性 - **核心价值**:开发者无需编写复杂 SQL,通过面向对象方式操作数据库 #### 2. **为什么需要配置 Hibernate?** 在 Spring Boot 中配置 Hibernate 的目的: - **数据持久化**:将业务数据存储到关系型数据库(MySQL/PostgreSQL 等) - **事务一致性**:确保复杂操作(如转账)的原子性 - **性能优化**:通过二级缓存、批处理提升数据库访问效率 - **跨数据库兼容**:切换数据库时只需修改方言配置(如 `MySQL8Dialect`) #### 3. **Spring Data JPA 是什么?** Spring Data JPASpring 提供的 **数据访问抽象层**: - **本质**:对 JPA 规范的封装(默认实现为 Hibernate) - **核心优势**: - 通过接口自动生成 CRUD 操作(如 `save()`, `findById()`) - 支持方法名衍生查询(如 `findByUsername(String name)`) - 简化分页/排序等复杂操作 - **与 Hibernate 关系**: ```mermaid graph TD A[Spring Data JPA] -->|底层实现| B(Hibernate) B -->|遵循规范| C(JPA) ``` --- ### 新建 Spring Boot 工程配置 Hibernate(Spring Data JPA) #### 步骤 1:创建项目 通过 [start.spring.io](https://start.spring.io/) 生成项目,依赖选择: - **Spring Data JPA**(自动包含 Hibernate) - **JDBC Driver**(如 MySQL Driver) - **Spring Web**(可选,用于 REST API) #### 步骤 2:配置数据源(`application.properties`) ```properties # 数据库连接 spring.datasource.url=jdbc:mysql://localhost:3306/mydb spring.datasource.username=root spring.datasource.password=123456 # Hibernate 配置 spring.jpa.hibernate.ddl-auto=update # 自动更新表结构 spring.jpa.show-sql=true # 显示执行的 SQL spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MySQL8Dialect ``` #### 步骤 3:创建实体类(映射数据库表) ```java @Entity public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Column(nullable = false, length = 50) private String username; // Getters and Setters } ``` #### 步骤 4:创建 Repository 接口(自动实现 CRUD) ```java public interface UserRepository extends JpaRepository<User, Long> { // 方法名自动生成查询:SELECT * FROM user WHERE username = ? List<User> findByUsername(String username); } ``` #### 步骤 5:注入 Repository 使用 ```java @Service public class UserService { @Autowired private UserRepository userRepository; public User createUser(String name) { User user = new User(); user.setUsername(name); return userRepository.save(user); // 自动执行 INSERT } } ``` --- ### 关键配置说明 | 配置项 | 作用 | |---------------------------------|----------------------------------------------------------------------| | `ddl-auto=update` | 启动时自动创建/更新表结构(生产环境建议用 `none`) | | `hibernate.dialect` | 指定数据库方言,优化 SQL 生成(如 MySQL8Dialect) | | `@Entity` + `@Id` | 声明实体类与主键 | | `JpaRepository` 接口 | 内置了 `save()`, `findAll()`, `deleteById()` 等 20+ 方法 |
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值