Hibernate入门4.核心技能 20131128

代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv

前言:

前面学习了Hibernate3的基本知识,并且应用在简单的实践中。这些知识Hibernate的基本知识,只能说是会使用简单的hibernate了。这一章学习的是Hibernate的核心技能。主要知识点:

Hibernate中持久化类的关联关系、Hibernate的批量处理技术、Query接口的核心方法和使用、HQL语言的查询、Criteria接口的核心方法以及查询技巧、Restrictions的使用方法、DetachedCriteria离线查询的技巧、Hibernate事务处理

1.Hibernate中的关联关系

关联关系指的是类之间的引用关系,是实体对象之间普遍存在的一种关系。使用Hibernate框架可以完整的表述这种关联关系,如果映射的十分恰当,Hibernate的关联映射将在很大程度上简化对于持久层数据的访问。

1.1一对多的关联关系

单项的N-1的关系,只能够从N访问到1的一端,在类与类的各种关联关系中,单项N-1关联和关系数据库中的外检参照关系最为相似。比如Customer和Order,使用的是N-1的单项关联,即从Order到Customer的关联关系。(其实这里已经买下一个地雷了,我们使用Order表示订单,在数据库中,对应的表的名字可以是order,当然是不可以的,因为order是关键字。在数据库的创建表的过程中,我习惯使用小写字母,这里就会出现非常隐蔽的错误,我们不断的调试程序,却始终找不到错误。)

Customer.java

package com.yang.hib.model;

public class Customer {

private int id;

private String userName;

private String password;

private String realName;

private String address;

private String mobile;

private String email;

public Customer(){}

public Customer(String userName, String password, String realName,

String address, String mobile, String email) {}

//getter & setter

}

Order.java:

package com.yang.hib.model;

import java.util.Date;

public class Order {

private int id;

private String orderNo;

private Date date;

private double total;

private Customer customer;

public Order(){}

public Order(String orderNo, Date date, double total, Customer customer) {}

//getter & setter

public void setCustomer(Customer customer){this.customer = customer;}

public Customer getCustomer(){return this.customer;}

}

Customer.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 package="com.yang.hib.model">

<class name="Customer" table="customer">

<!—参考之前的代码-->

</class>

</hibernate-mapping>

Order.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 package="com.yang.hib.model">

<class name="Order" table="myorder">

<!—注意这里的数据表不可以是order,关键字一般情况下不能够用作表名-->

<id name="id" column="id">

<generator class="native"/>

</id>

<property name="orderNo"    column="orderno"    type="string"/>

    <property name="date"       column="orderdate" type="timestamp"/>

        <property name="total"      column="total"      type="double"/>

        <many-to-one name="customer" column="customer_id" class="Customer" cascade="save-update"/>

        <!—这一句是最为核心的配置信息,实现多对一的级联关系-->

</class>

</hibernate-mapping>

HibernateUtil.java

package com.yang.hib.util;

public class HibernateUtil {

private static String HIBERNATE_CONFIG_FILE = "hibernate.cfg.xml";

private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();

private static Configuration configuration = new Configuration();

private static SessionFactory sessionFactory ;

/*静态代码段,在该类加载的时候,执行这一段代码,这里使用的是单例模式,同时为了在多线程中使用session,使用了线程的局部变量,之前在Java进阶中的关于线程同步的知识中,最后一种方式便是使用的这一种线程局部变量将他保护起来的方式*/

static{

try{

configuration.configure(ClassLoader.getSystemResource(HIBERNATE_CONFIG_FILE));

sessionFactory = configuration.buildSessionFactory();

}catch(Exception e){

System.err.println("%%%%%Error Creating session factory %%%%%%%%");

e.printStackTrace();

}

}

//禁止外部创建该类型的对象

private HibernateUtil(){}

public static Session getSession() throws HibernateException{

Session session = threadLocal.get();

if(session == null || !session.isOpen()){

if(sessionFactory == null){

sessionFactory = configuration.buildSessionFactory();

}

session = (sessionFactory != null)?sessionFactory.openSession():null;

threadLocal.set(session);

}

return session;

}

public static void reBuildSessionFactory(){

try{

configuration.configure(HIBERNATE_CONFIG_FILE);

sessionFactory = configuration.buildSessionFactory();

}catch(Exception e){

System.err.println("%%%%Error Creating SessionFactory %%%%%");

e.printStackTrace();

}

}

public static void closeSession() throws HibernateException{

Session session  = threadLocal.get();

threadLocal.set(null);

if(session != null){

session.close();

}

}

public static SessionFactory getSessionFactory(){

return sessionFactory;

}

public static void setHibernateConfigFile(String hibernateConfigFile){

HIBERNATE_CONFIG_FILE = hibernateConfigFile;

}

public static Configuration getConfiguration(){

return configuration;

}

}

