hibernate初步2
Hibernate级联设计
数据库表之间的关系(主要关系有一对多、一对一、多对多)主要是从如下三个方面体现出来:
1.表体设计
2.实体类的设计
3.配置文件
以下是一些重要级联设计参数属性介绍:
cascade级联操作,默认值为 none
1.none:只做级联查询
2.save-update:级联查询,级联插入和级联更新
3.delete:级联查询,级联删除
4.all:级联查询,级联插入,级联更新和级联删除
5.all-delete-orphan:基础主从表记录关系时,会把从表对应的记录一并删除
inverse:维护两张表之间的关系,默认值是 false,即维护从表的外键值
1.ture:不维护从表外键值
2.false:维护从表外键值
3.在 hibernate 中通过对 inverse 属性的值决定是由双向关联的哪一方来维护表和表之间的关系. inverse=false 的为主动方,inverse=true 的为被动方, 由主动方负责维护关联关系
4. 在没有设置 inverse=true 的情况下,父子两边都维护父子关系
5.在 1-n 关系中,将 n 方设为主控方将有助于性能改善
6.在 1-N 关系中,若将 1 方设为主控方 会额外多出 update 语句。
注意:cascade 和 inverse 优先考虑cascade操作,然后再考虑 inverse 操作!
lazy:是否延迟加载从表取出来的数据
1.true 延迟加载
2.flase 不延迟加载
一对多关联关系映射(表的设计原则是:在多的一方添加外键链来描述彼此之间的关系)
POJO类的设计:
1.设计 OrderItem 类,它代表为“1”的一方:
public class OrderItem {
private int id;
private int amount;
private String productName;
private UserOrder userOrder;
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public int getAmount() {return amount;}
public void setAmount(int amount) {this.amount = amount;}
public String getProductName() {return productName;}
public void setProductName(String productName) {this.productName = productName;}
public UserOrder getUserOrder() {return userOrder;}
public void setUserOrder(UserOrder userOrder) {this.userOrder = userOrder;}
}
2.设计 UserOrder 类,它代表为"n"的一方:
import java.util.HashSet;
import java.util.Set; public class UserOrder {
private int id;
private int userId;
private int status;
private double cost;
/**
* 存放相关联的OrderItem对象
*/
private Set<OrderItem> orderItems = new HashSet<OrderItem>();
//从面向对象的角度来看,在“多”的一方使用一个集合用来保存另一个相关联的对象的信息。
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public int getUserId() {return userId;}
public void setUserId(int userId) {this.userId = userId;}
public int getStatus() {return status;}
public void setStatus(int status) {this.status = status;}
public double getCost() {return cost;}
public void setCost(double cost) {this.cost = cost;} public Set<OrderItem> getOrderItems() {
return orderItems;
}
public void setOrderItems(Set<OrderItem> orderItems) {
this.orderItems = orderItems;
}
@Override
public String toString() {
return "UserOrder [id=" + id + ", userId=" + userId + ", status=" + status + ", cost=" + cost + "]";
}
}
3.建立 OrderItem 的 Hibernate 相关映射配置文件:orderitem.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="net.togogo.onetomany.pojo.OrderItem" table="order_item" >
<id name="id" type="int">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="amount" type="int">
<column name="amount" length="11" />
</property>
<property name="productName" type="string">
<column name="productName" length="30" />
</property>
<many-to-one name="userOrder" class="net.togogo.onetomany.pojo.UserOrder" cascade="all" column="order_id">
</many-to-one>
</class>
</hibernate-mapping>
4.建立 UserOrder 的 Hibernate 相关映射配置文件:userorder.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"> <hibernate-mapping>
<!-- POJO 数据库中的表对应的实体类 -->
<class name="net.togogo.onetomany.pojo.UserOrder" table="user_order" >
<id name="id" type="int">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="userId" type="int">
<column name="user_id" length="11" />
</property>
<property name="status" type="int">
<column name="status" length="11" />
</property>
<property name="cost" type="double">
<column name="cost" />
</property> <!-- many-to-one属性说明:
* name:设定待映射的持久化类的名字。
name="orderItems",对应UserOrder中的setOrderItems(Set<OrderItem> orderItems)方法 column:设定和持久化类的属性对应的表的外键。 class:设定持久化类的属性的类型。 not-null:是否允许为空。
cascade:级联操作,默认值是none,常用的值:
1)none:只做级联查询
2)save-update:级联查询,级联插入和级联更新
3)delete:级联查询,级联删除
4)all:级联查询,级联插入,级联删除,级联更新
5)all-delete-orphan:解除主从表记录关系时,会把从表对应的记录一并删除 inverse:维护两张表之间的关系,默认是false,即维护从表的外键值
1)true:不维护从表外键值
2) false:维护从表外键值 cascade和inverse:优先考虑cascade操作,然后再考虑inverse lazy:是否延迟加载从表的数据,true,延迟加载,false,立即加载
--> <set name="orderItems" cascade="all-delete-orphan" inverse="false" lazy="true">
<!-- 从表的外键字段 -->
<key column="order_id"></key>
<one-to-many class="net.togogo.onetomany.pojo.OrderItem"/>
</set>
</class>
</hibernate-mapping>
5.在 hibernate.cfg.xml 配置文件加入 userorder.hbm.xml 和 orderitem.hbm.xml 相关信息:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<!-- 数据库连接信息 -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<!-- 所使用的数据库名 -->
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/hibernate_db
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- 设置连接池大小 -->
<property name="hibernate.connection.pool_size">10</property>
<!--
实质是调用 Statement.setFetchSize() 方法设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数。
例如一次查询1万条记录,对于Oracle的JDBC驱动来说,是不会 1 次性把1万条取出来的,而只会取出Fetch Size条数,
当纪录集遍历完了这些记录以后,再去数据库取Fetch Size条数据。因此大大节省了无谓的内存消耗。
Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。
Oracle数据库的JDBC驱动默认的Fetch Size=10,是一个保守的设定,根据测试,当Fetch Size=50时,性能会提升1倍之多,
当Fetch Size=100,性能还能继续提升20%,Fetch Size继续增大,性能提升的就不显著了。
并不是所有的数据库都支持Fetch Size特性,例如MySQL就不支持。MySQL就像上面那种最坏的情况,总是一下就把1万条记录完全取出来,
内存消耗会非常惊人!
-->
<property name="hibernate.jdbc.fetch_size">50</property>
<!--
设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,类似于设置缓冲区大小的意思。Batch Size越大,
批量操作的向数据库发送sql的次数越少,速度就越快。测试结果是当Batch Size=0的时候,使用Hibernate对Oracle
数据库删除1万条记录需要25秒,Batch Size = 50的时候,删除仅仅需要5秒!
Oracle数据库 Batch Size = 30 的时候比较合适
-->
<property name="hibernate.jdbc.batch_size">50</property> <!-- 显示底层的sql语句,开发阶段设为true,项目发布阶段设为false -->
<property name="show_sql">true</property>
<property name="format_sql">false</property>
<property name="use_sql_comments">false</property> <!-- 在启动和停止时自动地创建,更新或删除数据库模式。取值 create | update | create-drop | validate,
推荐使用update,update值表示如果之前有表,就用之前的表,否则创建新的表 -->
<property name="hbm2ddl.auto">update</property>
<mapping resource="net/togogo/onetomany/pojo/userorder.hbm.xml"/>
<mapping resource="net/togogo/onetomany/pojo/orderitem.hbm.xml"/>
</session-factory>
</hibernate-configuration>
一对一级联关系映射(表的设计原则是:存在主从关系,主可以没有从,但从不能没有主。在从表中将主键链(默认拥有唯一约束和非空约束)声明成外键约束即可。---------也就是说,有一列既是主键列又是外键链。)
POJO类的设计
1.设计 Boy 类,它代表为"1"的一方:
public class Boy {
private int id;
private String name;
private Girl girl;
public int getId() { return id;}
public void setId(int id) { this.id = id;}
public String getName() {return name; }
public void setName(String name) { this.name = name;}
public Girl getGirl() {return girl;}
public void setGirl(Girl girl) {this.girl = girl;}
}
2.设计 Girl 类,它代表为"1"的另一方:
public class Girl {
private int id;
private String name;
private Boy boy; public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Boy getBoy() {return boy;}
public void setBoy(Boy boy) {this.boy = boy;}
}
3.建立 Boy 的 Hibernate 相关映射配置文件:boy.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Mapping file autogenerated by MyEclipse Persistence Tools -->
<hibernate-mapping>
<class name="net.togogo.onetoone.pojo.Boy" table="boy">
<id name="id" type="int">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="name" type="string">
<column name="name" length="30" />
</property> <many-to-one name="girl" cascade="all" lazy="false"
class="net.togogo.onetoone.pojo.Girl" unique="true" column="g_id"></many-to-one>
</class> </hibernate-mapping>
4.建立 Girl 的 Hibernate 相关映射配置文件:girl.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Mapping file autogenerated by MyEclipse Persistence Tools -->
<hibernate-mapping>
<class name="net.togogo.onetoone.pojo.Girl" table="girl">
<id name="id" type="int">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="name" type="string">
<column name="name" length="30" />
</property> <one-to-one name="boy" cascade="all" lazy="false"
class="net.togogo.onetoone.pojo.Boy">
</one-to-one>
</class>
</hibernate-mapping>
5.在 hibernate.cfg.xml 配置文件加入 boy.hbm.xml 和 girl.hbm.xml 相关信息:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<!-- 数据库连接信息 -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/hibernate_db
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property> <!-- 设置连接池大小 -->
<property name="hibernate.connection.pool_size">10</property>
<property name="hibernate.jdbc.fetch_size">50</property>
<property name="hibernate.jdbc.batch_size">50</property>
<property name="show_sql">true</property>
<property name="format_sql">false</property>
<property name="use_sql_comments">false</property>
<property name="hbm2ddl.auto">update</property> <mapping resource="net/togogo/onetoone/pojo/girl.hbm.xml"/>
<mapping resource="net/togogo/onetoone/pojo/boy.hbm.xml"/>
</session-factory>
</hibernate-configuration>
多对多级联关系映射(数据库表的设计原则:增加一个表用来保存两个表之间的关系)
POJO类的设计:
1.设计 Couse 类,它代表为"多"的一方:
public class Course {
private int id;
private String name;
public int getId() {return id;}
public void setId(int id) {this.id = id; }
public String getName() {return name;}
public void setName(String name) {this.name = name;}
}
2.设计 Stu 类,它代表为"多"的另一方:
public class Stu {
private int id;
private String name;
private Set<Course> courses = new HashSet<Course>();
public int getId() {return id;}
public void setId(int id) {this.id = id;}
public String getName() {return name;}
public void setName(String name) {this.name = name;}
public Set<Course> getCourses() {return courses;}
public void setCourses(Set<Course> courses) {this.courses = courses;}
}
3.建立 Course 的 Hibernate 相关映射配置文件:course.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="net.togogo.manytomany.pojo.Course" table="course">
<id name="id" type="int">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="name" type="string">
<column name="name" length="30" />
</property>
</class>
</hibernate-mapping>
4.建立 Stu 的 Hibernate 相关映射配置文件:stu.hbm.xml
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Mapping file autogenerated by MyEclipse Persistence Tools -->
<hibernate-mapping>
<class name="net.togogo.manytomany.pojo.Stu" table="stu">
<id name="id" type="int">
<column name="id" />
<generator class="native"></generator>
</id>
<property name="name" type="string">
<column name="name" length="30" />
</property>
<!-- inverse="false",在这里是要维护stu_course中的记录值 -->
<set name="courses" cascade="all" inverse="false" lazy="false" table="stu_course">
<key column="s_id"/>
<many-to-many column="c_id" class="net.togogo.manytomany.pojo.Course"></many-to-many>
</set>
</class>
</hibernate-mapping>
5.在 hibernate.cfg.xml 配置文件加入 stu.hbm.xml 和 course.hbm.xml 相关信息:
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- 数据库连接信息 -->
<property name="dialect">
org.hibernate.dialect.MySQLDialect
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.url">
jdbc:mysql://localhost:3306/hibernate_db
</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<!-- 设置连接池大小 -->
<property name="hibernate.jdbc.fetch_size">50</property>
<property name="hibernate.jdbc.batch_size">50</property>
<property name="show_sql">true</property>
<property name="format_sql">false</property>
<property name="use_sql_comments">false</property>
<property name="hbm2ddl.auto">update</property> <mapping resource="net/togogo/manytomany/pojo/stu.hbm.xml"/>
<mapping resource="net/togogo/manytomany/pojo/course.hbm.xml"/>
</session-factory>
</hibernate-configuration>
对象的状态转化
Hibernate 把对象分为 4 种状态:
1.临时状态
2.持久状态
3.游离状态
4.删除状态
Session 的特定方法能使对象从一个状态转换到另一个状态
临时状态(transient)
1.在使用代理主键的情况下, OID 通常为 null
2.不处于 Session 的缓存中
3.在数据库中没有对应的记录
持久化状态(托管状态)(Persist)
1.OID 不为 null
2.位于 Session 缓存中
3.持久化对象和数据库中的相关记录对应
4.Session 在清理缓存时, 会根据持久化对象的属性变化, 来同步更新数据库
5.在同一个 Session 实例的缓存中, 数据库表中的每条记录只对应唯一的持久化对象
游离状态(Detached)
1.OID 不为 null
2.不再处于 Session 的缓存中
3.一般情况需下, 游离对象是由持久化对象转变过来的, 因此在数据库中可能还存在与它对应的记录
删除状态(Removed)
1.OID 不为 null
2.从一个 Session实例的缓存中删除
3.Session 已经计划将其从数据库删除, Session 在清理缓存时, 会执行 SQL delete 语句, 删除数据库中的对应记录
4.一般情况下, 应用程序不该再使用被删除的对象
对象关系状态转化图如下:
//end
hibernate初步2的更多相关文章
- hibernate初步4
JPA 1.JPA概述 JPA(Java Persistence API)是Sun官方提出的Java持久化规范.它为Java开发人员提供了一种对象/关系映射工具来管理Java应用中的关系数据.,而Hi ...
- hibernate初步3
事务和并发 1.事务概念 一组不可分割的操作,事务有如下属性(ACID 属性:Atomic Consistent Isolated Durable)(1)原子性---Atomic 事务的原子性指的是 ...
- hibernate初步
Hibernate开发步骤1.新创建工程并且导入相关的包 主要是hibernate.mysql相关的JAR包. 注意:新导入的hibernate相关的JAR包是否与你当前所使用的jdk版本是否兼容,且 ...
- Hibernate知识总结(一)
一.ORM ORM的全称是Object/Relation Mapping,即对象/关系映射,可以将其理解成一种规范,它概述了这类框架的基本特征:完成面向对象的编程语言到关系数据库的映射.可以把ORM看 ...
- Hibernate(1)基本知识
hibernate初步 1.概述 ①hibernate是java应用和关系数据库之间的桥梁,是一个开源的对象关系映射框架,可用来把对象模型表示的java对象 映射到关系型数据库表中去. ②hibern ...
- Hibernate二次学习一----------搭建Hibernate
目录 1. 项目结构 1.2 hibernate.cfg.xml 1.3 entity 1.4 entity.hbm.xml 2. 测试 3. 总结 © 版权声明:本文为博主原创文章,转载请注明出处 ...
- 如何自学 Java 开发
如何自学 Java 开发? 568赞同反对,不会显示你的姓名 李艾米IT路上学习 568 人赞同 Java Web前端技术 HTML 入门视频课程 1 HTML 简介 2 HTML基本结构[ 3 HT ...
- Hibernate的初步
1.简介 在java开发领域,基于数据库应用的设计与实现一直都是面向关系的,Hibernate对象/关系映射ORM框架的出现为java面向对象开发提供了易于使用的数据持久化解决方案. ORM介绍: ( ...
- Hibernate学习2—Hibernate4 CRUD体验初步
接着上一节,工程结构: jar包没有变化: 一.HibernateUtil 封装: com.cy.util.HibernateUtil.java: package com.cy.util; impor ...
随机推荐
- Python3之format
print('{0},{1}'.format('zhangk', 32)) print('{},{},{}'.format('zhangk','boy',32)) print('{name},{sex ...
- Leetcode0523--Continuous Subarray Sum 连续和倍数
[转载请注明]https://www.cnblogs.com/igoslly/p/9341666.html class Solution { public: bool checkSubarraySum ...
- c++和python如何实现主机字节序和网络字节序的相互转换
在上一篇文章网络编程:主机字节序和网络字节序中,介绍了主机字节序和网络字节序的基本概念以及在实际的编程中,何时需要进行网络字节序和主机字节序的转换.本篇文章着重介绍使用c++和python语言,如何实 ...
- (转)分布式文件存储FastDFS(三)FastDFS配置
http://blog.csdn.net/xingjiarong/article/details/50559768 在上一节中我们一起搭建了一个单节点的FastDFS系统,但是仅仅将系统搭建起来是远远 ...
- python基础--字符串操作、列表、元组、文件操作
一.变量及条件判断 1.字符串.布尔类型.float.int类型,None都是不可变变量 2.字符串是不可变变量,不可变变量就是指定义之后不能修改它的值 3.count +=1和count=count ...
- C# WebKitBrowser 设置内容
WebKit.WebKitBrowser kitBrowser = new WebKit.WebKitBrowser(); kitBrowser.Dock = DockStyle.Fill; // k ...
- 关于css定位的一些总结
#pay_pic{ overflow: hidden; width: 200px; margin: 0 auto; } table.dataintable { margin-top: 15px; bo ...
- MFC CAD控制权问题
begineditorcommand(); 隐藏对话框 把控制权交给CAD completeeditorcommand(); 完成交互返回到应用程序 canceleditorcommand CAD被 ...
- Chrome Headless模式
在 Chrome 59 版本开始已经开始支持了 Headless 模式,也就是无界面模式,这样爬取的时候就不会弹出浏览器了,如果要使用此模式请把 Chrome 升级到 59 版本及以上,启用 Head ...
- Django cookie、session使用
一.cookie Cookie是key-value结构,类似于一个python中的字典.随着服务器端的响应发送给客户端浏览器.然后客户端浏览器会把Cookie保存起来,当下一次再访问服务器时把Cook ...