Hibernate各种基本注解及一对一(多)关系映射采坑笔记
- hibernate提供两种方式配置关系映射,一种XMl配置,一种注解。SpringBoot已经自带了hibernate注解方式,我也是特别喜欢使用注解,特此记下常用的知识点。
1.基本注解
@Table(name = " ",catalog=" ", schema=" ")
//name表名,虽然可选,建议写上。catalog在MySql不支持,不必写。schema在MySql中指数据库名。
@Table(uniqueConstraints = {@UniqueConstraint(columnNames="name")})
或
@Column(name = "name",unique = true)
//指定建表时需要建唯一约束的列(使除主键外的列保持唯一约束)
@Embeddable
//表示一个非Entity类嵌入到一个Entity类作为属性而存在。
//使用方法,新建一个类注上该注解即可。在此类同样可使用注解对字段进行约束。
@embedded
//该注解是用来注释属性的,表示该类为嵌入类,同时,该类也得注释@Embeddable注解
@GeneratedValue(strategy=GenerationType)
GenerationType.AUTO //默认,根据底层数据库自动选择
GenerationType.INDENTITY //根据数据库的Identity字段生成
GenerationType.SEQUENCE //根据sequenqe来决定主键的取值
GenerationType.TABLE //使用指定表来决定主键取值,结合TableGenerator使用
@Id //自定义主键生成策略
@GeneratedValue(generator="sid") //名字
@GenericGenerator(name="sid",strategy="assigned") //策略
@EmbeddedId
//使用嵌入式主键类实现复合主键
//主键类必须实现Serializable接口,必须有默认的public无参构造方法,
//必须覆盖equals和hashCode()方法,必须注解@Embeddable
//使用时,把主键类对象当做参数传入Table类,对Table类进行保存即可。
@Transient
//表示该属性并非是到数据库表的字段的映射,否则默认注解@Basic
@Column(columnDefinition="TEXT", nullable=true)
//表示该字段为数据库中的TEXT类型,存储长文本
@ElementCollection(fetch = FetchType.LAZY)//定义基本类型或可嵌入类的实例集合 @OrderColumn(name="position")//如果使用的是List,你需要多定义一个字段维护集合顺序 private List<String> part;
关系映射注解@OneToOne(cascade = {CascadeType.ALL})
- CascadeType.PERSIST:级联新增(又称级联保存):对order对象保存时也对items里的对象也会保存。对应EntityManager的presist方法。
- CascadeType.MERGE:级联合并(级联更新):若items属性修改了那么order对象保存时同时修改items里的对象。对应EntityManager的merge方法 。
- CascadeType.REMOVE:级联删除:对order对象删除也对items里的对象也会删除。对应EntityManager的remove方法。
- CascadeType.REFRESH:级联刷新:获取order对象里也同时也重新获取最新的items时的对象。对应EntityManager的refresh(object)方法有效。即会重新查询数据库里的最新数据。
- CascadeType.ALL:以上四种都是。
2.级联保存异常
org.springframework.dao.InvalidDataAccessApiUsageException: detached entity passed to persist
解决方法:
在进行多对多(一)保存操作时,数据表定义主键为自增,但在执行插入前需设置ID为-1。有多个级联关系,每个对象都要进行设置。即可避免该异常。如下:
public void test() {
User user=new User();
user.setId(-1); //加上这一句即可!!!
user.setUsername("李彤");
user.setPassword("1144");
user.setRoles(roles);
}
级联查询异常
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of .... could not initialize proxy -
- 翻译过来就是Hibernate无法延迟加载,该异常多出现在一对多查询时,解决方法:
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)Lazy:延迟加载该关联对象,改为EAGER即可。
下面讲关系映射,务必牢记:
级联保存\删除时取决于Entity类中cascade = {xxx}注解。
若是cascade = {CascadeType.ALL},直接delete主表对象即可级联删除属性对象
3.一对一
(1)单向
@Entity
@Table(name="User")
public class User {
@Id
@GeneratedValue
@Column(name="sid")
private int sid;
@Column(name="name")
private String name;
@OneToOne(cascade = {CascadeType.ALL})
@JoinColumn(name = "pid",unique=true)
//name=定义外键在本表的字段名,若只配置本类,则为单向关联
//unique=true是指这个字段的值在这张表里不能重复,所有记录值都要唯一,就像主键那样
private Room room;
public User() {
super();
// 多对一
}
...
}
(2)双向
@Entity
@Table(name="Room")
public class Room {
@Id
@Column(name="cid")
private int cid;
@Column(name="addr")
private String addr;
@OneToOne(mappedBy="room")//被控方
//mappedBy同样指定由对方来进行维护关联关系
private User user;
public Room() {
super();
// 多对一
}
...
}
4.一对多单向
@Entity
@Table(name="Room")
public class Room {
@Id
@GeneratedValue
@Column(name="cid")
private int cid;
@Column(name="addr")
private String addr;
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY) //一对多为Lazy,多对一为Eager
@JoinColumn(name="cid") //name=定义外键在本表的字段名 rCN=关联外键对象的哪个字段
private Set<User> users;
public Room() {
super();
// 一对多:一方持有多方的引用
}
...
}
//正常建表
@Entity
@Table(name="User")
public class User {
@Id
@GeneratedValue
@Column(name="sid")
private int sid;
@Column(name="name")
private String name;
public User() {
super();
//一对多
}
...
}
5.多对一单向
@Entity
@Table(name="User")
public class User {
@Id
@GeneratedValue
@Column(name="sid")
private int sid;
@Column(name="name")
private String name;
@ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER) //一对多为Lazy,多对一为Eager
@JoinColumn(name="cid", referencedColumnName="cid") //name=定义外键在本表的字段名 rCN=关联外键对象的哪个字段
private Room room;
public User() {
super();
// 多对一
}
...
}
//正常建表
@Entity
@Table(name="Room")
public class Room {
@Id
@Column(name="cid")
private int cid;
@Column(name="addr")
private String addr;
public Room() {
super();
// 多对一
}
...
}
6.一对多(多对一)双向
@Entity
@Table(name="User")
public class User {
@Id
@GeneratedValue
@Column(name="sid")
private int sid;
@Column(name="name")
private String name;
@ManyToOne(cascade={CascadeType.ALL}, fetch=FetchType.EAGER) //一对多为Lazy,多对一为Eager
@JoinColumn(name="cid") //name=定义外键在本表的字段名
private Room room;
public User() {
super();
// 多对一
}
...
}
@Entity
@Table(name="Room")
public class Room {
@Id
@GeneratedValue
@Column(name="cid")
private int cid;
@Column(name="addr")
private String addr;
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY) //一对多为Lazy,多对一为Eager
@JoinColumn(name="cid") //name=定义外键在本表的字段名
private Set<User> users;
public Room() {
super();
// 一对多:一方持有多方的引用
}
...
}
7.多对多
(1)单向
@Entity
@Table(name="t_course")
public class Course
{
@Id
@GeneratedValue
private int id;
private String name;
@ManyToMany ---> ManyToMany指定多对多的关联关系
@JoinTable(name="t_teacher_course",
joinColumns={@JoinColumn(name="cid")},
inverseJoinColumns={ @JoinColumn(name = "tid") })
/*因为多对多之间会通过一张中间表来维护两表直接的关系,所以通过 JoinTable
这个注解来声明,我方是Course,所以在对方外键的名称就是 rid,
inverseJoinColumns也是一个 @JoinColumn类型的数组,
表示的是对方在我这放中的外键名称,对方是Teacher,所以在我方外键的名称就是 tid*/
private Set<Teacher> teachers;
...
}
(2)双向
@Entity
@Table(name="t_teacher")
public class Teacher
{
@Id
@GeneratedValue
private String name;
@ManyToMany(mappedBy="teachers")//表示由Course那一方来进行维护
private Set<Course> courses;
...
}
Hibernate各种基本注解及一对一(多)关系映射采坑笔记的更多相关文章
- Hibernate -- 注解(Annotation)关系映射
转自:http://www.cnblogs.com/tyler2000/archive/2011/01/20/1940354.html 1. Hibernate Annotation关系映射有下面几种 ...
- Java 自定义注解实现ORM对象关系映射
一,ORM概念 ORM即Object Relation Mapping,Object就是对象,Relation就是关系数据库,Mapping映射,就是说Java中的对象和关系数据库中的表存在一种对应关 ...
- Hibernate制图(两)——许多-于─关系映射
上篇学习了Hibernate的基本映射,也就是单表映射,非常easy就能理解,可是对于关系数据库来说,表之间存在关系是比不可少的.关系数据库中存在的关系是通过主外键建立起来的.反应到Hibernate ...
- Hibernate自身一对多和多对多关系映射
一对多关系映射大家都明白,关系双方都一个含有对方多个引用,但自身一对多很多同学都不明白什么意思,那么首先我就说明一下什么是自身一对多,其实也很好理解,自身一对多就是自身含有本身的多个引用,例如新闻类别 ...
- Mybatis 一对一(OneToOne)关系映射__INSERT
今天测试Ibatis的一对一的关联映射时总是出现错误,其中很多的错误都是自己不小心写错的..现把整个Ibatis源代码记录下来,以便以后熟记: 1.数据库脚本: CREATE TABLE t_pers ...
- 【Hibernate】---【注解】一对一
一.核心配置文件 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-con ...
- Hibernate之Annotation(注解的方式,非映射)
在hibernate 3.0之后,可以建立一个符合JPA标准的Annotation,以hibernate3.3.2GA为例 Annotation 以 hibernate Annotation 3.3. ...
- 笔记:Hibernate 持久化类标注示例-双向1-N关系映射
1-N关系的1端持久化类 package org.drsoft.hibernate.model.oneToMany; import java.util.Date; import java.ut ...
- hibernate多对多单向(双向)关系映射
n-n(多对多)的关联关系必须通过连接表实现.下面以商品种类和商品之间的关系,即一个商品种类下面可以有多种商品,一种商品又可以属于多个商品种类,分别介绍单向的n-n关联关系和双向的n-n关联关系. 单 ...
随机推荐
- 短连接、长连接与keep-alive
短连接与长连接 通俗来讲,浏览器和服务器每进行一次通信,就建立一次连接,任务结束就中断连接,即短连接.相反地,假如通信结束(如完成了某个HTML文件的信息获取)后保持连接则为长连接.在HTTP/1.0 ...
- spark大批量读取Hbase时出现java.lang.OutOfMemoryError: unable to create new native thread
这个问题我去网上搜索了一下,发现了很多的解决方案都是增加的nproc数量,即用户最大线程数的数量,但我修改了并没有解决问题,最终是通过修改hadoop集群的最大线程数解决问题的. 并且网络上的回答多数 ...
- 无公网IP的阿里云ESC服务器如何访问外部网络
新购买了3台阿里云ECS服务器(centos7)和弹性公网IP(EIP),虽然是从事计算机行业的人员但俺不是计算机网络从业人员
- BurpSuit2.0专业版破解
简介 Burp Suite 是用于攻击web 应用程序的集成平台.它包含了许多Burp工具,这些不同的burp工具通过协同工作,有效的分享信息,支持以某种工具中的信息为基础供另一种工具使用的方式发起攻 ...
- @Autowired注解与@resource注解的区别(十分详细)
背景: 今天下班路上看到一个大货车,于是想到了装配,然后脑海里跳出了一个注解@Autowired(自动装配),于是又想到最近工作项目用的都是@Resource注解来进行装配.于是本着学什么东西都要一钻 ...
- .net core系列之《.net core内置IOC容器ServiceCollection》
一.IOC介绍 IOC:全名(Inversion of Control)-控制反转 IOC意味着我们将对象的创建控制权交给了外部容器,我们不管它是如何创建的,我们只需要知道,当我们想要某个实例时,我们 ...
- IDEA: Call Hierarchy
在日常开发中,查看某个方法.字段可能被用在哪些地方.这个是个很常见的操作. 例如,在使用Eclipse时,选择方法后,右键菜单里选择 show call hierarchy,即可查看有哪些地方调用了这 ...
- Windows 版本说明,Enterprise、Ultimate、Home、Professional知多少
关于Windows 的安装光盘版本很多种,很多人不知道选择哪些. Ultimate 旗舰版,VISTA开始有了这个级别,是最全最高级的,一般程序开发的电脑,玩游戏的电脑,建议用它,不过对配置稍有一些要 ...
- 获取自定义data的几种属性
//获取data属性的几种方法 var id = this.getAttribute('data-id'); var id = $(this).attr('data-id'); var id = $( ...
- win32gui.Findwindow(parm1,parm2)查找窗口的句柄方法
介绍之前先让大家了解一下win32gui的模块用法 和 获取窗口类名工具 使用Python时,有时也会要操作到系统窗口的一些东西,下面就介绍win32gui.Findwindow(param1,par ...