zoukankan      html  css  js  c++  java
  • hibernate学习(二)

                              hibernate 单向一对多映射

    一.数据表设计

      数据库名:hibernate5

      数据表:  ①表名:CUSTOMERS            

            字段: CUSTOMER_ID

                CUSTOMER_NAME

                          ②表名:ORDERS

              字段:ORDER_ID

                ORDER_NUMBER

                CUSTOMER_ID(关联CUSTOMERS表的CUSTOMER_ID,构成单向一对多关系)

    二.建立数据表对应的持久化类

      1.Customers.java

        

     1 package com.hjj.hibernate.entities.n21;
     2 public class Customer {
     3     private Integer customerId;
     4     private String customerName;
     5     
     6     
     7     public Customer(String customerName) {
     8         super();
     9         this.customerName = customerName;
    10     }
    11     
    12     public Customer() {
    13         super();
    14     }
    15 
    16     public Integer getCustomerId() {
    17         return customerId;
    18     }
    19     public void setCustomerId(Integer customerId) {
    20         this.customerId = customerId;
    21     }
    22     public String getCustomerName() {
    23         return customerName;
    24     }
    25     public void setCustomerName(String customerName) {
    26         this.customerName = customerName;
    27     }
    28 
    29     @Override
    30     public String toString() {
    31         return "Customer [customerId=" + customerId + ", customerName=" + customerName + "]";
    32     }    
    33 }

      2.Orders.java

        

     1 package com.hjj.hibernate.entities.n21;
     2 public class Order {
     3     private Integer orderId;
     4     private Customer customer;
     5     private  Integer  orderNumber;
     6 
     7     public Order() {
     8     
     9     }
    10     public Order(Customer customer, Integer orderNumber) {
    11         super();
    12         this.customer = customer;
    13         this.orderNumber = orderNumber;
    14     }
    15     public Integer getOrderId() {
    16         return orderId;
    17     }
    18     public void setOrderId(Integer orderId) {
    19         this.orderId = orderId;
    20     }
    21     public Customer getCustomer() {
    22         return customer;
    23     }
    24     public void setCustomer(Customer customer) {
    25         this.customer = customer;
    26     }
    27     public Integer getOrderNumber() {
    28         return orderNumber;
    29     }
    30     public void setOrderNumber(Integer orderNumber) {
    31         this.orderNumber = orderNumber;
    32     }
    33     @Override
    34     public String toString() {
    35         return "Order [orderId=" + orderId + ", customer=" + customer + ", orderNumber=" + orderNumber + "]";
    36     }
    37         
    38 }

    三.添加对象关系映射文件

      1.Customer.hbm.xml

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <!-- Generated 2016-3-12 14:51:58 by Hibernate Tools 3.4.0.CR1 -->
     5 <hibernate-mapping>
     6     <class name="com.hjj.hibernate.entities.n21.Customer" table="CUSTOMERS">
     7         <id name="customerId" type="java.lang.Integer">
     8             <column name="CUSTOMER_ID" />
     9             <generator class="native" />
    10         </id>
    11         <property name="customerName" type="java.lang.String">
    12             <column name="CUSTOMER_NAME" />
    13         </property>
    14     </class>
    15 </hibernate-mapping>

      

      2. Order.hbm.xml

     1 <?xml version="1.0"?>
     2 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     3 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     4 <!-- Generated 2016-3-12 14:51:58 by Hibernate Tools 3.4.0.CR1 -->
     5 <hibernate-mapping>
     6     <class name="com.hjj.hibernate.entities.n21.Order" table="ORDERS">
     7         <id name="orderId" type="java.lang.Integer">
     8             <column name="ORDER_ID" />
     9             <generator class="native" />
    10         </id>
    11       
    12         <property name="orderNumber" type="java.lang.Integer">
    13             <column name="ORDER_NUMBER" />
    14         </property>
    15         
    16         <!--     name:属性名  所对应的 class:实体类                              -->
    17         <!-- name: 多这一端关联的 一 那一端的属性的名字
    18             class:一的那端的类名
    19             column:一的那端的数据表字段名
    20         
    21          -->
    22         <many-to-one name="customer" class="com.hjj.hibernate.entities.n21.Customer" >
    23             <column name="CUSTOMER_ID" />
    24         </many-to-one>
    25     </class>
    26 </hibernate-mapping>

    四.配置hibernate.cfg.xml文件,并且把三中的两个关系映射文件关联到到此配置文件中.  

     1 <?xml version="1.0" encoding="UTF-8"?>
     2 <!DOCTYPE hibernate-configuration PUBLIC
     3         "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
     4         "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
     5 <hibernate-configuration>
     6     <session-factory>
     7     <property name="connection.password">000000</property>
     8     <property name="connection.username">root</property>
     9     <property name="connection.url">jdbc:mysql:///hibernate5</property>
    10     <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
    11    
    12     <property name="dialect"> org.hibernate.dialect.MySQL5InnoDBDialect </property>
    13     <property name="hbm2ddl.auto">update</property>
    14     <property name="format_sql">true</property>
    15     <property name="show_sql">true</property>
    16   
    17     <!--  指定关联的 .hbm.xml  -->
    18     <mapping resource="com/hjj/hibernate/entities/n21/Customer.hbm.xml"/>
    19     <mapping resource="com/hjj/hibernate/entities/n21/Order.hbm.xml"/>
    20    
    21    
    22     </session-factory>
    23 </hibernate-configuration>

     五.编写访问数据库的代码(使用单元测试类)。

      1.关于注解@Test @After @Before

      @Test:

        @Test注解的public void方法将会被当做测试用例,JUnit每次都会创建一个新的测试实例,然后调用@Test注解方法

      @Arter:

        使用@After注解一个public void方法会使该方法在@Test注解方法执行后被执行

      @Before

        使用@Before注解一个public void 方法会使该方法在@Test注解方法被执行前执行

      2. @After和@Before所做的事

        

     1 package com.hjj.hibernate.entities.n21;
     2 import org.hibernate.Session;
     3 import org.hibernate.SessionFactory;
     4 import org.hibernate.Transaction;
     5 import org.hibernate.cfg.Configuration;
     6 import org.junit.After;
     7 import org.junit.Before;
     8 import org.junit.Test;
     9 
    10 public class HibernateTest {
    11     private Session session ;
    12     private SessionFactory sessionFactory ;
    13     private Transaction transaction;
    14     @Before
    15     public void init(){
    16         Configuration configuration = new Configuration().configure();
    17         sessionFactory = configuration.buildSessionFactory();
    18         session = sessionFactory.openSession();
    19         transaction = session.beginTransaction();
    20         
    21     }
    22     
    23     @After
    24     public void destory(){
    25         transaction.commit();
    26         session.close();
    27         sessionFactory.close();
    28     }
    29 }

      3.@Test测试用例之save操作

        ①第一种save方法:先save customers关联对象(即先save一端),在save多端。

     1        @Test
     2         public void testSave(){
     3             
     4             Customer customer = new Customer();
     5             customer.setCustomerName("BB");
     6             
     7             Order order1 = new Order();
     8             order1.setOrderNumber(11111);
     9             
    10             Order order2 = new Order();
    11             order2.setOrderNumber(22222);
    12             //设定关联关系
    13             order1.setCustomer(customer);
    14             order2.setCustomer(customer);
    15     
    16             session.save(customer);
    17             session.save(order1);
    18             session.save(order2);
    19             
    20         }           

        

      控制台发送三条insert语句

    Hibernate: 
        insert 
        into
            CUSTOMERS
            (CUSTOMER_NAME) 
        values
            (?)
    Hibernate: 
        insert 
        into
            ORDERS
            (ORDER_NUMBER, CUSTOMER_ID) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            ORDERS
            (ORDER_NUMBER, CUSTOMER_ID) 
        values
            (?, ?)

        ②。第二种save方法:先save order(即先save多端),在save一端。

      

        @Test
            public void testSave(){
                
                Customer customer = new Customer();
                customer.setCustomerName("BB");
                
                Order order1 = new Order();
                order1.setOrderNumber(11111);
                
                Order order2 = new Order();
                order2.setOrderNumber(22222);
                //设定关联关系
                order1.setCustomer(customer);
                order2.setCustomer(customer);
        
                //save操作:先插入多的一端 在插入一的一端
                
                session.save(order1);
                session.save(order2);
                session.save(customer);
                    
            }

       控制台会发送三条insert语句,两条update语句.

    Hibernate: 
        insert 
        into
            ORDERS
            (ORDER_NUMBER, CUSTOMER_ID) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            ORDERS
            (ORDER_NUMBER, CUSTOMER_ID) 
        values
            (?, ?)
    Hibernate: 
        insert 
        into
            CUSTOMERS
            (CUSTOMER_NAME) 
        values
            (?)
    Hibernate: 
        update
            ORDERS 
        set
            ORDER_NUMBER=?,
            CUSTOMER_ID=? 
        where
            ORDER_ID=?
    Hibernate: 
        update
            ORDERS 
        set
            ORDER_NUMBER=?,
            CUSTOMER_ID=? 
        where
            ORDER_ID=?

        ③两种save方法的比较,可以明显的出第二种效率不如第一种.因此应该使用第一种save方式

        ④以上两种操作数据库表为下:

          CUSTOMERS表

          

          

          ORDERS表

          

      4.@Test测试用例之get操作

        ①正常编写代码

      @Test
        public void testGet(){
                Order order = (Order) session.get(Order.class, 1);
                System.out.println(order.getOrderNumber());    
        }

        控制台:

    Hibernate:
    select
      order0_.ORDER_ID as ORDER_ID1_2_0_,
      order0_.ORDER_NUMBER as ORDER_NU2_2_0_,
      order0_.CUSTOMER_ID as CUSTOMER3_2_0_
    from
      ORDERS order0_
    where
      order0_.ORDER_ID=?


    order.getOrderNumber:11111

        可以看出来这里并没有去查询order关联的customer对象。

        ②.当使用到的关联对象  或者 关联对象 的属性的时候才会去查询

        

    1   @Test
    2     public void testGet(){
    3             Order order = (Order) session.get(Order.class, 1);
    4             System.out.println("order.getOrderNumber:"+order.getOrderNumber());
    5             Customer customer = order.getCustomer();
    6             System.out.println(customer);
    7     
    8     }

        

        控制台  

    Hibernate: 
        select
            order0_.ORDER_ID as ORDER_ID1_2_0_,
            order0_.ORDER_NUMBER as ORDER_NU2_2_0_,
            order0_.CUSTOMER_ID as CUSTOMER3_2_0_ 
        from
            ORDERS order0_ 
        where
            order0_.ORDER_ID=?
    order.getOrderNumber:11111
    Hibernate: 
        select
            customer0_.CUSTOMER_ID as CUSTOMER1_0_0_,
            customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_ 
        from
            CUSTOMERS customer0_ 
        where
            customer0_.CUSTOMER_ID=?
    Customer [customerId=1, customerName=AAAAA]

        

          ③对于关联对象hibernate采用的是懒加载:对于 关联的对象 得到的是代理对象

    1   @Test
    2     public void testGet(){
    3             Order order = (Order) session.get(Order.class, 1);
    4             System.out.println("order.getOrderNumber:"+order.getOrderNumber());
    5             System.out.println(order.getCustomer().getClass().getName());
    6             
    7     
    8     }

       控制台:

    Hibernate: 
        select
            order0_.ORDER_ID as ORDER_ID1_2_0_,
            order0_.ORDER_NUMBER as ORDER_NU2_2_0_,
            order0_.CUSTOMER_ID as CUSTOMER3_2_0_ 
        from
            ORDERS order0_ 
        where
            order0_.ORDER_ID=?
    com.hjj.hibernate.entities.n21.Customer_$$_jvst392_0   //代理对象

      5.@Test测试用例之update操作

    1 @Test
    2     public void testUpdate(){
    3             Order order = (Order) session.get(Order.class, 1);
    4             order.getCustomer().setCustomerName("AAAAA");
    5     
    6     }

      控制台打印sql语句且数据库表中字段的记录也会相应的改变:

    Hibernate: 
        select
            order0_.ORDER_ID as ORDER_ID1_2_0_,
            order0_.ORDER_NUMBER as ORDER_NU2_2_0_,
            order0_.CUSTOMER_ID as CUSTOMER3_2_0_ 
        from
            ORDERS order0_ 
        where
            order0_.ORDER_ID=?
        Hibernate: 
            select
                customer0_.CUSTOMER_ID as CUSTOMER1_0_0_,
                customer0_.CUSTOMER_NAME as CUSTOMER2_0_0_ 
            from
                CUSTOMERS customer0_ 
            where
                customer0_.CUSTOMER_ID=?
        Hibernate: 
            update
                CUSTOMERS 
            set
                CUSTOMER_NAME=? 
            where
                CUSTOMER_ID=?

      6..@Test测试用例之delete操作

      

    1   @Test
    2     public void testMany2OneDelete(){
    3             Customer customer = session.get(Customer.class,1);
    4             session.delete(customer);
    5     
    6     }

      这样是会抛出异常:org.hibernate.exception.ConstraintViolationException: could not execute statement

      因为有多端的对象对它还有引用。因此不能直接删除这个对象.

      

  • 相关阅读:
    jsp设置footer底部内容
    dashboard项目心得:
    深度和广度优先算法
    一个action读取另一个action里的session
    算法笔记-0302
    JAVA基础---面向对象
    Flutter 读写本地文件
    Dart 处理json,built_value库
    Flutter 页面入栈和出栈
    web项目如何使用Material Icons
  • 原文地址:https://www.cnblogs.com/HouJiao/p/5316565.html
Copyright © 2011-2022 走看看