TeatMain.java

package com.yang.main;

public class TestMain {

public static void addCustomerAndOrder(){

Customer customer = new Customer("yang","12345","杨腾飞","广州","15800027127","1076906529@qq.com");

System.out.println("add customer to database");

addCustomer(customer);

Order order1 = new Order("A1",new Date(),42.8,customer);

System.out.println("add order to database");

addOrder(order1);

order1 = new Order("A2",new Date(),35.9,customer);

System.out.println("add antother order to database");

addOrder(order1);

}

public static void addCustomer(Customer customer){

Session session = HibernateUtil.getSession();

Transaction trans = session.beginTransaction();

session.save(customer);

trans.commit();

HibernateUtil.closeSession();

}

public static void addOrder(Order order){

Session session = HibernateUtil.getSession();

Transaction trans = session.beginTransaction();

session.save(order);

trans.commit();

HibernateUtil.closeSession();

}

public static void main(String[] args) {

// TODO Auto-generated method stub

addCustomerAndOrder();

}

}

我们可以根据订单查询出数据库中的对应的顾客的信息,修改TestMain.java函数:

public static void findOrder(int id){

Session session = HibernateUtil.getSession();

Order order = (Order) session.get(Order.class, id);

Customer customer = order.getCustomer();

System.out.println( "Id:"+order.getId()+

"\ntotal:"  + order.getTotal()+

"\norderdate:" + order.getDate().toLocaleString() +

"\nrealName:"+customer.getRealName()+

"\nmobile:" + customer.getMobile());

HibernateUtil.closeSession();

}

public static void main(String[] args) {

// TODO Auto-generated method stub

//addCustomerAndOrder();

findOrder(1);

}

这个时候,我们发现在控制台中是执行了两个SQL语句,对于两个表的查询,我们可以使用连接的形式使用一条SQL语句便可以完成这些查询:

在hibernate-mapper配置信息中,对于<many-to-one>元素中可以使用指定的属性来让hibernate使用连接的方式:

<many-to-one name=”customer” fetch=”join” column=”customer_id” class=”Customer”/>实现。对于many-to-one元素的fetch属性也可以使用outer-join属性替代,默认情况之下使用的是fetch=”select”。

1.2单项的1-N的关系

Customer与Order就是一对多的关系,我们可以在Order中添加orders集合属性

Customer.java

private Set<Order> orders=new HashSet<Order>();

public void setOrders(Set<Order> orders){ this.orders = orders;}

public Set<Order> getOrders(){return this.orders;}

配置文件中添加如下配置信息:

Customer.hbm.xml

<set name="orders">

<key column="customer_id"/><!—这里是对应的另一个表中的字段-->

<one-to-many class="Order"/>

</set>

在Hibernate中通过比较两个持久化对象的标识符属性ID来判断两者是否是相等的,这需要在实体类中对equals()和hashCode()方法重写。

重写hashCode()

public int hashCode(){

final int prime = 31;

int result = 1;

result = result*prime + ((id==null)?0:id.hashCode());

return result;

}

也就是将id+prime作为其对象的hashCode

同时对已比较两个对象是否相等,如果两者的引用是同一个对象的话,那么无论怎样都是相等的,否则如果对象是null的话,那么两者肯定不相等,因为如果两个都是null的话,那么在前面的判断中两者引用都是null则相等。继而继续判断:将obj转换成为目标类型的对象,这个时候原始的对象的id如果是null,也就是数据库中没有该数据,另一个对象也是没有持久化的,内容虽然不相同,但是两者的都没有id,则判断两者是相等的。

参考代码:

Customer c1 = new Customer("yssg","12345","sss","广州","sssss","1076sss529@qq.com");

Customer c2 = new Customer("yanssg","134545","sss","广州","sss7","107sss0ss6529@qq.com");

System.out.println(c1.equals(c2));

正常情况之下,两者是不想等的,但是在Hibernate重写equals函数之后,两者就是相等的。很诡异的吧,其实我现在也不是很理解。但是这是在Hibernate中比较数据库中的两个对象,就只会根据id来判断。

public boolean equals(Object obj){

if(this == obj){    return true;    }

if(obj == null){    return false;}

if(getClass() != obj.getClass()){   return false;}

Customer other = (Customer) obj;

if(id == null){

if(other.id != null){return false;}

}else if( ! id.equals(other.id)){

return false;

}

return true;

}

下面查询执行用户的订单:

public static void findOrderByCustomer(Integer id){

Session session = HibernateUtil.getSession();

Customer customer = (Customer) session.get(Customer.class, id);

Set<Order> orders = customer.getOrders();

for(Order order : orders){

System.out.println( "id:"+ order.getId()+

",\torderNo:"+order.getOrderNo()+

",\ttotal:" + order.getTotal()+

",\tdate:"+order.getDate().toLocaleString());

}

}

