我对 Spring Data JPA 还很陌生。我想在非 id 列上生成序列,该列具有前缀,但前缀可以在运行时更改。
例如,如果用户输入“A”,那么数据将是“A00001”...并且继续像 A00002、A00003,但用户可以输入“B”、“C”...那么数据将是“B00001”、“B00002”。
实体:
@Entity
public class UserEntity extends BaseTimeEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(nullable=false, length=20)
private String role;
@GeneratorType(type=CustomGenerator.class,when= GenerationTime.INSERT)
@Column(nullable=false, length=45, unique = true, updatable = false)
private String loginId;
}
自定义生成器:
public class CustomGenerator implements ValueGenerator<String> {
private static final String query = "SELECT CONCAT('A',COALESCE(MAX((SUBSTR(LOGIN_ID,3))),10000)+1) FROM USER WHERE INSTR(LOGIN_ID, 'A')>0";
@Override
public String generateValue(Session session, Object o) {
NativeQuery nativeQuery = session.createSQLQuery(query);
String loginId = (String) nativeQuery.setFlushMode(COMMIT).uniqueResult();
return loginId;
}
}
在这篇文章的一些帮助下,我弄清楚了如何在非 id 列上生成序列(如何为非 ID 字段使用序列生成器?),但仍然不知道如何动态更改前缀。
我有一个类似的问题,但条件是前缀取决于实体类型,并带有-月-年后缀。所以我的解决方案是:
@Getter
@AllArgsConstructor
public enum EntityType {
INNER("I", "inner_number_sequence"),
EXTERNAL("Е", "external_number_sequence");
private final String prefix;
private final String sequence;
}
@Override
public String generateValue(Session session, Object object) throws HibernateException {
if (!(object instanceof MyEntity)) {
throw new CastException("Incorrect cast...");
}
EntityType type = ((MyEntity) object).getType();
String nextSeqValue = String.format("select nextval('%s');", type.getSequence());
@SuppressWarnings("unchecked")
NativeQuery<BigInteger> query = session.createNativeQuery(nextSeqValue);
Long sequenceValue = query.setHibernateFlushMode(COMMIT).uniqueResult().longValue();
String postfix = LocalDate.now().format(DateTimeFormatter.ofPattern("-MM-yy"));
return type.getPrefix() + String.format("%05d", sequenceValue) + postfix;
}
我想没有什么可以阻止你将用户的字母放置到“loginId”中,并将其与类转换后的序列连接起来,如我的示例所示。