zoukankan      html  css  js  c++  java
  • JPA(五):映射关联关系------映射单向多对一的关联关系

    映射单向多对一的关联关系

    新建Customer.java:

    package com.dx.jpa.singlemanytoone;
    
    import java.util.Date;
    
    import javax.persistence.Column;
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.Table;
    import javax.persistence.Temporal;
    import javax.persistence.TemporalType;
    import javax.persistence.Transient;
    
    @Entity
    @Table(name = "jpa_customer")
    public class Customer {
        private Integer id;
        private String fullName;
        private Integer age;
        private Date birth;
        private Date createDate;
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        @Column(name = "FULL_NAME", length = 64, nullable = false)
        public String getFullName() {
            return fullName;
        }
    
        public void setFullName(String fullName) {
            this.fullName = fullName;
        }
    
        public Integer getAge() {
            return age;
        }
    
        public void setAge(Integer age) {
            this.age = age;
        }
    
        @Temporal(TemporalType.DATE)
        public Date getBirth() {
            return birth;
        }
    
        public void setBirth(Date birth) {
            this.birth = birth;
        }
    
        @Temporal(TemporalType.TIMESTAMP)
        public Date getCreateDate() {
            return createDate;
        }
    
        public void setCreateDate(Date createDate) {
            this.createDate = createDate;
        }
    
        // 帮助方法,不希望保存到数据库,但是需要动态获取Customer对象的属性。
        @Transient
        public String getCustomerInfo() {
            return "username:" + fullName + ",age:" + age;
        }
    }
    View Code

    Order.java:

    package com.dx.jpa.singlemanytoone;
    
    import javax.persistence.Entity;
    import javax.persistence.GeneratedValue;
    import javax.persistence.GenerationType;
    import javax.persistence.Id;
    import javax.persistence.JoinColumn;
    import javax.persistence.ManyToOne;
    import javax.persistence.Table;
    
    @Entity
    @Table(name = "jpa_order")
    public class Order {
        private Integer id;
        private String name;
        private Customer customer;
    
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        public Integer getId() {
            return id;
        }
    
        public void setId(Integer id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        // @JoinColumn来映射外键
        // @ManyToOne映射单项一对多映射关系
        @JoinColumn(name = "CUSTOMER_ID")
        @ManyToOne()
        public Customer getCustomer() {
            return customer;
        }
    
        public void setCustomer(Customer customer) {
            this.customer = customer;
        }
    
    }

    Client.java测试类:

    package com.dx.jpa.singlemanytoone;
    
    import java.util.Date;
    
    import javax.persistence.EntityManager;
    import javax.persistence.EntityManagerFactory;
    import javax.persistence.EntityTransaction;
    import javax.persistence.Persistence;
    
    import org.hamcrest.CustomTypeSafeMatcher;
    import org.junit.After;
    import org.junit.Before;
    import org.junit.Test;
    
    public class Client {
        private String persistenceUnitName = "Jpa-helloword";
        private EntityManagerFactory entityManagerFactory = null;
        private EntityManager entityManager = null;
        private EntityTransaction entityTransaction = null;
    
        @Before
        public void init() {
            // 1.创建EntityManagerFactory
            entityManagerFactory = Persistence.createEntityManagerFactory(persistenceUnitName);
            // 2.创建EntityManager
            entityManager = entityManagerFactory.createEntityManager();
            // 3.开始事务
            entityTransaction = entityManager.getTransaction();
            entityTransaction.begin();
        }
    
        @After
        public void destory() {
            // 5.提交事务
            entityTransaction.commit();
    
            // 6.关闭EntityManager
            entityManager.close();
            // 7.关闭EnityManagerFactory
            entityManagerFactory.close();
        }
    }
    View Code

    将Customer,Person添加到jpa配置文件persistence.xml中:

    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="2.0"
        xmlns="http://java.sun.com/xml/ns/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">
        <persistence-unit name="Jpa-helloword"
            transaction-type="RESOURCE_LOCAL">
            <!-- 配置使用什么 ORM 产品来作为 JPA 的实现 -->
            <provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
            <!-- 添加持久化类 -->
            <class>com.dxsoft.jpa.helloword.Person</class>
            <class>com.dx.jpa.singlemanytoone.Customer</class>
            <class>com.dx.jpa.singlemanytoone.Order</class>
            <properties>
                <!-- 数据库的相关配置 -->
                <property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
                <property name="javax.persistence.jdbc.url" value="jdbc:mysql://127.0.0.1:3306/jpa" />
                <property name="javax.persistence.jdbc.user" value="root" />
                <property name="javax.persistence.jdbc.password" value="root" />
                <!-- 指定方言 
                MySQL                org.hibernate.dialect.MySQLDialect
                MySQL with InnoDB    org.hibernate.dialect.MySQLInnoDBDialect
                MySQL with MyISAM    org.hibernate.dialect.MySQLMyISAMDialect
                MySQL5                org.hibernate.dialect.MySQL5Dialect
                MySQL5 with InnoDB    org.hibernate.dialect.MySQL5InnoDBDialect
                -->
                <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5InnoDBDialect" />
                <property name="hibernate.show_sql" value="true" />
                <property name="hibernate.format_sql" value="true" />
                <!-- 
                create:每次加载hibernate时都会删除上一次的生成的表,然后根据你的model类再重新来生成新表,哪怕两次没有任何改变也要这样执行,这就是导致数据库表数据丢失的一个重要原因。<br>
                create-drop :每次加载hibernate时根据model类生成表,但是sessionFactory一关闭,表就自动删除。<br>
                update:最常用的属性,第一次加载hibernate时根据model类会自动建立起表的结构(前提是先建立好数据库),以后加载hibernate时根据 model类自动更新表结构,即使表结构改变了但表中的行仍然存在不会删除以前的行。要注意的是当部署到服务器后,表结构是不会被马上建立起来的,是要等 应用第一次运行起来后才会。<br>
                validate :每次加载hibernate时,验证创建数据库表结构,只会和数据库中的表进行比较,不会创建新表,但是会插入新值。 <br> 
                -->
                <property name="hibernate.hbm2ddl.auto" value="update" />            
            </properties>
        </persistence-unit>
    </persistence>
    View Code

    执行初始化时,创建表打印语句如下:

    Hibernate: 
        
        create table jpa_customer (
           id integer not null,
            age integer,
            birth date,
            createDate datetime,
            FULL_NAME varchar(64) not null,
            primary key (id)
        ) engine=InnoDB
    Hibernate: 
        
        create table jpa_order (
           id integer not null,
            name varchar(255),
            CUSTOMER_ID integer,
            primary key (id)
        ) engine=InnoDB
    Hibernate: 
        
        alter table jpa_order 
           add constraint FK7glkngwj74nr8h2amofkp1fjd 
           foreign key (CUSTOMER_ID) 
           references jpa_customer (id)

    此时查看表,发现jpa_order表上新建了外键:

    测试添加:

    添加测试函数:

        @Test
        public void testPersist() {
            Customer customer = new Customer();
            customer.setFullName("AA");
            customer.setAge(26);
            customer.setBirth(new Date());
            customer.setCreateDate(new Date());
    
            Order order1 = new Order();
            order1.setName("O-AA-01");
            order1.setCustomer(customer);
    
            Order order2 = new Order();
            order2.setName("O-AA-02");
            order2.setCustomer(customer);
    
            entityManager.persist(customer);
            entityManager.persist(order1);
            entityManager.persist(order2);
        }

    此时打印语句为:

    Hibernate: 
        select
            next_val as id_val 
        from
            hibernate_sequence for update
                
    Hibernate: 
        update
            hibernate_sequence 
        set
            next_val= ? 
        where
            next_val=?
    Hibernate: 
        select
            next_val as id_val 
        from
            hibernate_sequence for update
                
    Hibernate: 
        update
            hibernate_sequence 
        set
            next_val= ? 
        where
            next_val=?
    Hibernate: 
        select
            next_val as id_val 
        from
            hibernate_sequence for update
                
    Hibernate: 
        update
            hibernate_sequence 
        set
            next_val= ? 
        where
            next_val=?
    Hibernate: 
        insert 
        into
            jpa_customer
            (age, birth, createDate, FULL_NAME, id) 
        values
            (?, ?, ?, ?, ?)
    Hibernate: 
        insert 
        into
            jpa_order
            (CUSTOMER_ID, name, id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            jpa_order
            (CUSTOMER_ID, name, id) 
        values
            (?, ?, ?)
    View Code

    修改customer,order1,order2添加顺序:

        @Test
        public void testPersist() {
            Customer customer = new Customer();
            customer.setFullName("BB");
            customer.setAge(26);
            customer.setBirth(new Date());
            customer.setCreateDate(new Date());
    
            Order order1 = new Order();
            order1.setName("O-BB-01");
            order1.setCustomer(customer);
    
            Order order2 = new Order();
            order2.setName("O-BB-02");
            order2.setCustomer(customer);
    
            entityManager.persist(order1);
            entityManager.persist(order2);
            entityManager.persist(customer);
        }

    执行打印sql语句如下:

    Hibernate: 
        select
            next_val as id_val 
        from
            hibernate_sequence for update
                
    Hibernate: 
        update
            hibernate_sequence 
        set
            next_val= ? 
        where
            next_val=?
    Hibernate: 
        select
            next_val as id_val 
        from
            hibernate_sequence for update
                
    Hibernate: 
        update
            hibernate_sequence 
        set
            next_val= ? 
        where
            next_val=?
    Hibernate: 
        select
            next_val as id_val 
        from
            hibernate_sequence for update
                
    Hibernate: 
        update
            hibernate_sequence 
        set
            next_val= ? 
        where
            next_val=?
    Hibernate: 
        insert 
        into
            jpa_order
            (CUSTOMER_ID, name, id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            jpa_order
            (CUSTOMER_ID, name, id) 
        values
            (?, ?, ?)
    Hibernate: 
        insert 
        into
            jpa_customer
            (age, birth, createDate, FULL_NAME, id) 
        values
            (?, ?, ?, ?, ?)
    Hibernate: 
        update
            jpa_order 
        set
            CUSTOMER_ID=?,
            name=? 
        where
            id=?
    Hibernate: 
        update
            jpa_order 
        set
            CUSTOMER_ID=?,
            name=? 
        where
            id=?
    View Code

    从打印信息中可以看出,此时是先插入的order,之后在修改其customer_id。比起之前的那种写法多出来了两次修改。

    测试查询:

    添加测试查询函数:

        @Test
        public void testSelect() {
            Order order = entityManager.find(Order.class, 3);
            System.out.println(order.getName());
            //System.out.println(order.getCustomer().getFullName());
        }

    此时执行打印sql语句为:

    Hibernate: 
        select
            order0_.id as id1_1_0_,
            order0_.CUSTOMER_ID as CUSTOMER3_1_0_,
            order0_.name as name2_1_0_,
            customer1_.id as id1_0_1_,
            customer1_.age as age2_0_1_,
            customer1_.birth as birth3_0_1_,
            customer1_.createDate as createDa4_0_1_,
            customer1_.FULL_NAME as FULL_NAM5_0_1_ 
        from
            jpa_order order0_ 
        left outer join
            jpa_customer customer1_ 
                on order0_.CUSTOMER_ID=customer1_.id 
        where
            order0_.id=?

    从sql语句可以看出即使不插叙customer信息,也会使用left outer join把customer信息给关联出来。

    修改Order的getCustomer方法的属性:

    修改Order属性为:

    重新测试查询:

        @Test
        public void testSelect() {
            Order order = entityManager.find(Order.class, 2);
            System.out.println("------------------------");
            System.out.println(order.getName());
            System.out.println("------------------------");
            System.out.println(order.getCustomer().getFullName());
            System.out.println("------------------------");
        }

    打印sql语句为:

    Hibernate: 
        select
            order0_.id as id1_1_0_,
            order0_.CUSTOMER_ID as CUSTOMER3_1_0_,
            order0_.name as name2_1_0_ 
        from
            jpa_order order0_ 
        where
            order0_.id=?
    ------------------------
    O-BB-02
    ------------------------
    Hibernate: 
        select
            customer0_.id as id1_0_0_,
            customer0_.age as age2_0_0_,
            customer0_.birth as birth3_0_0_,
            customer0_.createDate as createDa4_0_0_,
            customer0_.FULL_NAME as FULL_NAM5_0_0_ 
        from
            jpa_customer customer0_ 
        where
            customer0_.id=?
    BB
    ------------------------

    查询修改:

    添加修改测试:

        @Test
        public void testUpdate() {
            Order order = entityManager.find(Order.class, 1);
            order.setName("O-BBB-01");
            order.getCustomer().setFullName("BBB");
        }

    打印执行sql:

    Hibernate: 
        select
            order0_.id as id1_1_0_,
            order0_.CUSTOMER_ID as CUSTOMER3_1_0_,
            order0_.name as name2_1_0_ 
        from
            jpa_order order0_ 
        where
            order0_.id=?
    Hibernate: 
        select
            customer0_.id as id1_0_0_,
            customer0_.age as age2_0_0_,
            customer0_.birth as birth3_0_0_,
            customer0_.createDate as createDa4_0_0_,
            customer0_.FULL_NAME as FULL_NAM5_0_0_ 
        from
            jpa_customer customer0_ 
        where
            customer0_.id=?
    Hibernate: 
        update
            jpa_order 
        set
            CUSTOMER_ID=?,
            name=? 
        where
            id=?
    Hibernate: 
        update
            jpa_customer 
        set
            age=?,
            birth=?,
            createDate=?,
            FULL_NAME=? 
        where
            id=?
    View Code

    查询删除:

    测试删除多的一端:

        @Test
        public void testRemove() {
            Order order = entityManager.find(Order.class, 1);
            entityManager.remove(order);        
        }
        

    执行打印语句:

    Hibernate: 
        select
            order0_.id as id1_1_0_,
            order0_.CUSTOMER_ID as CUSTOMER3_1_0_,
            order0_.name as name2_1_0_ 
        from
            jpa_order order0_ 
        where
            order0_.id=?
    Hibernate: 
        delete 
        from
            jpa_order 
        where
            id=?

    删除一的一端,此时其在多的一端还对应的有数据记录:

    执行测试函数:

        @Test
        public void testRemove() {
            Customer customer = entityManager.find(Customer.class, 3);
            entityManager.remove(customer);
        }

    提示删除失败:

    再次修改,将多一端的对应的数据也删除后,再次尝试删除:

        @Test
        public void testRemove() {
            Order order = entityManager.find(Order.class, 2);
            entityManager.remove(order);
    
            Customer customer = entityManager.find(Customer.class, 3);
            entityManager.remove(customer);
        }

    此时提示删除成功。 

  • 相关阅读:
    未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”
    未能正确加载“Microsoft.VisualStudio.Editor.Implementation.EditorPackage”包
    重装VS2010时出现未能正确加载 "radlangsvc.package,radlangsvc.vs...
    page.Response.WriteFile(newpath);
    Response.ContentType 详细列表 <转>
    创建存储过程,使用游标更新表信息
    淘宝顶端的通知样式 .
    ssm整合各配置文件
    XSS-Labs(Level1-10)
    局域网技术
  • 原文地址:https://www.cnblogs.com/yy3b2007com/p/9226213.html
Copyright © 2011-2022 走看看