hibernate 单向一对多映射

一.数据表设计

  数据库名:hibernate5

  数据表:  ①表名:CUSTOMERS

        字段: CUSTOMER_ID

            CUSTOMER_NAME

②表名:ORDERS

          字段:ORDER_ID

            ORDER_NUMBER

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

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

  1.Customers.java

    

 package com.hjj.hibernate.entities.n21;
public class Customer {
private Integer customerId;
private String customerName; public Customer(String customerName) {
super();
this.customerName = customerName;
} public Customer() {
super();
} public Integer getCustomerId() {
return customerId;
}
public void setCustomerId(Integer customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
} @Override
public String toString() {
return "Customer [customerId=" + customerId + ", customerName=" + customerName + "]";
}
}

  2.Orders.java

    

 package com.hjj.hibernate.entities.n21;
public class Order {
private Integer orderId;
private Customer customer;
private Integer orderNumber; public Order() { }
public Order(Customer customer, Integer orderNumber) {
super();
this.customer = customer;
this.orderNumber = orderNumber;
}
public Integer getOrderId() {
return orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Integer getOrderNumber() {
return orderNumber;
}
public void setOrderNumber(Integer orderNumber) {
this.orderNumber = orderNumber;
}
@Override
public String toString() {
return "Order [orderId=" + orderId + ", customer=" + customer + ", orderNumber=" + orderNumber + "]";
} }

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

  1.Customer.hbm.xml

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

  

  2. Order.hbm.xml

 <?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2016-3-12 14:51:58 by Hibernate Tools 3.4.0.CR1 -->
<hibernate-mapping>
<class name="com.hjj.hibernate.entities.n21.Order" table="ORDERS">
<id name="orderId" type="java.lang.Integer">
<column name="ORDER_ID" />
<generator class="native" />
</id> <property name="orderNumber" type="java.lang.Integer">
<column name="ORDER_NUMBER" />
</property> <!-- name:属性名 所对应的 class:实体类 -->
<!-- name: 多这一端关联的 一 那一端的属性的名字
class:一的那端的类名
column:一的那端的数据表字段名 -->
<many-to-one name="customer" class="com.hjj.hibernate.entities.n21.Customer" >
<column name="CUSTOMER_ID" />
</many-to-one>
</class>
</hibernate-mapping>

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

 <?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.password">000000</property>
<property name="connection.username">root</property>
<property name="connection.url">jdbc:mysql:///hibernate5</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property> <property name="dialect"> org.hibernate.dialect.MySQL5InnoDBDialect </property>
<property name="hbm2ddl.auto">update</property>
<property name="format_sql">true</property>
<property name="show_sql">true</property> <!-- 指定关联的 .hbm.xml  -->
<mapping resource="com/hjj/hibernate/entities/n21/Customer.hbm.xml"/>
<mapping resource="com/hjj/hibernate/entities/n21/Order.hbm.xml"/> </session-factory>
</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所做的事

    

 package com.hjj.hibernate.entities.n21;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class HibernateTest {
private Session session ;
private SessionFactory sessionFactory ;
private Transaction transaction;
@Before
public void init(){
Configuration configuration = new Configuration().configure();
sessionFactory = configuration.buildSessionFactory();
session = sessionFactory.openSession();
transaction = session.beginTransaction(); } @After
public void destory(){
transaction.commit();
session.close();
sessionFactory.close();
}
}

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

    ①第一种save方法:先save customers关联对象(即先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); session.save(customer);
session.save(order1);
session.save(order2); }

    

  控制台发送三条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对象。

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

    

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

    

    控制台  

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采用的是懒加载:对于 关联的对象 得到的是代理对象

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

   控制台:

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操作

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

  控制台打印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
public void testMany2OneDelete(){
Customer customer = session.get(Customer.class,1);
session.delete(customer); }

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

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

  

