Hibernate 关联时不生成外键
为什么不生成外键?
1、处理表数据时麻烦,当然这个不是重点
2、分表分库的时候没办法做,这个才是问题所在
做法:
1、注解方式:
@ManyToOne//或者其他关系
@JoinColumn(
name = "some_fk",
foreignKey = @ForeignKey(name = "none",value = ConstraintMode.NO_CONSTRAINT)
)//注意这里的@ForeignKey是javax.persistence包中类,不要使用org.hibernate的
注意:
1.当两边都有关联关系字段,1的这端利用@org.hibernate.annotations.ForeignKey(name = “none”),多的那端在JoinColumn中加上foreignKey = @ForeignKey(name = “none”,value = ConstraintMode.NO_CONSTRAINT)
2.当只有多的那端有关联字段,一的那段没有关联字段或者关联字段被@Transient所修饰,请在多的那端在JoinColumn中加上foreignKey = @ForeignKey(name = “none”,value = ConstraintMode.NO_CONSTRAINT)
最后需要说明的是@org.hibernate.annotations.ForeignKey(name = “none”)这个注解之后可能会在之后的版本会被直接移除掉,所以更新jar包的时候需要注意下。
2、修改dialect
因为Hibernate为了处理不同数据库SQL的差异,为每个数据库定义了dialect,在执行SQL时会由dialect类的方法中获取相应的SQL,所以可以通过重写dialect类中生成外键SQL的方法不生成数据库外键关联。分别重写的Postgresql数据库和Oracle数据库的Dialect类如下:
创建了重写的Dialect类,通过hibernate.dialect=Oracle10gDialectWithoutFK配置后,在生成数据库表时外键策略就会生效。
PostgreSQL
import org.hibernate.dialect.PostgreSQL9Dialect;
/**
* 不生成外键,通过类似于SQL注入的方法,为每个数据库修改创建外键的SQL
*/
public class PostgreSQL9DialectWithoutFK extends PostgreSQL9Dialect {
@Override
public String getAddForeignKeyConstraintString(
String constraintName,
String[] foreignKey,
String referencedTable,
String[] primaryKey,
boolean referencesPrimaryKey) {
// 设置foreignkey对应的列值可以为空
return " alter "+ foreignKey[0] +" set default null " ;
}
}
Oracle
import org.hibernate.dialect.Oracle10gDialect; /** * 不生成外键,通过类似于SQL注入的方法,为每个数据库修改创建外键的SQL */ public class Oracle10gDialectWithoutFK extends Oracle10gDialect { @Override public String getAddForeignKeyConstraintString( String constraintName, String[] foreignKey, String referencedTable, String[] primaryKey, boolean referencesPrimaryKey) { // 通过修改外键列的默认值,而不是添加外键,避免生成外键 return " modify "+ foreignKey[0] +" default null " ; } }