Java 用JPA实现数据库一级缓存
我有以下设置(未测试),因为我担心这将打破。在签入LDAP之前,我想在数据库中实现某种一级缓存查找 (1)如何在服务代码中循环表/getUserEmail,恐怕会有多行来自数据库。如果没有,如何预防。 (2)如何改进或使其成为傻瓜。 我对JPA/Spring boot一般来说是新手,所以请帮助我 实体Java 用JPA实现数据库一级缓存,java,spring,spring-boot,spring-data-jpa,spring-data,Java,Spring,Spring Boot,Spring Data Jpa,Spring Data,我有以下设置(未测试),因为我担心这将打破。在签入LDAP之前,我想在数据库中实现某种一级缓存查找 (1)如何在服务代码中循环表/getUserEmail,恐怕会有多行来自数据库。如果没有,如何预防。 (2)如何改进或使其成为傻瓜。 我对JPA/Spring boot一般来说是新手,所以请帮助我 实体 @Entity @Table(name = "userEmailCache") public class userEmailCacheEntity { @Id
@Entity
@Table(name = "userEmailCache")
public class userEmailCacheEntity {
@Id
@Column(unique = true)
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String userEmail;
private String userId;
// getter and setters redacted
@Repository
public interface userEmailCacheEntityRepository extends JpaRepository<userEmailCacheEntity, Long> {
@Query(value="SELECT "
+ "userEmail "
+ "FROM userEmailCache "
+ "WHERE userId = :param01 ")
String getUserEmail(@Param("param01") String param01);
}
存储库
@Entity
@Table(name = "userEmailCache")
public class userEmailCacheEntity {
@Id
@Column(unique = true)
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String userEmail;
private String userId;
// getter and setters redacted
@Repository
public interface userEmailCacheEntityRepository extends JpaRepository<userEmailCacheEntity, Long> {
@Query(value="SELECT "
+ "userEmail "
+ "FROM userEmailCache "
+ "WHERE userId = :param01 ")
String getUserEmail(@Param("param01") String param01);
}
Java按照惯例使用CamelCase和大写的类名,所以我改变了这一点 您不需要在
@Id
上使用@Column(unique=true)
-这意味着它是主键,并且必须是唯一的
@Entity
@Table(name = "userEmailCache")
public class UserEmailCacheEntity {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String userEmail;
private String userId;
// getter and setters redacted
}
那么你说userId
不是唯一的?我认为这有点用词不当,因为ID应该用来识别事物。无论如何,您可能希望确保在数据库中的userId
列上有一个索引,以加快搜索速度
不过,您确实弄错了返回类型。因为您说过每个用户ID可以有多封电子邮件,所以您需要返回一个列表:
@Repository
public interface UserEmailCacheEntityRepository
extends JpaRepository<UserEmailCacheEntity, Long> {
@Query(value="SELECT "
+ "userEmail "
+ "FROM userEmailCache "
+ "WHERE userId = :uid ")
List<String> getUserEmails(@Param String uid);
}
@存储库
公共接口UserEmailCacheEntityRepository
扩展JPA假设{
@查询(value=“选择”
+“用户电子邮件”
+“来自userEmailCache”
+“其中userId=:uid”)
列出getUserEmails(@Param String uid);
}
然后还需要处理包含多个条目的结果:
@Autowired
userEmailCacheEntityRepository repo;
//check in database and get email
List<String> strEmails = repo.getUserEmails(userId);
//if not found in database
if (strEmails.isEmpty()) {
//fetch email from LDAP/Active Directory
String ldapMail = retrieve();
} else {
LOG.info("[I] Found in DB {} results for {}: {}", strEmail.size(), userId, strEmail);
}
//save in Database
UserEmailCacheEntity file = new userEmailCacheEntity();
file.setUserEmail(ldapMail);
file.setUserId(userId);
repo.save(file);
@Autowired
userEmailCacheEntityRepository回购;
//签入数据库并获取电子邮件
List strEmails=repo.getUserEmails(userId);
//如果在数据库中找不到
if(strEmails.isEmpty()){
//从LDAP/Active Directory获取电子邮件
字符串ldapMail=retrieve();
}否则{
LOG.info({}:{},strEmail.size(),userId,strEmail的DB{}结果中找到[I];
}
//保存在数据库中
UserEmailCacheEntity文件=新的UserEmailCacheEntity();
setUserEmail(ldapMail)文件;
setUserId(userId);
保存(文件);
我无法告诉您如何处理多封返回的电子邮件,因为我不知道您在用它们做什么(尽管这种设计似乎很奇怪)
你为什么称你的新实体为“文件”?它不是文件,不是吗?它不是文件。我使用以下函数绕过可选的findFirst1ByUserIdOrderByEmailAsc(字符串userId);