Spring data jpa 的事務與快取優化
阿新 • • 發佈:2019-01-31
各配置檔案如下:
applicationContext.xml
persistence.xml<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context" xmlns:jdbc="http://www.springframework.org/schema/jdbc" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.2.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc-3.2.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.2.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.2.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.2.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd" default-lazy-init="true"> <!--第一步--> <!--定義服務層程式碼存放的包掃描路徑--> <context:component-scan base-package="com.jike.usermanage.service" /> <!--第二步--> <!--定義實體的工廠bean--> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="persistenceUnitName" value="userPU" /> <property name="persistenceXmlLocation" value="classpath:persistence.xml"></property> </bean> <!--第三步--> <!--定義事務管理器--> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> </bean> <!--第四步--> <!--定義repository介面的存放目錄--> <!--定義介面實現的字尾,通常用Impl--> <!--定義實體工廠的引用--> <!--定義事務管理器的引用--> <jpa:repositories base-package="com.jike.usermanage.repository" repository-impl-postfix="Impl" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="transactionManager"/> <!--第五步--> <!--宣告採用註解的方式申明事務--> <tx:annotation-driven transaction-manager="transactionManager"/> <tx:advice id="userAdvice" transaction-manager="transactionManager"> <tx:attributes> <tx:method name="save*" propagation="REQUIRED" isolation="DEFAULT" read-only="false" rollback-for="UserNotFoundException" timeout="-1"/> <tx:method name="del*" propagation="REQUIRED"/> <tx:method name="update*" propagation="REQUIRED"/> <tx:method name="add*" propagation="REQUIRED"/> <tx:method name="find*" propagation="REQUIRED"/> <tx:method name="get*" propagation="REQUIRED"/> <tx:method name="apply*" propagation="REQUIRED"/> </tx:attributes> </tx:advice> <aop:config> <aop:pointcut id="userServiceMethod" expression="execution(* com.jike.usermanage.service.*.*(..))"/> <aop:advisor pointcut-ref="userServiceMethod" advice-ref="userAdvice" /> </aop:config> </beans>
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" version="2.0"> <persistence-unit name="userPU" transaction-type="RESOURCE_LOCAL"> <!--jpa的提供者--> <provider>org.hibernate.ejb.HibernatePersistence</provider> <properties> <!--宣告資料庫連線的驅動--> <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/> <!--jdbc資料庫的連線地址--> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/user_manage"/> <property name="hibernate.connection.username" value="root"/> <property name="hibernate.connection.password" value="123456"/> <!--配置方言--> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect"/> <!--啟用查詢日誌功能--> <property name="hibernate.show_sql" value="true"/> <!--優雅地輸出Sql--> <property name="hibernate.format_sql" value="true"/> <!--新增一條解釋型標註--> <property name="hibernate.use_sql_comments" value="false"/> <!--配置如何根據java模型生成資料庫表結構,常用update,validate--> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.cache.use_query_cache" value="true"/> <property name="hibernate.cache.use_second_level_cache" value="true"/> <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/> <property name="hibernate.cache.region.factory_class" value="org.hibernate.cache.ehcache.EhCacheRegionFactory"/> <property name="hibernate.cache.provider_configuration" value="classpath:ehcache.xml"/> </properties> </persistence-unit> </persistence>
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd"> <!-- 自動掃描controller包下的所有類,使其認為spring mvc的控制器 --> <context:component-scan base-package="com.jike.usermanage.controller" /> <mvc:annotation-driven /> <!-- 對模型檢視名稱的解析,即在模型檢視名稱新增前後綴 --> <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" p:prefix="/WEB-INF/pages/" p:suffix=".jsp" /> </beans>
ehcache.xml
<?xml version="1.0" encoding="UTF-8" ?>
<ehcache>
<defaultCache
maxElementsInMemory="50000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="false"/>
<cache name="entityCache" eternal="false" maxElementsInMemory="10000"
timeToIdleSeconds="60" timeToLiveSeconds="120" overflowToDisk="true" />
<!-- settings per class -->
<!-- <cache name="com.danielme.demo.springjpahib.Country"
maxElementsInMemory="1000"
eternal="false"
timeToIdleSeconds="180"
timeToLiveSeconds="180"
overflowToDisk="false"/>-->
</ehcache>
處理事務一般有兩種方式:
1. xml配置 如上。
2. 註解
@Transactional(isolation=Isolation.DEFAULT,propagation=Propagation.REQUIRED)
@Override
public User updateUser(User user) throws UserNotFound {
User userUpdate = userRepository.findOne(user.getId());
if (userUpdate==null)
throw new UserNotFound();
if (user.getName()!=null)
userUpdate.setName(user.getName());
if (user.getPhone()!=null)
userUpdate.setPhone(user.getPhone());
userRepository.save(userUpdate);
return userUpdate;
}
快取的xml配置如上。
程式碼書寫如下:
1. 實體類快取:
@Cache(usage=CacheConcurrencyStrategy.READ_WRITE,region="entityCache")
@Cacheable(true)
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue
@Column(name="id_")
private Integer id;
@Column(name="name_", length=60)
private String name;
@Column(name="phone_", length=11)
private String phone;
@Column(name="inCome_", precision=12, scale=2)
private BigDecimal inCome;
@Column(name="old_")
private Integer old;
@Column(name="worktimes_")
private Integer worktime;
@OneToMany(fetch=FetchType.EAGER)
private List<Interest> interests;
public User(){
}
public User(Integer id, String name){
this.id = id;
this.name = name;
}
public Integer getWorktime() {
return worktime;
}
public void setWorktime(Integer worktime) {
this.worktime = worktime;
}
public Integer getOld() {
return old;
}
public void setOld(Integer old) {
this.old = old;
}
public List<Interest> getInterests() {
return interests;
}
public void setInterests(List<Interest> interests) {
this.interests = interests;
}
public BigDecimal getInCome() {
return inCome;
}
public void setInCome(BigDecimal inCome) {
this.inCome = inCome;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
}
2. 常用的查詢語句快取:
public interface UserRepository extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User>{
public void add(User user);//新增
public User update(User user);//修改
public User addOrUpdate(User user);//新增或修改
public void delete(User user);//刪除
public User findOne(Integer id);//查詢單個實體
public List<User> findAll();//查詢所有實體
@Query(value="select u from User u where u.name like :name")
@QueryHints(value={@QueryHint(name="org.hibernate.cacheable",value="true")})
public List<User> findUserByName(@Param("name")String name);
}