-
}
-
AdminRole类:
-
@Entity
-
@Table(name=“t_admin_role”)
-
public class AdminRole
-
{
-
private int id;
-
private String name;
-
private Admin admin;
-
private Role role;
-
@Id
-
@GeneratedValue
-
public int getId()
-
{
-
return id;
-
}
-
public void setId(int id)
-
{
-
this.id = id;
-
}
-
public String getName()
-
{
-
return name;
-
}
-
public void setName(String name)
-
{
-
this.name = name;
-
}
-
@ManyToOne —> ManyToOne关联到Admin
-
@JoinColumn(name=“aid”)
-
public Admin getAdmin()
-
{
-
return admin;
-
}
-
public void setAdmin(Admin admin)
-
{
-
this.admin = admin;
-
}
-
@ManyToOne —>
-
@JoinColumn(name=“rid”)
-
public Role getRole()
-
{
-
return role;
-
}
-
public void setRole(Role role)
-
{
-
this.role = role;
-
}
-
}
-
小技巧:通过hibernate来进行插入操作的时候,不管是一对多、一对一还是多对多,都只需要记住一点,在哪个实体类声明了外键,就由哪个类来维护关系,在保存数据时,总是先保存的是没有维护关联关系的那一方的数据,后保存维护了关联关系的那一方的数据,如:
-
Person p = new Person();
-
p.setName(”xiaoluo”);
-
session.save§;
-
IDCard card = new IDCard();
-
card.setNo(”1111111111”);
-
card.setPerson§;
-
session.save(card);
2、Hibernate基于注解的双向one-to-many映射关系的实现
==================================================================================================
项目中用到了一对多的实体类关系映射,之前接触的都是基于配置文件的映射实现,但是公司的大部分都是基于注解的,因此自己参考之前的代码捣鼓了基于注解的一对多的映射关系实现。
背景:
一的一端:QingAoCenterInfo:青奥场所信息,
多的一端:QingAoPlaceInfo:青奥场馆信息,
其中一个青奥场所下可以包含多个青奥场馆
one端:QingAoCenterInfo,持有QingAoPlaceInfo的List引用,
通过注解@OneToMany(mappedBy=”qingAoCenterInfo”,cascade= CascadeType.ALL)
mappedBy:定义类之间的双向关系。如果类之间是单向关系,不需要提供定义,如果类和类之间形成双向关系,我们就需要使用这个属性进行定义, 否则可能引起数据一致性的问题。要由One的一方指向Many的一方,并且,这个属性应该等于Many的一方中含有One类的属性的属性名,否则会出错啦
cascade:CascadeType[]类型。该属性定义类和类之间的级联关系。
定义的级联关系将被容器视为对当前类对象及其关联类对象采取相同的操作,而且这种关系是递归调用的。
举个例子:Order 和OrderItem有级联关系,那么删除QingAoCenterInfo时将同时删除它所对应的QingAoPlaceInfo对象。而如果QingAoPlaceInfo还和其他的对象之间有级联关系,那么这样的操作会一直递归执行下去。
cascade的值只能从CascadeType.PERSIST(级联新建)、CascadeType.REMOVE(级联删除)、CascadeType.REFRESH(级联刷新)、CascadeType.MERGE(级联更新)中选择一个或多个。还有一个选择是使用CascadeType.ALL,表示选择全部四项。
[java] view plain copy
-
package com.yuqiaotech.nttelcom.model;
-
import java.util.Date;
-
import java.util.List;
-
import javax.persistence.CascadeType;
-
import javax.persistence.Entity;
-
import javax.persistence.GeneratedValue;
-
import javax.persistence.GenerationType;
-
import javax.persistence.Id;
-
import javax.persistence.OneToMany;
-
import javax.persistence.Table;
-
/**
-
* 青奥重点场所信息表。
-
*
-
*/
-
@Entity(name=“QING_AO_CENTER_INFO”)
-
@Table(name=“QING_AO_CENTER_INFO”)
-
public class QingAoCenterInfo {
-
private Long id;
-
private String centerName; //重点场所名称
-
private Long alarmNum; //告警数
-
private String note; //备注
-
private String iconName; //图标名称
-
private String cityName; //所在城市
-
private String type; //重点场所、活动保障
-
private Date createTime;
-
private List qingAoPlaceInfo; //场所拥有的场馆
-
@Id
-
@GeneratedValue(strategy=GenerationType.AUTO)
-
public Long getId() {
-
return id;
-
}
-
public void setId(Long id) {
-
this.id = id;
-
}
-
/**
-
* @searchItem
-
* displayType=”text”
-
*
-
* 重点场所名称
-
* @return
-
*/
-
public String getCenterName() {
-
return centerName;
-
}
-
public void setCenterName(String centerName) {
-
this.centerName = centerName;
-
}
-
/**
-
* 告警数
-
* @return
-
*/
-
public Long getAlarmNum() {
-
return alarmNum;
-
}
-
public void setAlarmNum(Long alarmNum) {
-
this.alarmNum = alarmNum;
-
}
-
/**
-
* 备注
-
* @return
-
*/
-
public String getNote() {
-
return note;
-
}
-
public void setNote(String note) {
-
this.note = note;
-
}
-
/**
-
* 图标名称
-
* @return
-
*/
-
public String getIconName() {
-
return iconName;
-
}
-
public void setIconName(String iconName) {
-
this.iconName = iconName;
-
}
-
public String getCityName() {
-
return cityName;
-
}
-
public void setCityName(String cityName) {
-
this.cityName = cityName;
-
}
-
public String getType() {
-
return type;
-
}
-
public void setType(String type) {
-
this.type = type;
-
}
-
public Date getCreateTime() {
-
return createTime;
-
}
-
public void setCreateTime(Date createTime) {
-
this.createTime = createTime;
-
}
-
@OneToMany(mappedBy=“qingAoCenterInfo”,cascade= CascadeType.ALL)
-
public List getQingAoPlaceInfo() {
-
return qingAoPlaceInfo;
-
}
-
public void setQingAoPlaceInfo(List qingAoPlaceInfo) {
-
this.qingAoPlaceInfo = qingAoPlaceInfo;
-
}
-
}
many端:QingAoPlaceInfo,持有QingAoCenterInfo的引用
通过@ManyToOne(fetch=FetchType.LAZY ) @JoinColumn(name=”f_center_id”)设置关联关系
@ManyToOne指明QingAoPlaceInfo和QingAoCenterInfo之间为多对一关系,多个QingAoPlaceInfo实例关联的都是同一个QingAoCenterInfo对象
fetch和lazy是用来定义级联查询的方式:
fetch:官方文档里对fetch有如下描述,Hibernate3 定义了如下几种抓取策略:
-
连接抓取(Join fetching):Hibernate 通过在
SELECT
语句使用OUTER JOIN
(外连接)来获得对象的关联实例或者关联集合。 -
批量抓取(Batch fetching):对查询抓取的优化方案,通过指定一个主键或外键列表,Hibernate 使用单条
SELECT
语句获取一批对象实例或集合。
[java] view plain copy
-
package com.yuqiaotech.nttelcom.model;
-
import java.util.Date;
-
import java.util.List;
-
import javax.persistence.CascadeType;
-
import javax.persistence.Entity;
-
import javax.persistence.FetchType;
-
import javax.persistence.GeneratedValue;
-
import javax.persistence.GenerationType;
-
import javax.persistence.Id;
-
import javax.persistence.JoinColumn;
-
import javax.persistence.ManyToOne;
-
import javax.persistence.OneToMany;
-
import javax.persistence.Table;
-
/**
-
* 场馆信息。
-
*
-
*/
-
@Entity(name=“QING_AO_PLACE_INFO”)
-
@Table(name=“QING_AO_PLACE_INFO”)
-
public class QingAoPlaceInfo {
-
private Long id;
-
private QingAoCenterInfo qingAoCenterInfo;// 重点场所id
-
private String placeName;// 场馆名称
-
private String note;// 备注
-
private String openStat;// 开通状态
-
private Long displayOrder;
-
private String cityName;
-
private Date createTime;
-
private List qingAoPlaceCdmaSector;//拥有的cdma
-
private List qingAoPlaceLteSector;//拥有的Lte
-
private List qingAoAp; //拥有的Ap
-
@Id
-
@GeneratedValue(strategy = GenerationType.AUTO)
-
public Long getId() {
-
return id;
-
}
-
public void setId(Long id) {
-
this.id = id;
-
}
-
@ManyToOne(fetch=FetchType.LAZY )
-
@JoinColumn(name=“f_center_id”)
-
public QingAoCenterInfo getQingAoCenterInfo() {
-
return qingAoCenterInfo;
-
}
-
public void setQingAoCenterInfo(QingAoCenterInfo qingAoCenterInfo) {
-
this.qingAoCenterInfo = qingAoCenterInfo;
-
}
-
/**
-
* @searchItem
-
* displayType=”text”
-
* 场所名称
-
* @return
-
*/
-
public String getPlaceName() {
-
return placeName;
-
}
-
public void setPlaceName(String placeName) {
-
this.placeName = placeName;
-
}
-
public String getNote() {
-
return note;
-
}
-
public void setNote(String note) {
-
this.note = note;
-
}
-
public String getOpenStat() {
-
return openStat;
-
}
-
public void setOpenStat(String openStat) {
-
this.openStat = openStat;
-
}
-
public Long getDisplayOrder() {
-
return displayOrder;
-
}
-
public void setDisplayOrder(Long displayOrder) {
-
this.displayOrder = displayOrder;
-
}
-
public String getCityName() {
-
return cityName;
-
}
-
public void setCityName(String cityName) {
-
this.cityName = cityName;
-
}
-
public Date getCreateTime() {
-
return createTime;
-
}
-
public void setCreateTime(Date createTime) {
-
this.createTime = createTime;
-
}
-
@OneToMany(mappedBy=“qingAoPlaceInfo”,cascade= CascadeType.ALL)
-
public List getQingAoPlaceCdmaSector() {
-
return qingAoPlaceCdmaSector;
-
}
-
public void setQingAoPlaceCdmaSector(
-
List qingAoPlaceCdmaSector) {
-
this.qingAoPlaceCdmaSector = qingAoPlaceCdmaSector;
-
}
-
@OneToMany(mappedBy=“qingAoPlaceInfo”,cascade= CascadeType.ALL)
-
public List getQingAoPlaceLteSector() {
-
return qingAoPlaceLteSector;
-
}
-
public void setQingAoPlaceLteSector(
-
List qingAoPlaceLteSector) {
-
this.qingAoPlaceLteSector = qingAoPlaceLteSector;
-
}
-
@OneToMany(mappedBy=“qingAoPlaceInfo”,cascade= CascadeType.ALL)
-
public List getQingAoAp() {
-
return qingAoAp;
-
}
-
public void setQingAoAp(List qingAoAp) {
-
this.qingAoAp = qingAoAp;
-
}
-
}
3、Hibernate4 注解版关系案例
=====================================================================================
公司用的maven 所以我也是建的maven工程,导入hibernate4的jar包
[html] view plain copy
-
<dependency>
-
<groupId>org.hibernate</groupId>
-
<artifactId>hibernate-core</artifactId>
-
<version>4.1.6.Final</version>
-
</dependency>
但是oracle的驱动包,好像要自己手动加。不知道有没有用maven直接从网上加的方法。
hibernate.cfg.xml 文件
[html] view plain copy
-
”-//Hibernate/Hibernate Configuration DTD 3.0//EN”
-
“http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd”>
-
<hibernate-configuration>
-
<session-factory>
-
<!– 数据库信息 –>
-
<property name=“dialect”>
-
org.hibernate.dialect.Oracle10gDialect
-
</property>
-
<property name=“connection.url”>jdbc:oracle:thin:@192.168.15.102:1521:ora11g</property>
-
<property name=“connection.driver_class”>oracle.jdbc.driver.OracleDriver</property>
-
<property name=“connection.username”>iris_ecnu_dev</property>
-
<property name=“connection.password”>iris_ecnu_dev</property>
-
<!– 其他配置 –>
-
<property name=“show_sql”>true</property>
-
<property name=“hbm2ddl.auto”>update</property>
-
<property name=“format_sql”>true</property>
-
<!– 导入映射配置 –>
-
<mapping class=“cn.lzg.Order” />
-
<mapping class=“cn.lzg.Person” />
-
</session-factory>
-
</hibernate-configuration>
Order.java 文件
[java] view plain copy
-
package cn.lzg;
-
import java.util.Date;
-
import javax.persistence.Column;
-
import javax.persistence.Entity;
-
import javax.persistence.FetchType;
-
import javax.persistence.GeneratedValue;
-
import javax.persistence.GenerationType;
-
import javax.persistence.Id;
-
import javax.persistence.JoinColumn;
-
import javax.persistence.ManyToOne;
-
import javax.persistence.SequenceGenerator;
-
import javax.persistence.Table;
-
@Entity
-
@Table(name = “order_lzg”)
-
public class Order {
-
@Id
-
@SequenceGenerator(name = “order_lzg”, sequenceName = “o_seq”, allocationSize = 1)
-
@GeneratedValue(generator = “order_lzg”, strategy = GenerationType.SEQUENCE)
-
private Long order_id;
-
@Column(name = “submit_time”)
-
private Date submit_time;
-
@ManyToOne(fetch = FetchType.LAZY)
-
@JoinColumn(name = “p_id”)
-
// order_lzg表 里面 放person_lzg ID的列
-
private Person person_lzg;
-
public Order() {
-
}
-
public Long getOrder_id() {
-
return order_id;
-
}
-
public void setOrder_id(Long order_id) {
-
this.order_id = order_id;
-
}
-
public Date getSubmit_time() {
-
return submit_time;
-
}
-
public void setSubmit_time(Date submit_time) {
-
this.submit_time = submit_time;
-
}
-
public Person getPerson_lzg() {
-
return person_lzg;
-
}
-
public void setPerson_lzg(Person person_lzg) {
-
this.person_lzg = person_lzg;
-
}
-
}
Person.java 文件
[java] view plain copy
-
package cn.lzg;
-
import java.util.HashSet;
-
import java.util.Set;
-
import javax.persistence.CascadeType;
-
import javax.persistence.Column;
-
import javax.persistence.Entity;
-
import javax.persistence.FetchType;
-
import javax.persistence.GeneratedValue;
-
import javax.persistence.GenerationType;
-
import javax.persistence.Id;
-
import javax.persistence.OneToMany;
-
import javax.persistence.SequenceGenerator;
-
import javax.persistence.Table;
-
@Entity
-
@Table(name = “person_lzg”)
-
public class Person {
-
@Id
-
@SequenceGenerator(name = “person_lzg”, sequenceName = “p_seq”, allocationSize = 1)
-
@GeneratedValue(generator = “person_lzg”, strategy = GenerationType.SEQUENCE)
-
private Long p_id;
-
@Column(name = “name”)
-
private String name;
-
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = “person_lzg”)
-
// mappedBy的值,是Order对象里面存Person对象的属性的值
-
private Set orderSet = new HashSet();
-
public Long getp_id() {
-
return p_id;
-
}
-
public void setp_id(Long p_id) {
-
this.p_id = p_id;
-
}
-
public String getName() {
-
return name;
-
}
-
public void setName(String name) {
-
this.name = name;
-
}
-
public Set getOrderSet() {
-
return orderSet;
-
}
-
public void setOrderSet(Set orderSet) {
-
this.orderSet = orderSet;
-
}
-
}
多对多
其实它的和 一对多 差不多,但是按照网上写法出现了一个问题,使得 双向的关系变成了单向的。
Person类
[java] view plain copy
-
package cn.lzg;
-
import java.util.ArrayList;
-
import java.util.List;
-
import javax.persistence.Column;
-
import javax.persistence.Entity;
-
import javax.persistence.FetchType;
-
import javax.persistence.GeneratedValue;
-
import javax.persistence.GenerationType;
-
import javax.persistence.Id;
-
import javax.persistence.JoinColumn;
-
import javax.persistence.JoinTable;
-
import javax.persistence.ManyToMany;
-
import javax.persistence.SequenceGenerator;
-
import javax.persistence.Table;
-
@Entity
-
@Table(name = “person_lzg”)
-
public class Person {
-
@Id
-
@SequenceGenerator(name = “person_lzg”, sequenceName = “p_seq”, allocationSize = 1)
-
@GeneratedValue(generator = “person_lzg”, strategy = GenerationType.SEQUENCE)
-
private Long p_id;
-
@Column(name = “name”)
-
private String name;
-
@ManyToMany(targetEntity = cn.lzg.Book.class, fetch = FetchType.LAZY)
-
@JoinTable(name = “lzgp_lzgb”, joinColumns = { @JoinColumn(name = “p_id”) }, inverseJoinColumns = { @JoinColumn(name = “b_id”) })
-
// name中间表的名字,第一个自己的主键,第二个关联的主键
-
private List books = new ArrayList();
-
public Long getP_id() {
-
return p_id;
-
}
-
public void setP_id(Long p_id) {
-
this.p_id = p_id;
-
}
-
public String getName() {
-
return name;
-
}
-
public void setName(String name) {
-
this.name = name;
-
}
-
public List getBooks() {
-
return books;
-
}
-
public void setBooks(List books) {
-
this.books = books;
-
}
-
}
Book类
[java] view plain copy
-
package cn.lzg;
-
import java.util.ArrayList;
-
import java.util.List;
-
import javax.persistence.Column;
-
import javax.persistence.Entity;
-
import javax.persistence.FetchType;
-
import javax.persistence.GeneratedValue;
-
import javax.persistence.GenerationType;
-
import javax.persistence.Id;
-
import javax.persistence.JoinColumn;
-
import javax.persistence.JoinTable;
-
import javax.persistence.ManyToMany;
-
import javax.persistence.SequenceGenerator;
-
import javax.persistence.Table;
-
@Entity
-
@Table(name = “book_lzg”)
-
public class Book {
-
@Id
-
@SequenceGenerator(name = “book_lzg”, sequenceName = “b_seq”, allocationSize = 1)
-
@GeneratedValue(generator = “book_lzg”, strategy = GenerationType.SEQUENCE)
-
private Long b_id;
-
@Column(name = “name”)
-
private String name;
-
@ManyToMany(targetEntity = cn.lzg.Person.class, fetch = FetchType.LAZY)
-
// 如果在上面使用mappedBy后,就成单向的了.也就是mappedBy出现的位置所在的类,这个类是被维护端,它只能被别人级联,不能去保存别人.
-
// 这个问题搞了好久才发现,开始一直是单向的.
-
@JoinTable(name = “lzgp_lzgb”, joinColumns = { @JoinColumn(name = “b_id”) }, inverseJoinColumns = { @JoinColumn(name = “p_id”) })
-
private List persons = new ArrayList();
-
public Long getB_id() {
-
return b_id;
-
}
-
public void setB_id(Long b_id) {
-
this.b_id = b_id;
-
}
-
public String getName() {
-
return name;
-
}
-
public void setName(String name) {
-
this.name = name;
-
}
-
public List getPersons() {
-
return persons;
-
}
-
public void setPersons(List persons) {
-
this.persons = persons;
-
}
-
}
注意
[java] view plain copy
-
如果在上面ManyToMany注解中使用mappedBy,就成单向的了.因为mappedBy出现的位置所在的类,这个类是被维护端,它只能被别人级联,不能去保存别人
-
测试类
-
<pre name=”code” class=“java”>package cn.lzg;
-
import java.util.ArrayList;
-
import java.util.Date;
-
import java.util.List;
-
import org.hibernate.Session;
-
import org.hibernate.SessionFactory;
-
import org.hibernate.Transaction;
-
import org.hibernate.cfg.Configuration;
-
import org.hibernate.service.ServiceRegistry;
-
import org.hibernate.service.ServiceRegistryBuilder;
-
import org.junit.Test;
-
public class TestHibernate {
-
private static Configuration configuration = null;
-
private static SessionFactory sessionFactory = null;
-
private static ServiceRegistry serviceRegistry = null;
-
private static Session session = null;
-
static {
-
/**
-
* hibernate 4 貌失要这样获得sessionFactory 以前的configuration.buildSessionFactory();方法 过时了
-
*/
-
configuration = new Configuration().configure();
-
serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties())
-
.buildServiceRegistry();
-
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
-
session = sessionFactory.openSession();
-
}
-
@Test
-
// 测试manytomany
-
public void testM2M() {
-
Person p1 = new Person();
-
p1.setName(”张三”);
-
Person p2 = new Person();
-
p2.setName(”李四”);
-
Person p3 = new Person();
-
p3.setName(”王五”);
-
List persons = new ArrayList();
-
persons.add(p1);
-
persons.add(p2);
-
persons.add(p3);
-
Book b1 = new Book();
-
b1.setName(”书本1”);
-
Book b2 = new Book();
-
b2.setName(”书本2”);
-
Book b3 = new Book();
-
b3.setName(”书本3”);
-
List books = new ArrayList();
-
books.add(b1);
-
books.add(b2);
-
books.add(b3);
-
p1.setBooks(books);
-
b3.setPersons(persons);
-
Transaction tx = session.beginTransaction();
-
session.save(p1);
-
session.save(p2);
-
session.save(p3);
-
session.save(b1);
-
session.save(b2);
-
session.save(b3);
-
tx.commit();
-
session.close();
-
}
-
}
结果生成了中间表
[java] view plain copy
- lzgp_lzgb 里面的关系p1 有三本书, p1,p2,p3都有b3
最近在公司做一个小项目,框架的持久层我选用的是Hibernate annotation,用户和他收藏的网站的关系是多对多的关系,一个用户可以收藏多个他喜爱的网站;反过来,一个网站也可以被多个用户收藏。
因此在设计类的时候,我设计了一个Sysuser(用户)类和一个Website(网站)类。
在配置注解的时候,由于在用户和网站之前,用户是主控方,网站是被控方。所以我在Sysuser类的getWebsite()方法上加了下面一段内容进行注解。
[java] view plain copy
-
@ManyToMany(fetch=FetchType.EAGER,cascade={CascadeType.PERSIST,CascadeType.MERGE})
-
@JoinTable(name=“user_web”,joinColumns=@JoinColumn(name=“userid”),
-
inverseJoinColumns=@JoinColumn(name=“webid”))
-
public Set getWebsite() {
-
return website;
-
}
-
public void setWebsite(Set website) {
-
this.website = website;
-
}
其中@ManyToMany就不用说了,指明用户和网站之前是多对多的关系。这里需要说的是,在主控方的get那个set集合的方法上面需要再加上@JoinTable进行注解,其中name=”user_web”就是指在数据库中体现多对多关系的中间表是user_web,指定之后在首次运行项目的时候会在数据库中自动生成这个中间表,而且这个中间表不需要写个类去对应,可以通过这两个有多对多关系的类去维护第三章表的数据。joinColumns=@JoinColumn(name=”userid”)这句话的意思是是定义中间表与Sysuser这个类外键关系,中间表是通过userid这一列产生外键关联的,而inverseJoinColumns是中间表参考另一张的表的主键生成的列。
在Website类的getSysuser()方法上加了下面一段内容进行注解
[java] view plain copy
-
@ManyToMany(cascade={CascadeType.MERGE,CascadeType.PERSIST},mappedBy=“website”)
-
public Set getSysuser() {
-
return sysuser;
-
}
-
public void setSysuser(Set sysuser) {
-
this.sysuser = sysuser;
-
}
其中的@ManyToMany也不用说了,指明网站与用户之间是多对多的关系。需要说明的是在被控方,需要加上mappedBy,例如这里的mappedBy=”website”是产生关系的属性。
总结一下需要注意的几点:
1、只有OneToOne,OneToMany,ManyToMany上才有mappedBy属性,ManyToOne不存在该属性;
2、mappedBy标签一定是定义在the owned side(被控方,或者叫被拥有方),他指向the owning side(主控方,或者叫做拥有方);
3、mappedBy跟JoinColumn/JoinTable总是处于互斥的一方,可以理解为正是由于拥有方的关联被拥有方的字段存在,拥有方才拥有了被拥有方。mappedBy这方定义的JoinColumn/JoinTable总是失效的,不会建立对应的字段或者表。
Hibernate Annotation关系映射的几种类型映射用法及使用方法
====================================================================================================
[java] view plain copy
-
Hibernate Annotation关系映射的几种类型映射用法及使用方法(说明:以前实例的实体是user和role,主键分别是userid和roleid)
-
1)一对一外键关联映射(单向)
-
@OneToOne(cascade=CascadeType.ALL) //一对一外键关联,使用@OneToOne,并设置了级联操作
-
@JoinColumn(name=“userid”,unique=true) //@JoinColum设置了外键的名称为userid(数据库字段名),如果不设置,则默认为另一类的属性名+ _id。外键的值是唯一的(unique),不可重复,与另一类的主键一直
-
2)一对一外键关联映射(双向)
-
@OneToOne(mappedBy=“ role”,cascade=CascadeType.ALL) //一对一双向关联关系,使用@OneToOne。注意:需要加上mappedBy=”role”,如果不加上的话, role 也会生成一个外键(user_id),mappedby=”role”需要指向与他关联对象的一个属性,说明双向关联关系中,有且仅有一端是作为主体(owner)端存在的,主体端负责维护联接列,对于不需要维护这种关系的从表则通过mappedBy属性进行声明,mappedBy的值指向主体的关联属性
-
//规律:只有是双向关联关系,都加上mappedby,cascade=CascadeType.ALL级联
-
3)一对一主键关联映射(不重要)
-
在实际中很少用,使用注解@PrimaryKeyJoinColumn,意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML映射可以生成。Annotation注解一对一主键关联映,有些bug。不过没空去研究它。因为在实际开发中一对一很少用。在实际开发中我机会没有用过,主键关联就更少了
-
4)多对一关联映射
-
多端配置
-
@ManyToOne(targetEntity=role.class) //多对一注解@ManyToOne;targetEntity指定了关联对象
-
@JoinColumn(name=“userid”) //@JoinColumn(name=”userid”)指定生产的外键的字段名,默认是org_id
-
5)一对多关联映射(单向)
-
@OneToMany //一对多注解@OneToMany(单向),如果只写@OneToMany的话,hibernate会建一张中间表来维护他们之间的关系
-
@JoinColumn(name=“roleid”) //加上@JoinColumn(name=”roleid”),则不会建中间表,他会在多的一端加上外键roleid,来维护他们之间的关系
-
6)一对多关联映射(双向)
-
一端配置
-
@OneToMany(mappedBy=“role”) //一对多双向,在一的一端中设置mappedBy,说明多的一端为主导
-
@JoinColumn(name=“roleid”) //如果指定了外键字段名称,则多的一端也需要指定相同的字段名称
-
多端配置
-
@ManyToOne //一对多双向
-
@JoinColumn(name=“ roleid ”) //需要指定外键与一的一端给的外键名称一致,@JoinColumn(name=” roleid ”),也可以不指定,如果在多的一端不指定,则一的一端也不能指定,否则为生成两个外键
-
7)多对多关联映射(单向)
-
@ManyToMany //多对多映射:注解@ManyToMany(单向),默认情况下,hibernate会自动的创建一张中间表来维护多对多关系
-
默认中间表的名称 :user_role中间表,字段的名称user_id role_id,如果想更换表名和字段名称,注解如下:
-
@JoinTable(name=“t_u_r”,joinColumns={@JoinColumn(name=“u_id”)},inverseJoinColumns={@JoinColumn(name=“r_id”)})
-
8)多对多关联映射(双向)
-
user端
-
@ManyToMany //多对多映射:注解@ManyToMany(单向);默认情况下,hibernate会自动的创建一张中间表,来维护多对多关系;默认中间表的名称 :user_role中间表,字段的名称user_id role_id
-
如果想更换表名和字段名称,注解如下:
-
@JoinTable(name=“t_u_r”,joinColumns={@JoinColumn(name=“u_id”)},inverseJoinColumns={@JoinColumn(name=“r_id”)}) //@JoinTable(name=”t_u_r”),指定中间表的表名;joinColumns={@JoinColumn(name=”u_id”)},指定当前对象的外键;inverseJoinColumns={@JoinColumn(name=”r_id”)},指定关联对象的外键
-
role端
-
@ManyToMany(mappedBy=“role”) //多对多,双向关联映射
====================================================================================
在过去几年里,Hibernate不断发展,几乎成为Java数据库持久性的事实标准。它非常强大、灵活,而且具备了优异的性能。在本文中,我们将了解如何使用Java 5 注释来简化Hibernate代码,并使持久层的编码过程变得更为轻松。
传统上,Hibernate的配置依赖于外部 XML 文件:数据库映射被定义为一组 XML 映射文件,并且在启动时进行加载。
在最近发布的几个Hibernate版本中,出现了一种基于 Java 5 注释的更为巧妙的新方法。借助新的 Hibernate Annotation 库,即可一次性地分配所有旧映射文件——一切都会按照您的想法来定义——注释直接嵌入到您的Java 类中,并提供一种强大及灵活的方法来声明持久性映射。
即利用hibernate注解后,可不用定义持久化类对应的*.hbm.xml文件,直接以注解方式写入在持久化类中来实现。
Hibernate annotation使用了ejb JPA的注解,所以,下面安装配置hibernate annotation环境时,需要导入ejb的包。许多网上的资料都是jpa hibernate annotation方面的资料。
(2)
安装 Hibernate Annotation
第一步,
环境与jar包:
要使用 Hibernate Annotation,您至少需要具备 Hibernate 3.2和Java 5。可以从 Hibernate 站点下载 Hibernate 3.2 和 Hibernate Annotation库。除了标准的 Hibernate JAR 和依赖项之外,您还需要 Hibernate Annotations .jar 文件(hibernate-annotations.jar)、Java 持久性 API (lib/ejb3-persistence.jar)。
添加hibernate3.2.jar,hibernate-annotations-3.3.0.jar,hibernate-commons-annotations.jar和ejb3-persistence.jar 。这样就可以使用hibernate的annotation了。
如果您正在使用 Maven,只需要向 POM 文件添加相应的依赖项即可,如下所示:
…
org.hibernate
hibernate
3.2.1.ga
org.hibernate
hibernate-annotations
3.2.0.ga
javax.persistence
persistence-api
1.0
第二步,
获取 Hibernate 会话工厂。尽管无需惊天的修改,但这一工作与使用 Hibernate Annotations有所不同。您需要使用 AnnotationConfiguration 类来建立会话工厂:
sessionFactory = new AnnotationConfiguration().buildSessionFactory();
第三步,
尽管通常使用 元素来声明持久性类,您还是需要在 Hibernate 配置文件(通常是 hibernate.cfg.xml)中声明持久性类:
近期的许多 Java 项目都使用了轻量级的应用框架,例如 Spring。如果您正在使用 Spring 框架,可以使用
AnnotationSessionFactoryBean 类轻松建立一个基于注释的 Hibernate 会话工厂,如下所示:
<!– Hibernate session factory –>
<bean id=”sessionFactory”
class=”org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean”>
org.hibernate.dialect.DerbyDialect
create
…
com.onjava.modelplanes.domain.PlaneType
com.onjava.modelplanes.domain.ModelPlane
…
(3)
hibernate Annotation标签的使用:
[1]
1.带注释的持久性类也是普通 POJO,它们只是具备了持久性注释的普通 POJO 。
2.事实上,您既可以保持字段的持久性(注释写在成员变量之上),也可以保持属性(注释写在getter方法之上)的持久性。
3.常用的hibernate annotation标签如下:
@Entity –注释声明该类为持久类。将一个Javabean类声明为一个实体的数据库表映射类,最好实现序列化.此时,默认情况下,所有的类属性都为映射到数据表的持久性字段.若在类中,添加另外属性,而非映射来数据库的,要用下面的Transient来注解.
@Table(name= “promotion_info”) –持久性映射的表(表名=”promotion_info).@Table是类一级的注解,定义在@Entity下,为实体bean映射表,目录和schema的名字, 默认为实体bean的类名,不带包名.
@Id–注释可以表明哪种属性是该类中的独特标识符(即相当于数据表的主键)。
@GeneratedValue –定义自动增长的主键的生成策略.
@Transient –将忽略这些字段和属性,不用持久化到数据库.适用于,在当前的持久类中,某些属性不是用于映射到数据表,而是用于其它的业务逻辑需要,这时,须将这些属性进行transient的注解.否则系统会因映射不到数据表相应字段而出错.
@Temporal(TemporalType.TIMESTAMP)–声明时间格式
@Enumerated –声明枚举
@Version –声明添加对乐观锁定的支持
@OneToOne –可以建立实体bean之间的一对一的关联
@OneToMany –可以建立实体bean之间的一对多的关联
@ManyToOne –可以建立实体bean之间的多对一的关联
@ManyToMany –可以建立实体bean之间的多对多的关联
@Formula –一个SQL表达式,这种属性是只读的,不在数据库生成属性(可以使用sum、average、max等)
@OrderBy –Many端某个字段排序(List)
1.2
Hibernate 能够出色地自动生成主键。Hibernate/EBJ 3 注释也可以为主键的自动生成提供丰富的支持,允许实现各种策略。
其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法, JPA提供四种标准用法,由@GeneratedValue的源代码可以明显看出.
JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.
TABLE:使用一个特定的数据库表格来保存主键。
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
IDENTITY:主键由数据库自动生成(主要是自动增长型)
AUTO:主键由程序控制。
在指定主键时,如果不指定主键生成策略,默认为AUTO。
@Id
相当于
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
identity:
使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用)。
Oracle就要采用sequence了.
同时,也可采用uuid,native等其它策略.(相关用法,上网查询)
[2]
第一个持久性类
@Entity
@Table(name= “T_MODEL_PLANE”)
public class ModelPlane implements Serializable {
@Id
@Column(name= “PLANE_ID”)
@GeneratedValue(strategy=GenerationType.AUTO) //注解于属性中
/*
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
最后
分享一些系统的面试题,大家可以拿去刷一刷,准备面试涨薪。
这些面试题相对应的技术点:
- JVM
- MySQL
- Mybatis
- MongoDB
- Redis
- Spring
- Spring boot
- Spring cloud
- Kafka
- RabbitMQ
- Nginx
- …
大类就是:
- Java基础
- 数据结构与算法
- 并发编程
- 数据库
- 设计模式
- 微服务
- 消息中间件
1.2
Hibernate 能够出色地自动生成主键。Hibernate/EBJ 3 注释也可以为主键的自动生成提供丰富的支持,允许实现各种策略。
其生成规则由@GeneratedValue设定的.这里的@id和@GeneratedValue都是JPA的标准用法, JPA提供四种标准用法,由@GeneratedValue的源代码可以明显看出.
JPA提供的四种标准用法为TABLE,SEQUENCE,IDENTITY,AUTO.
TABLE:使用一个特定的数据库表格来保存主键。
SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持序列。
IDENTITY:主键由数据库自动生成(主要是自动增长型)
AUTO:主键由程序控制。
在指定主键时,如果不指定主键生成策略,默认为AUTO。
@Id
相当于
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
identity:
使用SQL Server 和 MySQL 的自增字段,这个方法不能放到 Oracle 中,Oracle 不支持自增字段,要设定sequence(MySQL 和 SQL Server 中很常用)。
Oracle就要采用sequence了.
同时,也可采用uuid,native等其它策略.(相关用法,上网查询)
[2]
第一个持久性类
@Entity
@Table(name= “T_MODEL_PLANE”)
public class ModelPlane implements Serializable {
@Id
@Column(name= “PLANE_ID”)
@GeneratedValue(strategy=GenerationType.AUTO) //注解于属性中
/*
小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数初中级Java工程师,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年最新Java开发全套学习资料》送给大家,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
[外链图片转存中…(img-3sDCKnl8-1710400268411)]
[外链图片转存中…(img-R58nKSo2-1710400268411)]
[外链图片转存中…(img-YZpEHliS-1710400268412)]
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频
如果你觉得这些内容对你有帮助,可以添加下面V无偿领取!(备注Java)
[外链图片转存中…(img-3vFv0F0g-1710400268412)]
最后
分享一些系统的面试题,大家可以拿去刷一刷,准备面试涨薪。
这些面试题相对应的技术点:
- JVM
- MySQL
- Mybatis
- MongoDB
- Redis
- Spring
- Spring boot
- Spring cloud
- Kafka
- RabbitMQ
- Nginx
- …
大类就是:
- Java基础
- 数据结构与算法
- 并发编程
- 数据库
- 设计模式
- 微服务
- 消息中间件
[外链图片转存中…(img-G1TLQmD5-1710400268412)]
[外链图片转存中…(img-Z0znPi4K-1710400268413)]
[外链图片转存中…(img-CnNPomL6-1710400268413)]
[外链图片转存中…(img-qtxiSm6R-1710400268413)]
[外链图片转存中…(img-eNpJOa32-1710400268413)]
[外链图片转存中…(img-9MrFX2uz-1710400268414)]
[外链图片转存中…(img-bJX0UOVS-1710400268414)]
[外链图片转存中…(img-gVlDRvzV-1710400268414)]
[外链图片转存中…(img-UchDvoaZ-1710400268415)]