JPA主键自动生成策略-数据库Oracle
2023-12-21 20:53:39
@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
}
代码例子
Controller
@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();
}
}
Dao
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使用不同的策略标识
Service
== 不同策略的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;
}
}
策略使用错误提示
TABLE
== 不指定从表中查询一些数据==
SEQUENCE
不指定generator,默认为hibernate_sequence。
IDENTITY
直接往数据库中插入数据,出现不为空插入数据错误
AUTO
SequenceGenerator
@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优先级更高)
序列不对的时候,启动会变慢(我的本地启动是这样)
文章来源:https://blog.csdn.net/weixin_47748878/article/details/135124232
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!