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_idemployee_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。

 

 

阅读全文
0 0
原创粉丝点击