我写了一个必须返回唯一字符串的控制器。要求是,即使经过数年并且即使代码将扩展到更多VM,此控制器的两次调用也绝不能返回相同的String。
我的问题是以下代码是否正确达到声明的目的,或者您是否有任何提示。
控制器:
@RestController public class UtilityController { @Autowired UtilityServices utilityServices; @GetMapping("/uniqueIdentifier") @ResponseBody public String uniqueIdentifier() { return utilityServices.getUniqueIdentifier(); }
服务:
@Service public class UtilityServices { @Autowired private UniqueIdRepository uniqueIdRepository; @Transactional public String getUniqueIdentifier() { String uniqueId = RandomString.getSecureRandomString(); while (uniqueIdRepository.existsById(uniqueId)) { uniqueId = RandomString.getSecureRandomString(); } uniqueIdRepository.save(new UniqueId(uniqueId)); return uniqueId; } }
实体:
@Entity @AllArgsConstructor @NoArgsConstructor @Getter @Setter @EqualsAndHashCode @ToString public class UniqueId implements Serializable { @Id private String uniqueId; }
仓库:
public interface UniqueIdRepository extends CrudRepository<UniqueId, String> { }
就这样。我忽略了RandomString该类的代码,因为它在这种情况下不相关:我基于编写了一个代码SecureRandom,很可能每次返回一个不同的String时,但是我对此没有保证。假设我的RandomString.getSecureRandomString()方法迟早可以返回相同的String。
RandomString
SecureRandom
RandomString.getSecureRandomString()
我不确定@Transactional注解是否保证该getUniqueIdentifier()方法永远不会抛出错误。
@Transactional
getUniqueIdentifier()
根据您的情况,更好的主意是使用UUID:
因此,任何人都可以创建一个UUID并几乎可以肯定地使用它来标识某些内容,即该标识符不会重复已经或将要创建的用于标识其他内容的标识符。因此,以后可以将由独立各方用UUID标记的信息合并到单个数据库中,或在同一信道上传输,且重复的可能性很小。
@Service public class UtilityServices { @Autowired private UniqueIdRepository uniqueIdRepository; @Transactional public String getUniqueIdentifier() { String uniqueId = String.format("%s-%s", RandomStringUtils.randomAlphanumeric(4), UUID.randomUUID().toString().replace("-", "") ); // you could left this check while (uniqueIdRepository.existsById(uniqueId)) { uniqueId = UUID.randomUUID().toString().replace("-", ""); } uniqueIdRepository.save(new UniqueId(uniqueId)); return uniqueId; } }
顺便说一句, 您可以使用@DataModel:
@Data
@Data @Entity @NoArgsConstructor @AllArgsConstructor public class UniqueId implements Serializable { private static final long serialVersionUID = 0L; @Id private String uniqueId; }
而且不要忘记serialVersionUID。
serialVersionUID