一般使用的技术是双向的1-N级联,也就是在两个里面都配置级联关系,形成双向的级联。

YangTengfei

2013.11.28

转载于:https://www.cnblogs.com/hbhzsysutengfei/p/3473208.html

Hibernate入门4.核心技能相关推荐

  1. Vue3 核心技能从入门到难点攻破,看这一篇就够了!

    在 Vue2.0 时代,国内大厂的前端开发框架,几乎清一色偏向 React.因为对于业务成熟的公司而言,一个项目,可能会包含很多非侵入式的代码和服务,并不是功能实现了就万事大吉. 但随着 Vue3.0 ...

  2. 杨老师课堂之JavaEE三大框架Hibernate入门第一课

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/kese7952/article/details/80998421 本篇任务 1. 使用Hiberna ...

  3. 写 Python 爬虫 5 年,复制粘贴一直是我赖以生存的核心技能,直到我看到这些腾讯阿里大佬们的技术公众号,太强了...

    人与人之间的差异,很多时候在于细节和主动性,有的程序员习惯了复制粘贴,把这些当成自己的核心技能,也有大佬会把握技术细节,优化代码,而不是简单的复制粘贴,从根本上搞定问题.下面介绍一些技术圈的大厂程序员 ...

  4. Hibernate入门这一篇就够了

    前言 本博文主要讲解介绍Hibernate框架,ORM的概念和Hibernate入门,相信你们看了就会使用Hibernate了! 什么是Hibernate框架? Hibernate是一种ORM框架,全 ...

  5. SSH Chapter 04 Hibernate 入门

    SSH Chapter 04 Hibernate入门 笔记 Hibernate 知识体系图: 本章目标: 理解类和表的映射关系 掌握单表的增删改 掌握按主键查询 理解持久化对象的状态及其转换 技术内容 ...

  6. Hibernate入门6.Hibernate检索方式

    Hibernate入门6.Hibernate检索方式 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv Hibernate的整体框架已经 ...

  7. python语言训练教程_Houdini中Python编程语言核心技能训练视频教程

    CGcountry致力于国内外最新CG素材的发布欣赏与下载,CG软件的下载,插件下载等等.主要软件分类有:3dsmax,maya,houdini,ZBrush,vray,AE,premiere等.涉及 ...

  8. hibernate入门

    什么是hibernate? Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得java程序员可以随心所欲的使用对象编程思维来操纵数据库. Hiberna ...

  9. Hibernate4实战 之 第一部分 Hibernate入门

    第一部分:Hibernate入门 Hibernate是什么 Hibernate是一个轻量级的ORMapping框架 ORMapping原理(Object Relational Mapping) ORM ...

最新文章

  1. js各种图表组件网站
  2. Install Qt5 on Ubuntu 16.04
  3. 德州寒流对IDC带来极大影响
  4. 客户端命令(docker)
  5. jdbc.properties文件
  6. easyui动态显示和隐藏表头
  7. 如何安装pfbprophet
  8. newifi mini固件_如何在vmware虚拟机中安装OpenWrt系统,含x86固件编译教程
  9. 设置背景图时防止图片拉伸的解决方法
  10. C/C++——cmd下丢失mspdb100.DLL解决方法
  11. java 中的scanner_java 中的Scanner
  12. gtx780有html接口吗,笔记本玩转游戏大作 达人外接GTX780Ti
  13. STM32F103mini教程学习总结与心得(四)---->看门狗
  14. Android MTK修改手机型号
  15. 考试系统微信小程序的设计与实现
  16. topic是短语还是句子_词组、短语、句子--Unit 3 Topic 3
  17. 每日一滴——更新pycharm_nltk包中模块的安装
  18. 深度强化学习——DQN
  19. Oracle索引简介
  20. uni-app中如何引入uview-ui?

热门文章

  1. 1017 非常可乐
  2. NestJS、Vite 和 esbuild 入门
  3. Codis源码解析——Jodis
  4. JS 将毫秒数时间,转化为时间格式(yy-MM-dd)
  5. 【干货】Python中“\n”、“\t”、“end”的用法
  6. 我们不曾向这个世界的庸俗低头!!!
  7. IEEE TRANSACTIONS ON CIRCUITS AND SYSTEMS FOR VIDEO TECHNOLOGY(TCSVT) 投稿经验
  8. Koordinator 0.6:企业级容器调度系统解决方案,引入 CPU 精细编排、资源预留与全新的重调度框架...
  9. 快速实现抖音的分享登录(android) 1
  10. 专业B2C电子商务平台推荐