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 ...
随机推荐
- Kivy: Crossplatform Framework for NUI
Kivy: Crossplatform Framework for NUI ivy - Open source Python library for rapid development of appl ...
- Android中通过耳机按键控制音乐播放的实现
今天在研究Android中实现Android 4.2.2源码中的Music应用的源码,关于通过耳机按键控制音乐播放的实现,有点好奇,就仔细分析了一下源码, 主要由 MediaButtonIntentR ...
- Random Teams
n participants of the competition were split into m teams in some manner so that each team has at le ...
- Windows下用WinSCP传输数据到Linux上
Scenario:最近公司做的一个项目,UI部分我是使用python在编译时做localization的,是linux下运行的,但是开发是在windows下进行的每次编译后都要手动通过WinSCP这个 ...
- oracle数据库中insert与select
前几天遇到了一个问题,insert语句中,不仅要insert页面传过来的值,还要insert select的值. 语句应该这样写: insert into 表1(字段a,字段b,...) select ...
- Matlab,Visio等生成的图片的字体嵌入问题解决方法
确保所有字体嵌入,是生成高质量学术论文的必要条件.但是在Windows下,总会遇到Matlab或Visio生成字体没有嵌入的问题,当然这个问题的解决办法有很多(例如,对于Visio可以这样做:直接拷贝 ...
- 【VC】Dialog 窗体随意切割子窗体。
用 Dialog 对话框来实现窗体的随意切割. 在资源中加入 Dialog 选择 IDD_FORMVIEW 资源..分别新建FormViewOne,FormViewTwo FormViewThre ...
- Redhat下安装fedora
步骤具体解释: 1:到fedora官网下载fedora的DVD镜像文件. 2:在linux系统中预留一部分为未分区的空间大约50G 3: 在linux系统上的根分区创建一个fedora的目录,里面 ...
- ASP.NET - (Session)后台登陆时,判断是不是已经登陆,如果不是,跳转回登陆页
admin(小写):用户输入的账户. password(小写):用户输入的密码. 1.先将用户名和密码,存储到Session会话中. Session["Admin"] = admi ...
- Linux/ubuntu下的boost库安装
我一直都没有写博客的习惯,最近正好在研究linux下的开发(目前也只是粗粗的研究),且用到了boost库,就乘此机会写点什么,最起码记录一下我在安装boost的一些步骤,主要给和我一样的linux开发 ...