-
Address对象必须定义为@Embededable
-
示例:
-
@Embeddable
-
public class Address {city,street,zip}
-
@Entity
-
public class User {
-
@Embedded
-
public Address getAddress() {
-
……….
-
}
-
}
=================================================================
===================================================================================
[java] view plain copy
-
在hibernate中,通常配置对象关系映射关系有两种,一种是基于xml的方式,另一种是基于annotation的注解方式,熟话说,萝卜青菜,可有所爱,每个人都有自己喜欢的配置方式,我在试了这两种方式以后,发现使用annotation的方式可以更简介,所以这里就简单记录下通过annotation来配置各种映射关系,在hibernate4以后已经将annotation的jar包集成进来了,如果使用hibernate3的版本就需要引入annotation的jar包。
-
一、单对象操作
-
@Entity —> 如果我们当前这个bean要设置成实体对象,就需要加上Entity这个注解
-
@Table(name=“t_user”) —-> 设置数据库的表名
-
public class User
-
{
-
private int id;
-
private String username;
-
private String password;
-
private Date born;
-
private Date registerDate;
-
@Column(name=“register_date”) —> Column中的name属性对应了数据库的该字段名字,里面还有其他属性,例如length,nullable等等
-
public Date getRegisterDate()
-
{
-
return registerDate;
-
}
-
public void setRegisterDate(Date registerDate)
-
{
-
this.registerDate = registerDate;
-
}
-
@Id —> 定义为数据库的主键ID (建议不要在属性上引入注解,因为属性是private的,如果引入注解会破坏其封装特性,所以建议在getter方法上加入注解)
-
@GeneratedValue —-> ID的生成策略为自动生成
-
public int getId()
-
{
-
return id;
-
}
-
public void setId(int id)
-
{
-
this.id = id;
-
}
-
…………
-
}
-
最后只需要在hibernate.cfg.xml文件里面将该实体类加进去即可:
-
<!– 基于annotation的配置 –>
-
<mapping class=“com.xiaoluo.bean.User”/>
-
<!– 基于hbm.xml配置文件 –>
-
这样我们就可以写测试类来进行我们的CRUD操作了。
-
二、一对多的映射(one-to-many)
-
这里我们定义了两个实体类,一个是ClassRoom,一个是Student,这两者是一对多的关联关系。
-
ClassRoom类:
-
@Entity
-
@Table(name=“t_classroom”)
-
public class ClassRoom
-
{
-
private int id;
-
private String className;
-
private Set students;
-
public ClassRoom()
-
{
-
students = new HashSet();
-
}
-
public void addStudent(Student student)
-
{
-
students.add(student);
-
}
-
@Id
-
@GeneratedValue
-
public int getId()
-
{
-
return id;
-
}
-
public void setId(int id)
-
{
-
this.id = id;
-
}
-
public String getClassName()
-
{
-
return className;
-
}
-
public void setClassName(String className)
-
{
-
this.className = className;
-
}
-
@OneToMany(mappedBy=“room”) —> OneToMany指定了一对多的关系,mappedBy=“room”指定了由多的那一方来维护关联关系,mappedBy指的是多的一方对1的这一方的依赖的属性,(注意:如果没有指定由谁来维护关联关系,则系统会给我们创建一张中间表)
-
@LazyCollection(LazyCollectionOption.EXTRA) —> LazyCollection属性设置成EXTRA指定了当如果查询数据的个数时候,只会发出一条 count(*)的语句,提高性能
-
public Set getStudents()
-
{
-
return students;
-
}
-
public void setStudents(Set students)
-
{
-
this.students = students;
-
}
-
}
-
Student类:
-
@Entity
-
@Table(name=“t_student”)
-
public class Student
-
{
-
private int id;
-
private String name;
-
private int age;
-
private ClassRoom room;
-
@ManyToOne(fetch=FetchType.LAZY) —> ManyToOne指定了多对一的关系,fetch=FetchType.LAZY属性表示在多的那一方通过延迟加载的方式加载对象(默认不是延迟加载)
-
@JoinColumn(name=“rid”) —> 通过 JoinColumn 的name属性指定了外键的名称 rid (注意:如果我们不通过JoinColum来指定外键的名称,系统会给我们声明一个名称)
-
public ClassRoom getRoom()
-
{
-
return room;
-
}
-
public void setRoom(ClassRoom room)
-
{
-
this.room = room;
-
}
-
@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;
-
}
-
public int getAge()
-
{
-
return age;
-
}
-
public void setAge(int age)
-
{
-
this.age = age;
-
}
-
}
-
三、一对一映射(One-to-One)
-
一对一关系这里定义了一个Person对象以及一个IDCard对象
-
Person类:
-
@Entity
-
@Table(name=“t_person”)
-
public class Person
-
{
-
private int id;
-
private String name;
-
private IDCard card;
-
@OneToOne(mappedBy=“person”) —> 指定了OneToOne的关联关系,mappedBy同样指定由对方来进行维护关联关系
-
public IDCard getCard()
-
{
-
return card;
-
}
-
public void setCard(IDCard card)
-
{
-
this.card = card;
-
}
-
@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;
-
}
-
}
-
IDCard类:
-
@Entity
-
@Table(name=“t_id_card”)
-
public class IDCard
-
{
-
private int id;
-
private String no;
-
private Person person;
-
@Id
-
@GeneratedValue
-
public int getId()
-
{
-
return id;
-
}
-
public void setId(int id)
-
{
-
this.id = id;
-
}
-
public String getNo()
-
{
-
return no;
-
}
-
public void setNo(String no)
-
{
-
this.no = no;
-
}
-
@OneToOne —> OnetoOne指定了一对一的关联关系,一对一中随便指定一方来维护映射关系,这里选择IDCard来进行维护
-
@JoinColumn(name=“pid”) —> 指定外键的名字 pid
-
public Person getPerson()
-
{
-
return person;
-
}
-
public void setPerson(Person person)
-
{
-
this.person = person;
-
}
-
}
-
注意:在判断到底是谁维护关联关系时,可以通过查看外键,哪个实体类定义了外键,哪个类就负责维护关联关系。
-
四、Many-to-Many映射(多对多映射关系)
-
多对多这里通常有两种处理方式,一种是通过建立一张中间表,然后由任一一个多的一方来维护关联关系,另一种就是将多对多拆分成两个一对多的关联关系
-
1.通过中间表由任一一个多的一方来维护关联关系
-
Teacher类:
-
@Entity
-
@Table(name=“t_teacher”)
-
public class Teacher
-
{
-
private int id;
-
private String name;
-
private Set courses;
-
public Teacher()
-
{
-
courses = new HashSet();
-
}
-
public void addCourse(Course course)
-
{
-
courses.add(course);
-
}
-
@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;
-
}
-
@ManyToMany(mappedBy=“teachers”) —> 表示由Course那一方来进行维护
-
public Set getCourses()
-
{
-
return courses;
-
}
-
public void setCourses(Set courses)
-
{
-
this.courses = courses;
-
}
-
}
-
Course类:
-
@Entity
-
@Table(name=“t_course”)
-
public class Course
-
{
-
private int id;
-
private String name;
-
private Set teachers;
-
public Course()
-
{
-
teachers = new HashSet();
-
}
-
public void addTeacher(Teacher teacher)
-
{
-
teachers.add(teacher);
-
}
-
@ManyToMany —> ManyToMany指定多对多的关联关系
-
@JoinTable(name=“t_teacher_course”, joinColumns={ @JoinColumn(name=“cid”)},
-
inverseJoinColumns={ @JoinColumn(name = “tid”) }) —> 因为多对多之间会通过一张中间表来维护两表直接的关系,所以通过 JoinTable 这个注解来声明,name就是指定了中间表的名字,JoinColumns是一个 @JoinColumn类型的数组,表示的是我这方在对方中的外键名称,我方是Course,所以在对方外键的名称就是 rid,inverseJoinColumns也是一个 @JoinColumn类型的数组,表示的是对方在我这放中的外键名称,对方是Teacher,所以在我方外键的名称就是 tid
-
public Set getTeachers()
-
{
-
return teachers;
-
}
-
public void setTeachers(Set teachers)
-
{
-
this.teachers = teachers;
-
}
-
@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;
-
}
-
}
-
2.将Many-to-Many拆分成两个One-to-Many的映射(Admin、Role、AdminRole)
-
Admin类:
-
@Entity
-
@Table(name=“t_admin”)
-
public class Admin
-
{
-
private int id;
-
private String name;
-
private Set ars;
-
public Admin()
-
{
-
ars = new HashSet();
-
}
-
public void add(AdminRole ar)
-
{
-
ars.add(ar);
-
}
-
@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;
-
}
-
@OneToMany(mappedBy=“admin”) —> OneToMany关联到了AdminRole这个类,由AdminRole这个类来维护多对一的关系,mappedBy=“admin”
-
@LazyCollection(LazyCollectionOption.EXTRA)
-
public Set getArs()
-
{
-
return ars;
-
}
-
public void setArs(Set ars)
-
{
-
this.ars = ars;
-
}
-
}
-
Role类:
-
@Entity
-
@Table(name=“t_role”)
-
public class Role
-
{
-
private int id;
-
private String name;
-
private Set ars;
-
public Role()
-
{
-
ars = new HashSet();
-
}
-
public void add(AdminRole ar)
-
{
-
ars.add(ar);
-
}
-
@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;
-
}
-
@OneToMany(mappedBy=“role”) —> OneToMany指定了由AdminRole这个类来维护多对一的关联关系,mappedBy=“role”
-
@LazyCollection(LazyCollectionOption.EXTRA)
-
public Set getArs()
-
{
-
return ars;
-
}
-
public void setArs(Set ars)
-
{
-
this.ars = ars;
-
}
-
}
-
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.persistenc
必看视频!获取2024年最新Java开发全套学习资料 备注Java
e.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
…
最后
小编在这里分享些我自己平时的学习资料,由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
程序员代码面试指南 IT名企算法与数据结构题目最优解
这是” 本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现。针对当前程序员面试缺乏权威题目汇总这一-痛点, 本书选取将近200道真实出现过的经典代码面试题,帮助广“大程序员的面试准备做到万无一失。 “刷”完本书后,你就是“题王”!
《TCP-IP协议组(第4版)》
本书是介绍TCP/IP协议族的经典图书的最新版本。本书自第1版出版以来,就广受读者欢迎。
本书最新版进行」护元,以体境计算机网络技不的最新发展,全书古有七大部分共30草和7个附录:第一部分介绍一些基本概念和基础底层技术:第二部分介绍网络层协议:第三部分介绍运输层协议;第四部分介绍应用层协议:第五部分介绍下一代协议,即IPv6协议:第六部分介绍网络安全问题:第七部分给出了7个附录。
Java开发手册(嵩山版)
这个不用多说了,阿里的开发手册,每次更新我都会看,这是8月初最新更新的**(嵩山版)**
MySQL 8从入门到精通
本书主要内容包括MySQL的安装与配置、数据库的创建、数据表的创建、数据类型和运算符、MySQL 函数、查询数据、数据表的操作(插入、更新与删除数据)、索引、存储过程和函数、视图、触发器、用户管理、数据备份与还原、MySQL 日志、性能优化、MySQL Repl ication、MySQL Workbench、 MySQL Utilities、 MySQL Proxy、PHP操作MySQL数据库和PDO数据库抽象类库等。最后通过3个综合案例的数据库设计,进步讲述 MySQL在实际工作中的应用。
Spring5高级编程(第5版)
本书涵盖Spring 5的所有内容,如果想要充分利用这一领先的企业级 Java应用程序开发框架的强大功能,本书是最全面的Spring参考和实用指南。
本书第5版涵盖核心的Spring及其与其他领先的Java技术(比如Hibemate JPA 2.Tls、Thymeleaf和WebSocket)的集成。本书的重点是介绍如何使用Java配置类、lambda 表达式、Spring Boot以及反应式编程。同时,将与企业级应用程序开发人员分享一些见解和实际经验,包括远程处理、事务、Web 和表示层,等等。
JAVA核心知识点+1000道 互联网Java工程师面试题
企业IT架构转型之道 阿里巴巴中台战略思想与架构实战
本书讲述了阿里巴巴的技术发展史,同时也是-部互联网技 术架构的实践与发展史。
tory = 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
…
最后
小编在这里分享些我自己平时的学习资料,由于篇幅限制,pdf文档的详解资料太全面,细节内容实在太多啦,所以只把部分知识点截图出来粗略的介绍,每个小节点里面都有更细化的内容!
程序员代码面试指南 IT名企算法与数据结构题目最优解
这是” 本程序员面试宝典!书中对IT名企代码面试各类题目的最优解进行了总结,并提供了相关代码实现。针对当前程序员面试缺乏权威题目汇总这一-痛点, 本书选取将近200道真实出现过的经典代码面试题,帮助广“大程序员的面试准备做到万无一失。 “刷”完本书后,你就是“题王”!
[外链图片转存中…(img-FQiFzxHr-1716442308212)]
《TCP-IP协议组(第4版)》
本书是介绍TCP/IP协议族的经典图书的最新版本。本书自第1版出版以来,就广受读者欢迎。
本书最新版进行」护元,以体境计算机网络技不的最新发展,全书古有七大部分共30草和7个附录:第一部分介绍一些基本概念和基础底层技术:第二部分介绍网络层协议:第三部分介绍运输层协议;第四部分介绍应用层协议:第五部分介绍下一代协议,即IPv6协议:第六部分介绍网络安全问题:第七部分给出了7个附录。
[外链图片转存中…(img-nUgipoGi-1716442308212)]
Java开发手册(嵩山版)
这个不用多说了,阿里的开发手册,每次更新我都会看,这是8月初最新更新的**(嵩山版)**
[外链图片转存中…(img-NXG5Gi83-1716442308212)]
MySQL 8从入门到精通
本书主要内容包括MySQL的安装与配置、数据库的创建、数据表的创建、数据类型和运算符、MySQL 函数、查询数据、数据表的操作(插入、更新与删除数据)、索引、存储过程和函数、视图、触发器、用户管理、数据备份与还原、MySQL 日志、性能优化、MySQL Repl ication、MySQL Workbench、 MySQL Utilities、 MySQL Proxy、PHP操作MySQL数据库和PDO数据库抽象类库等。最后通过3个综合案例的数据库设计,进步讲述 MySQL在实际工作中的应用。
[外链图片转存中…(img-L1uVR9zr-1716442308213)]
Spring5高级编程(第5版)
本书涵盖Spring 5的所有内容,如果想要充分利用这一领先的企业级 Java应用程序开发框架的强大功能,本书是最全面的Spring参考和实用指南。
本书第5版涵盖核心的Spring及其与其他领先的Java技术(比如Hibemate JPA 2.Tls、Thymeleaf和WebSocket)的集成。本书的重点是介绍如何使用Java配置类、lambda 表达式、Spring Boot以及反应式编程。同时,将与企业级应用程序开发人员分享一些见解和实际经验,包括远程处理、事务、Web 和表示层,等等。
[外链图片转存中…(img-tTeUgPpv-1716442308213)]
JAVA核心知识点+1000道 互联网Java工程师面试题
[外链图片转存中…(img-R2zLJpLH-1716442308213)]
[外链图片转存中…(img-bOc5oK3E-1716442308213)]
企业IT架构转型之道 阿里巴巴中台战略思想与架构实战
本书讲述了阿里巴巴的技术发展史,同时也是-部互联网技 术架构的实践与发展史。
[外链图片转存中…(img-Panf8Dyh-1716442308214)]