hibernate学习(二)的更多相关文章

  1. Hibernate学习(二)关系映射----基于外键的单向一对一

    事实上,单向1-1与N-1的实质是相同的,1-1是N-1的特例,单向1-1与N-1的映射配置也非常相似.只需要将原来的many-to-one元素增加unique="true"属性, ...

  2. hibernate学习二(HelloWorld)

    一.建立hibernate配置文件 在工程Hibernate_01_HelloWorld下的src上建立hibernate.cfg.xml,打开hibernate-release-4.3.11.Fin ...

  3. hibernate学习二 基本用法

    一  映射文件User.hbm.xml 定义了持久化类实例是如何存储和加载的,这个文件定义了持久化类和表的映射. 根据映射文件,Hibernate可以生成足够的信息以产生所有的SQL语句,也就是类的实 ...

  4. Hibernate学习二----------hibernate简介

    © 版权声明:本文为博主原创文章,转载请注明出处 1.hibernate.cfg.xml常用配置 - hibernate.show_sql:是否把Hibernate运行时的SQL语句输出到控制台,编码 ...

  5. Hibernate学习(二补充)关系映射----基于外键的双向一对一

    刚刚写的是基于外键的单向一对一.  那么双向一对一就是在单向一对一的基础上稍微改动就可以了. account.java和account.hbm.xml都不用变动  只要我们小小的变动address.j ...

  6. Hibernate学习笔记(二)

    2016/4/22 23:19:44 Hibernate学习笔记(二) 1.1 Hibernate的持久化类状态 1.1.1 Hibernate的持久化类状态 持久化:就是一个实体类与数据库表建立了映 ...

  7. 我的hibernate学习记录(二)

    通过上一篇文章我的hibernate学习记录(一)基本上的入门了hibernate,但是,里面还有还多东西是通过迷迷糊糊的记忆,或者说copy直接弄进去的,所以这篇文章就需要对上篇的一些文件.对象进行 ...

  8. Hibernate学习之——搭建log4j日志环境

    昨天讲了Hibernate开发环境的搭建以及实现一个Hibernate的基础示例,但是你会发现运行输出只有sql语句,很多输出信息都看不见.这是因为用到的是slf4j-nop-1.6.1.jar的实现 ...

  9. Hibernate 学习教程

    第1课 课程内容. 6 第2课Hibernate UML图. 6 第3课 风格. 7 第4课 资源. 7 第5课 环境准备. 7 第6课 第一个演示样例HibernateHelloWorld 7 第7 ...

随机推荐

  1. 配置Jenkins的slave节点的详细步骤适合windows等其他平台(转)

    @  新建一个slave节点在Jenkins服务器上 1,进入Jenkins的主界面,进入“Manage Jenkins” 页面: 2,点击如下图中的“Manage  Nodes”: 3,进入页面后点 ...

  2. 设计模式(五)适配器模式Adapter(结构型)

      设计模式(五)适配器模式Adapter(结构型) 1. 概述: 接口的改变,是一个需要程序员们必须(虽然很不情愿)接受和处理的普遍问题.程序提供者们修改他们的代码;系统库被修正;各种程序语言以及相 ...

  3. ios9怎么设置6位密码 ios9设置6位密码图文教程

    在原来的 iOS 系统中,只有四位数字密码与复杂密码之分,而在 iOS9 系统中却多出了一个六位数字密码,那ios9怎么设置6位密码,今天小编就为大家带来ios9设置6位密码图文教程   在原来的 i ...

  4. C++ 库研究笔记——通过inline避免hpp 的mutiple definition 错误

    C++用了这么多年,这个却第一次知道,以前没用过hpp 这样: // foo.hpp void foo() { /* body */ } // a.cpp #include "foo.hpp ...

  5. JS实现图片翻书效果

    picture.html <html xmlns="http://www.w3.org/1999/xhtml"> <head> <meta http- ...

  6. android sim 卡短信读写

    因为对短信读写操作的api 被隐藏了 , 我们须要使用<Java反射机制的学习>一文中提到的反射的方法得到隐藏API . 这有一个用例大家能够下载http://zhushou.360.cn ...

  7. 【Android】自己定义控件——仿天猫Indicator

    今天来说说类似天猫的Banner中的小圆点是怎么做的(图中绿圈部分) 在学习自己定义控件之前,我用的是很二的方法,直接在布局中放入多个ImageView,然后代码中依据Pager切换来改变图片.这样的 ...

  8. Storm流计算之项目篇(Storm+Kafka+HBase+Highcharts+JQuery,含3个完整实际项目)

    1.1.课程的背景 Storm是什么? 为什么学习Storm? Storm是Twitter开源的分布式实时大数据处理框架,被业界称为实时版Hadoop. 随着越来越多的场景对Hadoop的MapRed ...

  9. 浏览器打开URL的方式和加载过程

    不同浏览器的工作方式不完全一样,大体上,浏览器的核心是浏览器引擎,目前市场占有率最高的几种浏览器几乎都使用了不同的浏览器引擎:IE使用的是Trident.Firefox使用的是Gecko.Safari ...

  10. STM32的FSMC总线复用调试笔记

    调试FSMC总线复用模式时主要遇到以下几点: 1.寄存器的配置,首先注意使能地址数据复用,其次要存储器类型选择FSMC_MemoryType_NOR,否则出现不了NADV信号. FSMC_NORSRA ...