postgresql ALTER TABLE添加ON CASCADE语句

9fkzdhlc  于 2023-11-18  发布在  PostgreSQL
关注(0)|答案(4)|浏览(164)

我想在PostgreSQL中执行以下操作(使用Hibernate):

ALTER TABLE fruits ADD CONSTRAINTS id ON DELETE CASCADE;

字符串
显然,我上面的代码不起作用,所以我正在寻找正确的语句。
如果我不能做到这一点,那么以下几点如何:
我的表fruits中有一堆数据。fruits中的id字段被表grapes用作外键。我需要删除fruits中的特定行,并且我希望删除级联到grapes,并删除grapes中具有指定id的所有条目。如何执行?

delete from fruits where id = 1 cascade;


注意事项:我不想做一个连接,然后删除grape中相应的数据。这只是一个例子。在真实的应用中,大量的表依赖于fruits
既然我使用的是Hibernate,那么当我使用一个delete语句时,Hibernate可以帮助我吗?
或者我可以用PostgreSQL中的信息模式或系统目录来做这件事吗?

k3fezbri

k3fezbri1#

您所描述的是使用ON DELETE CASCADE选项的教科书外键约束
SQL中,您可以在场景中创建表grapes时隐式创建:

CREATE TABLE grapes (
  grape_id int PRIMARY KEY
  fruit_id int REFERENCES fruits(fruit_id) ON DELETE CASCADE
  );

字符串
或者你可以稍后添加:

ALTER TABLE grapes
ADD CONSTRAINT grapes_fruit_id_fkey FOREIGN KEY (fruit_id)
REFERENCES fruits (fruit_id) ON DELETE CASCADE;


不要直接为此编辑系统目录。请使用专用的DDL命令。
请注意,外键约束要求引用列上有唯一索引或主索引(在本例中为fruits.fruit_id),并强制执行referential integrity

jpfvwuh4

jpfvwuh42#

这是一个单向的父子关系,你希望父级的更改向下级联到子级,而不是相反。使用注解,我们可以实现这一点。在fruits实体中:

@Cascade(value = { org.hibernate.annotations.CascadeType.ALL, 
    org.hibernate.annotations.CascadeType.DELETE_ORPHAN })
@OneToMany(fetch = FetchType.LAZY, mappedBy = "fruit")
public Set<Grape> getGrapes() {
    return grapes;
}

字符串
在“葡萄”实体中:

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "fruit_id")
public Fruit getFruit() {
    return fruit;
}


当您更新或删除父fruit时,更改将自动级联到grape子节点。

ha5z0ras

ha5z0ras3#

我找到了答案:

//in Fruit object
    @OneToMany(mappedBy = "fruit", orphanRemoval=true)
    private List<Grape> grapes;

   //in Grape object
   @OneToOne
   private Fruit fruit;

字符串

bkhjykvo

bkhjykvo4#

动机

这对我不起作用,我设置了

<property name="show_sql">true</property>

字符串
并且输出没有像...ON DELETE CASCADE...这样的状态。
我找到了另一个适合我的解决方案:
让我们假设你有一个作者类和一个作者的书类,你想在删除作者时自动删除所有的书(通过hibernate,sql-query,.),并且有一些原因你不能(总是)通过session.delete()删除。
也许是吧:

session.createSQLQuery("DELETE FROM author").executeUpdate();

解决方案

所以你的作者类可能看起来像这样:

@Entity
@Table(name = "author")
public class Author {

   @Id
   @GeneratedValue(generator = "increment")
   @GenericGenerator(name = "increment", strategy = "increment")
   @Column(name = "ID")
   private Integer id;

   @Column(name = "NAME")
   private String name;

   @OneToMany(mappedBy = "author")
   private Set<Book> books;
...


课本是这样的:

@Entity
@Table(name = "book")
public class Book {

   @Id
   @GeneratedValue(generator = "increment")
   @GenericGenerator(name = "increment", strategy = "increment")
   @Column(name = "ID")
   private Integer id;

   @Column(name = "TITLE")
   private String title;

   @ManyToOne
   @JoinColumn(name = "AUTHOR_ID", foreignKey = @ForeignKey(name = "FK_BOOK_author_AUTHOR_ID"))
   private Author author;
...


诀窍是使用

foreignKey = @ForeignKey(name = "FK_BOOK_author_AUTHOR_ID")


然后添加

<property name="hibernate.hbm2ddl.import_files">update.sql</property>


到你的 hibernate.cfg.xml(不要忘记 * hibernate.hbm2ddl.auto *)。然后 update.sql 包含表约束的更新:

ALTER TABLE `book` DROP FOREIGN KEY `FK_BOOK_author_AUTHOR_ID`; 
ALTER TABLE `book` ADD CONSTRAINT `FK_BOOK_author_AUTHOR_ID` FOREIGN KEY (`AUTHOR_ID`) REFERENCES `author`(`ID`) ON DELETE CASCADE;


因此,hibernate总是能够删除/更改约束,因为它知道约束的名称-您还应该检查@Cascade设置-并且您必须实现如何处理会话中对象删除的策略!

相关问题