@Target({METHOD, FIELD})
@Retention(RUNTIME)
public @interface GeneratedValue {
GenerationType strategy() default AUTO;
String generator() default "";
}
public enum GenerationType {
//表生成: 当你的实体需要一个新的主键时,JPA 将会从这个表中获取下一个可用的主键值。这种方式可以跨不同的数据库平台使用。
TABLE,
//序列生成: 必须指定SEQ,Oracle、PostgreSQL数据库要指定序列
SEQUENCE,
//自增生成: 数据库会自动为主键分配一个唯一的值,MySQL 使用 AUTO_INCREMENT
IDENTITY,
//自动选择: 自动选择合适的策略来生成主键,根据底层数据库选择使用IDENTITY、SEQUENCE或TABLE策略
AUTO
}
@RestController
public class GeneratedStrategyController {
@Autowired
GeneratedStrategyService generatedStrategyService;
@GetMapping("/strategy")
public Map<String,String> generatedStrategy(){
return generatedStrategyService.generatedStrategy();
}
@GetMapping("/saveNotId")
public Map<String,String> saveNotId(){
return generatedStrategyService.saveNotId();
}
}
public interface InventoryListDao extends JpaRepository<InventoryListEntity, Integer> {
@Query(value = "SELECT * FROM (select * from inventory_list ORDER BY id DESC) WHERE rownum <= 1", nativeQuery = true)
InventoryListEntity getLastOne();
}
== 不同策略的dao接口都将entity指定上id,看执行的结果。==
是用JPA的自带接口方法,执行save时,entity中主键不为空,则会先通过id查询数据。与id为null的情况不同,插入的entity会在原来的对象上修改,不用重新接收对象。如果Entity的id不为null,对应id的数据不存在,则需要重新接收才能获取到对应entity的id值。
@Component
public class GeneratedStrategyServiceImpl implements GeneratedStrategyService {
@Autowired
InventoryListDao inventoryListDao;
@Autowired
InventoryListAUTODao inventoryListAUTODao;
@Autowired
InventoryListSEQUENCEDao inventoryListSEQUENCEDao;
@Autowired
InventoryListTABLEDao inventoryListTABLEDao;
private final Log log = LogFactory.getLog(this.getClass());
Gson gson = new Gson();
@Override
@Transactional
public Map<String,String> generatedStrategy(){
Map<String, String> map = new HashMap<>();
InventoryListEntity source = inventoryListDao.getLastOne();
log.info("source: " + gson.toJson(source));
// TABLE
InventoryListTABLEEntity tableEntity = gson.fromJson(gson.toJson(source), InventoryListTABLEEntity.class);
log.info("TABLE开始: " + gson.toJson(tableEntity));
tableEntity.setId(source.getId() + 10);
InventoryListTABLEEntity saveTableEntity = inventoryListTABLEDao.save(tableEntity);
log.info("TABLE结束1: " + gson.toJson(tableEntity));
log.info("TABLE结束2: " + gson.toJson(saveTableEntity));
map.put("TABLE", String.valueOf(saveTableEntity.getId()));
// SEQUENCE
InventoryListSEQUENCEEntity sequenceEntity = gson.fromJson(gson.toJson(source), InventoryListSEQUENCEEntity.class);
log.info("SEQUENCE开始: " + gson.toJson(sequenceEntity));
sequenceEntity.setId(source.getId() + 20);
InventoryListSEQUENCEEntity saveSequenceEntity = inventoryListSEQUENCEDao.save(sequenceEntity);
log.info("SEQUENCE结束1: " + gson.toJson(sequenceEntity));
log.info("SEQUENCE结束2: " + gson.toJson(saveSequenceEntity));
map.put("SEQUENCE", String.valueOf(saveSequenceEntity.getId()));
// IDENTITY
InventoryListEntity identityEntity = gson.fromJson(gson.toJson(source), InventoryListEntity.class);
log.info("IDENTITY开始: " + gson.toJson(identityEntity));
identityEntity.setId(source.getId() + 30);
InventoryListEntity saveIdentityEntity = inventoryListDao.save(identityEntity);
log.info("IDENTITY结束1: " + gson.toJson(identityEntity));
log.info("IDENTITY结束2: " + gson.toJson(saveIdentityEntity));
map.put("IDENTITY", String.valueOf(saveIdentityEntity.getId()));
// AUTO
InventoryListAUTOEntity autoEntity = gson.fromJson(gson.toJson(source), InventoryListAUTOEntity.class);
log.info("AUTO开始: " + gson.toJson(autoEntity));
autoEntity.setId(source.getId() + 40);
InventoryListAUTOEntity saveAutoEntity = inventoryListAUTODao.save(autoEntity);
log.info("AUTO结束1: " + gson.toJson(autoEntity));
log.info("AUTO结束2: " + gson.toJson(saveAutoEntity));
map.put("AUTO", String.valueOf(saveAutoEntity.getId()));
return map;
}
@Override
public Map<String, String> saveNotId() {
Map<String, String> map = new HashMap<>();
InventoryListEntity source = inventoryListDao.getLastOne();
log.info("source: " + gson.toJson(source));
InventoryListTABLEEntity tableEntity = gson.fromJson(gson.toJson(source), InventoryListTABLEEntity.class);
tableEntity.setId(null);
InventoryListTABLEEntity saveTableEntity = inventoryListTABLEDao.save(tableEntity);
log.info("TABLE结束1: " + gson.toJson(tableEntity));
log.info("TABLE结束2: " + gson.toJson(saveTableEntity));
map.put("TABLE", String.valueOf(saveTableEntity.getId()));
return map;
}
}
不指定generator,默认为hibernate_sequence。
@Repeatable(SequenceGenerators.class)
@Target({TYPE, METHOD, FIELD})
@Retention(RUNTIME)
public @interface SequenceGenerator {
// 与GeneratedValue连用指定自增序列名称
String name();
// 数据库对应自增序列名称
String sequenceName() default "";
String catalog() default "";
String schema() default "";
int initialValue() default 1;
int allocationSize() default 50;
}
GeneratedValue指定自增序列和SequenceGenerator的name不一致,优先级高(不一致序列,GeneratedValue优先级更高)
序列不对的时候,启动会变慢(我的本地启动是这样)