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. docker学习笔记4:利用docker hub上的mysql镜像创建mysql容器

    docker hub上有官方的mysql镜像,我们可以利用它来创建mysql容器,作为一个服务容器使用. 1.下载mysql镜像 docker pull mysql 2.创建镜像 docker run ...

  2. UTL_RAW

    The UTL_RAW package provides SQL functions for manipulating RAW data types. 该包的功能其实可以用来加密: SELECT    ...

  3. 基于visual Studio2013解决C语言竞赛题之1005整理队形

         题目 解决代码及点评 /************************************************************************/ ...

  4. Creating Spatial Indexes(mysql 创建空间索引 The used table type doesn't support SPATIAL indexes)

    For MyISAM tables, MySQL can create spatial indexes using syntax similar to that for creating regula ...

  5. Spring源代码解析 ---- 循环依赖

    一.循环引用: 1. 定义: 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比方CircularityA引用CircularityB,CircularityB引用Circularit ...

  6. 第1章 软件测试基本概念(Week1,3月3日)

    一.对软件的认识 1. 什么是软件 2. 软件的分类 3. 软件开发的生命周期模型 (1)瀑布模型 (2)Scrum 其实对用瀑布模型这种臃肿不堪.要求严格.而无法适应软件开发周期变化的开发模型,渐渐 ...

  7. 页面提交进不了Action的原因

    1.进不了action,页面没有任何js报错,可能的原因是数据类型不一致.例如用ajax方式提交所带的参数类型a是String类型,而action中定义的a是Integer类型就会导致这种情况的发生.

  8. 关于android多点触控

    最近项目需要一个多点触控缩放的功能.然后上网查了下资料 总结一下: 首先android sdk版本很重要,比如你在AndroidManifest.xml中指定android:minSdkVersion ...

  9. asp.net2.0安全性(4)--Login系列控件--转载来自车老师

    前面主要说了与安全相关的一系列的类,现在我们使用这些类就可以做出我们自己的安全系统了.其实微软的目的远不至于此,下面我们就来看一下微软为我们提供的Login系列控件. Login系列控件是微软为了简化 ...

  10. 开源JDBC工具类DbUtils

    本篇将会详细地介绍Apache公司的JDBC帮助工具类DbUtils以及如何使用.在上一篇中我们已经通过将以前对dao层使用JDBC操作数据库的冗余代码进行了简易封装形成自己的简单工具类JdbcUti ...