EclipseLink学习(二)--- 一对一映射
来源:互联网 发布:淘宝联盟不能用红包吗 编辑:程序博客网 时间:2024/06/14 19:04
官网上给的例子是用的ApacheDerby进行的数据库操作,在这里咱们用mysql。
而且官网上的例子,onetomany,manytoone混着用,感觉如果纯看的话,得花费很多时间
去理解,所以这里咱们就一个一个单独讲解。
上篇文章简单介绍了:@Entity和@id以及@Column这些注解的使用。
这篇文章,我们就来讲解EclipseLink的映射关系之一-----oneToOne
其实一对一的关系,在数据库中的表示有很多种:
1、两个实体可以合成一个数据库;
2、可以是两个数据库表但是有外键关联。
3、也可以是两个数据库表,一个外键关系表。
下面咱们就来一一说明这三种情况怎么表示。
第一种,两个实体,但是对应一个数据库表
这种情况下用到了注解:@Embedded
在一个实体中,被标注上@Embedded的属性的实体,在形成数据库表的时候
是可以嵌入到这个实体表中的。
比如员工和家庭住址,是一对一的情况,我们把家庭住址实体放入到员工实体里面去,
就可以生成一个数据表。
员工实体如下:
package model;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="Employee")
public class Employee {
@Id
@Column(name="id")
private int id;
@Column(name="name")
private String name;
@Column(name="salary")
private long salary;
@Embedded
privateFamilyAddressfamilyAddress;
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 long getSalary() {
return salary;
}
public void setSalary(long salary) {
this.salary = salary;
}
public Address getFamilyAddress() {
returnfamilyAddress;
}
public void setFamilyAddress(FamilyAddressfamilyAddress) {
this.familyAddress=familyAddress;
}
}
地址实体如下:
package model;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public classFamilyAddress {
@Column(name="street")
private String street;
@Column(name="city")
private String city;
@Column(name="state")
private String state;
@Column(name="zip_code")
private String zip;
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
然后不要忘了修改xml文件中的运行类,不然会报错:“is not a known entity type”
如下:
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="EmployeeService" transaction-type="RESOURCE_LOCAL">
<!-- <class>model.PersonInformation</class> -->
<!-- <class>model.Person</class> -->
<class>model.Employee</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://192.168.81.129:3306/simpleDb" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
</properties>
</persistence-unit>
</persistence>
测试方法如下:
package main;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import model.FamilyAddress;
import model.Employee;
public class EmployeeTest {
private static final String PERSISTENCE_UNIT_NAME = "EmployeeService";
private static EntityManagerFactory factory;
public static void main(String[] args) {
factory = Persistence.createEntityManagerFactory(
PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
//保证事务
em.getTransaction().begin();
Employee employee =new Employee();
employee.setName("David");
employee.setSalary(26000);
Address address =new Address();
address.setCity("beijing");
address.setState("stand_by");
address.setStreet("hutong");
address.setZip("1523647");
employee.setFamilyAddress(familyAddress);
em.persist(employee);
em.getTransaction().commit();
em.close();
}
}
运行后的结果如下:
第二种:形成有外键关系的两个数据表
员工表实体
package model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name="Employee2")
public class Employee2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="name")
private String name;
@Column(name="salary")
private long salary;
@OneToOne(cascade=CascadeType.ALL)//cascade表示他们的级联关系
.保证测试类中的em.persist方法保存的是两个对象实体,而不是知识员工实体
//不用显式的保存地址实体
@JoinColumn(name="address_id")// @JoinColumn里面指定了Employee表里引
用到Address时关联的名字是什么
private FamilyAddress2 familyAddress2;
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 long getSalary() {
return salary;
}
public void setSalary(long salary) {
this.salary = salary;
}
public Address2 getAddress2() {
return address2;
}
public void setAddress2(Address2 address2) {
this.address2 = address2;
}
public Employee2() {}
public Employee2(int id) { this.id = id; }
}
地址表实体
package model;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name="FamilyAddress2")
public class FamilyAddress2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="street")
private String street;
@Column(name="city")
private String city;
@Column(name="state")
private String state;
@Column(name="zip_code")
private String zip;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getZip() {
return zip;
}
public void setZip(String zip) {
this.zip = zip;
}
}
同样不要忘了改xml,因为这次要创建两个表,所以得添加两个表的model到xml中。
xml的<class>的内容:需要创建的数据表的表对应的实体名
<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
<persistence-unit name="EmployeeService" transaction-type="RESOURCE_LOCAL">
<!-- <class>model.PersonInformation</class> -->
<!-- <class>model.Person</class> -->
<class>model.Employee2</class>
<class>model.FamilyAddress2</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:mysql://192.168.81.129:3306/simpleDb" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="root" />
<!-- EclipseLink should create the database schema automatically -->
<property name="eclipselink.ddl-generation" value="create-tables" />
<property name="eclipselink.ddl-generation.output-mode"
value="database" />
</properties>
</persistence-unit>
</persistence>
测试类,如下:
因为员工类中已经设置了@OneToOne(cascade=CascadeType.ALL)
所以,保存的时候不用写em.persist(familyAddress2 ),
只用写保存员工实体就可以了。
package main;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;
import model.FamilyAddress2 ;
import model.Employee2;
public class EmployeeTest {
private static final String PERSISTENCE_UNIT_NAME = "EmployeeService";
private static EntityManagerFactory factory;
public static void main(String[] args) {
factory = Persistence.createEntityManagerFactory(
PERSISTENCE_UNIT_NAME);
EntityManager em = factory.createEntityManager();
//保证事务
em.getTransaction().begin();
Employee2 employee2 =new Employee2();
employee2.setName("David");
employee2.setSalary(26000);
FamilyAddress2 address2 =new FamilyAddress2();
address2.setCity("beijing");
address2.setState("stand_by");
address2.setStreet("hutong");
address2.setZip("1523647");
employee2.setFamilyAddress2(address2);
em.persist(employee2);
em.getTransaction().commit();
em.close();
}
}
运行后的结果如下:
可以看出两个表的外键连接上了。
第三种,两个实体表生成两个数据表,外键独立一个表
此方法很简单,就把上面例子中的employee实体中的FamilyAddress属性上加上注解
@JoinTable和@OneToOne(cascade=CascadeType.ALL) 就可以了。
具体的employee实体如下:
package model;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.OneToOne;
import javax.persistence.Table;
@Entity
@Table(name="Employee2")
public class Employee2 {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="name")
private String name;
@Column(name="salary")
private long salary;
/*@OneToOne(cascade=CascadeType.ALL) //cascade表示他们的级联关系 .
保证测试类中的em.persist方法保存的是两个对象实体,而不是知识员工实体
//不用显式的保存地址实体
@JoinColumn(name="address_id")
// @JoinColumn里面指定了Employee表里引用到Address时关联的名字是什么*/
@OneToOne(cascade=CascadeType.ALL)
@JoinTable(name="employee_address",joinColumns=@JoinColumn(name="address_id"),
inverseJoinColumns=@JoinColumn(name="employee_id"))
//外键关系表,表名为employee_address,字段分别为address_id和employee_id
//如果不写joinColumns和inverseJoinColumns,默认生成的字段名是
//两个单独数据表的"表名_id"
private FamilyAddress2 familyAddress2;
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 long getSalary() {
return salary;
}
public void setSalary(long salary) {
this.salary = salary;
}
public FamilyAddress2 getFamilyAddress2() {
return familyAddress2;
}
public void setFamilyAddress2(FamilyAddress2 familyAddress2) {
this.familyAddress2 = familyAddress2;
}
public Employee2() {}
public Employee2(int id) { this.id = id; }
}
小总:
至此,讲到了几种注解:@Embedded和@OneToOne和@JoinColumn和@JoinTable。
- EclipseLink学习(二)--- 一对一映射
- EclipseLink学习(三)--- 一对多映射
- Hibernate 一对一映射(二)
- EclipseLink学习(四) --- 多对多映射
- 【HIbernate框架学习】:Hibernate对象关系映射之一对一关联映射(二)
- hibernnate映射关联 一对一关联(二)
- Hibernate一对一映射学习
- EclipseLink学习(五) --- 缓存
- 【SSH之旅】一步步学习Hibernate框架(二):一对一关联映射中的主键关联
- Hibernate 二 实体映射(一对一映射)
- EclipseLink的动态映射
- hibernate annotation (注解映射) 测试二 一对一 关联
- 【Hibernate步步为营】--双向关联一对一映射详解(二)
- 【Hibernate步步为营】--双向关联一对一映射详解(二)
- 【Hibernate步步为营】--双向关联一对一映射详解(二)
- hibernate进阶之路之一对一映射(二)
- hibernate中一对一映射配置详细解析(二)
- 【Hibernate】二、Hibernate映射详解(一对一单向关联)
- 临时替代Samba 完后直接操作服务器项目的工具sftpnetdrive
- kafka mac下载安装
- 设计模式----策略模式(推送的实现)
- SVG 贝塞尔曲线学习一
- BZOJ 4197([Noi2015]寿司晚宴-状压dp)
- EclipseLink学习(二)--- 一对一映射
- Map的keySet(),entrySet(),values()方法
- NFS架构下使用realpath_turbo优化php性能
- opengles中VBO和IBO结合使用
- 面向对象的基本概念
- Scala String.replaceALL() 替换 '\' 字符
- actor-critic框架
- UIScrollView和Button中手势冲突
- Compilation failed: internal java compiler error