jpa联合主键
在微服务的世界中,不同模块的表在不同的数据库中,而jpa无法通过@ManyToMany
这种注解来实现多对多关系,所以还是使用中间表的方式来进行多对多的关系配置。
当类中需要表示联合主键时,除了在主键属性上添加注解@Id
注解外,还需在类上标明注解@IdClass(Pl.class)
,指定主键所在的类
注意:中间表需要通过网络传输,所以需要实现Serializable
接口
package com.tensquare.qa.pojo;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
@Entity
@Table(name = "tb_pl")
@IdClass(Pl.class)
public class Pl implements Serializable {
@Id
private String problemid;
@Id
private String labelid;
public String getProblemid() {
return problemid;
}
public void setProblemid(String problemid) {
this.problemid = problemid;
}
public String getLabelid() {
return labelid;
}
public void setLabelid(String labelid) {
this.labelid = labelid;
}
}
jpa修改数据库
当jpa新添加的dao方法需要修改数据库时,需要添加@Modifying
注解,表示需要修改数据库
public interface ArticleDao extends JpaRepository<Article,String>,JpaSpecificationExecutor<Article>{
//审核
@Query("update Ariticle set state = '1' where id = ?")
@Modifying //表示需要修改数据库
public void examine(String articleId);
//点赞
@Query("update Ariticle set thumbup = thumbup+1 where id = ?")
@Modifying //表示需要修改数据库
public void thumbup(String articleId);
}
除此之外,需要在service中添加事务注解@Transactional
,使用该注解需要在启动类中添加@EnableTransactionManagement
注解
在SpringBoot中使用redis
首先docker中安装redis
docker run -di --name=tensquare_redis -p 6379:6379 redis
一、添加起步依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
二、添加redis配置
spring:
redis:
host: 192.168.200.131
三、redis的使用逻辑
一般来说,使用redis时,以文章为例。
- 根据id查询文章时保存文章到redis,以便下次去redis中查询
- 修改删除文章时,将redis中的文章删除
注意:redis缓存中存储数据一般会设置时效,这里设置为1天
/**
* 根据ID查询实体
* @param id
* @return
*/
public Article findById(String id) {
Article article = (Article) redisTemplate.opsForValue().get("article_" + id);
if (article==null){
//如果缓存中没有,从数据库中查询
article = articleDao.findById(id).get();
//参数3:缓存有效时间长度
//参数4:缓存有效时间单位
redisTemplate.opsForValue().set("article_"+id,article,1, TimeUnit.DAYS);
}
return article;
}
当修改或删除时,去redis中删除文章
/**
* 修改
* @param article
*/
public void update(Article article) {
//从redis缓存中移除
redisTemplate.delete("article_"+article.getId());
articleDao.save(article);
}
/**
* 删除
* @param id
*/
public void deleteById(String id) {
//从redis缓存中移除
redisTemplate.delete("article_"+id);
articleDao.deleteById(id);
}
四、注意被存入redis的实体类应该实现Serializable
接口
原因:实现Serializable接口,可以让对象以流的形式输出或存储,如果不实现,对象只能存在于虚拟机的内存中
SpringCache缓存
SpringCache缓存的底层实现是ConcurrentHashMap
一、在启动类上添加注解@EnableCaching
,启动springcache
@SpringBootApplication
@EnableCaching //启动springcache
public class GatheringApplication {
public static void main(String[] args) {
SpringApplication.run(GatheringApplication.class, args);
}
@Bean
public IdWorker idWorkker(){
return new IdWorker(1, 1);
}
}
二、在根据id查询的方法中,添加缓存
@Cacheable
:添加缓存
value
:指定缓存添加到的域(随意指定)key
:指定缓存的键,#id指从参数列表中获取id值- 注解所在方法的返回值为缓存的值
@Cacheable(value = "gathering",key = "#id")
public Gathering findById(String id) {
return gatheringDao.findById(id).get();
}
三、在修改与删除方法中,删除缓存
@CacheEvict
移除缓存
value
:指定缓存所在的域(需要与Cacheable对应)key
:指定移除的键,#gathering.id表示从参数列表中获取gathering对象的id属性
@CacheEvict(value = "gathering", key="#gathering.id")
public void update(Gathering gathering) {
gatheringDao.save(gathering);
}
/**
* 删除
* @param id
*/
@CacheEvict(value = "gathering", key="#id")
public void deleteById(String id) {
gatheringDao.deleteById(id);
}