hibernate学习(二)
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学习(二)的更多相关文章
- Hibernate学习(二)关系映射----基于外键的单向一对一
事实上,单向1-1与N-1的实质是相同的,1-1是N-1的特例,单向1-1与N-1的映射配置也非常相似.只需要将原来的many-to-one元素增加unique="true"属性, ...
- hibernate学习二(HelloWorld)
一.建立hibernate配置文件 在工程Hibernate_01_HelloWorld下的src上建立hibernate.cfg.xml,打开hibernate-release-4.3.11.Fin ...
- hibernate学习二 基本用法
一 映射文件User.hbm.xml 定义了持久化类实例是如何存储和加载的,这个文件定义了持久化类和表的映射. 根据映射文件,Hibernate可以生成足够的信息以产生所有的SQL语句,也就是类的实 ...
- Hibernate学习二----------hibernate简介
© 版权声明:本文为博主原创文章,转载请注明出处 1.hibernate.cfg.xml常用配置 - hibernate.show_sql:是否把Hibernate运行时的SQL语句输出到控制台,编码 ...
- Hibernate学习(二补充)关系映射----基于外键的双向一对一
刚刚写的是基于外键的单向一对一. 那么双向一对一就是在单向一对一的基础上稍微改动就可以了. account.java和account.hbm.xml都不用变动 只要我们小小的变动address.j ...
- Hibernate学习笔记(二)
2016/4/22 23:19:44 Hibernate学习笔记(二) 1.1 Hibernate的持久化类状态 1.1.1 Hibernate的持久化类状态 持久化:就是一个实体类与数据库表建立了映 ...
- 我的hibernate学习记录(二)
通过上一篇文章我的hibernate学习记录(一)基本上的入门了hibernate,但是,里面还有还多东西是通过迷迷糊糊的记忆,或者说copy直接弄进去的,所以这篇文章就需要对上篇的一些文件.对象进行 ...
- Hibernate学习之——搭建log4j日志环境
昨天讲了Hibernate开发环境的搭建以及实现一个Hibernate的基础示例,但是你会发现运行输出只有sql语句,很多输出信息都看不见.这是因为用到的是slf4j-nop-1.6.1.jar的实现 ...
- Hibernate 学习教程
第1课 课程内容. 6 第2课Hibernate UML图. 6 第3课 风格. 7 第4课 资源. 7 第5课 环境准备. 7 第6课 第一个演示样例HibernateHelloWorld 7 第7 ...
随机推荐
- docker学习笔记4:利用docker hub上的mysql镜像创建mysql容器
docker hub上有官方的mysql镜像,我们可以利用它来创建mysql容器,作为一个服务容器使用. 1.下载mysql镜像 docker pull mysql 2.创建镜像 docker run ...
- UTL_RAW
The UTL_RAW package provides SQL functions for manipulating RAW data types. 该包的功能其实可以用来加密: SELECT ...
- 基于visual Studio2013解决C语言竞赛题之1005整理队形
题目 解决代码及点评 /************************************************************************/ ...
- 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 ...
- Spring源代码解析 ---- 循环依赖
一.循环引用: 1. 定义: 循环依赖就是循环引用,就是两个或多个Bean相互之间的持有对方,比方CircularityA引用CircularityB,CircularityB引用Circularit ...
- 第1章 软件测试基本概念(Week1,3月3日)
一.对软件的认识 1. 什么是软件 2. 软件的分类 3. 软件开发的生命周期模型 (1)瀑布模型 (2)Scrum 其实对用瀑布模型这种臃肿不堪.要求严格.而无法适应软件开发周期变化的开发模型,渐渐 ...
- 页面提交进不了Action的原因
1.进不了action,页面没有任何js报错,可能的原因是数据类型不一致.例如用ajax方式提交所带的参数类型a是String类型,而action中定义的a是Integer类型就会导致这种情况的发生.
- 关于android多点触控
最近项目需要一个多点触控缩放的功能.然后上网查了下资料 总结一下: 首先android sdk版本很重要,比如你在AndroidManifest.xml中指定android:minSdkVersion ...
- asp.net2.0安全性(4)--Login系列控件--转载来自车老师
前面主要说了与安全相关的一系列的类,现在我们使用这些类就可以做出我们自己的安全系统了.其实微软的目的远不至于此,下面我们就来看一下微软为我们提供的Login系列控件. Login系列控件是微软为了简化 ...
- 开源JDBC工具类DbUtils
本篇将会详细地介绍Apache公司的JDBC帮助工具类DbUtils以及如何使用.在上一篇中我们已经通过将以前对dao层使用JDBC操作数据库的冗余代码进行了简易封装形成自己的简单工具类JdbcUti ...