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. tcp/ip协议listen函数中backlog參数的含义

    listen函数的定义例如以下所看到的: #include <sys/socket.h> int accept(int sockfd, struct sockaddr * restrict ...

  2. STL之iterator(迭代器)

    3.迭代器简单介绍 除了使用下标来訪问vector对象的元素外,标准库还提供了訪问元素的方法:使用迭代器.迭代器是一种检查容器内元素而且遍历元素的数据类型. 百科释义: 迭代器(iterator)是一 ...

  3. 视频播放-SurfaceView

    1.视图 <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:too ...

  4. OC-多线程安全隐患及一般解决办法

    1.多线程的安全隐患1.1>一块资源可能被多个线程共享,也就是多个线程可能会访问同一块资源,如多个线程访问同一个对象,变量,文件等当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题1. ...

  5. winform 防止主界面卡死

    总结网络上的解决方案:新线程=> 委托=> 主界面的异步更新方法(IAsyncResult BeginInvoke(Delegate method)),一句话就是通过委托调用另一个线程的异 ...

  6. c:foreach如何嵌套循环,求指教,求优化

    java类: public class PopedomItem { private String id; private String pid; private String name; privat ...

  7. RESTFul Shiro

    RESTFul与服务没有关系?REST的本质是设计风格,不是技术. REST的URL还是个URL,就是个普通的URL,访问这个URL的时候,先被Servlet Filter(即Shiro 的Filte ...

  8. VC 对话框背景颜色、控件颜色

    系统环境:Windows 7软件环境:Visual C++ 2008 SP1本次目的:为对话框设置背景颜色.控件颜色 既然MFC对话框不好开发,那么现在我们来开始美化我们的对话框.为对话框设置背景颜色 ...

  9. [hadoop系列]Pig的安装和简单演示样例

    inkfish原创,请勿商业性质转载,转载请注明来源(http://blog.csdn.net/inkfish ).(来源:http://blog.csdn.net/inkfish) Pig是Yaho ...

  10. 解 自己关于 C# Button的Click事件的疑惑

    先说说C#中事件的用法,从事件的用法中,我自己会产生一个疑惑 C#事件 class Program { static void Main(string[] args) { EventClass ec ...