当前位置:文档之家› 跟我学Hibernate框架技术——多对多的实体映射实现

跟我学Hibernate框架技术——多对多的实体映射实现

跟我学Hibernate框架技术——多对多的实体映射实现
跟我学Hibernate框架技术——多对多的实体映射实现

目录

1.1多对多的实体映射实现示例 (2)

1.1.1了解多对多关联的实现方案 (2)

1.1.2实现本例中的“多对多”实体之间的关联 (3)

1.1.3设计示例相关的POJO类 (5)

1.1.4为实体类创建数据库表与实体之间的映射文件 (8)

1.1.5实现BookAuthor与Book之间的关联 (13)

1.1多对多的实体映射实现示例

1.1.1了解多对多关联的实现方案

1、多对多关联的实现方案

(1)多对多关联---“* - *”,表之间多对多的关联,通常借助中间表来实现在实际的项目开发中也会经常碰到,假设实现一个员工薪金计算,Employee表存放员工信息,Welfare表存放福利项目信息,Salary表存放员工薪金信息,一个员工可以拥有多项福利,一项福利可以被多个员工拥有。Salary表用来保存这些关联关系。

(2)实现方案

对于多对多关联的实现一般有两种可选方案:

●类似一对多情形中的最常用方案,为关联的双方增加到对方的外键,操作比较简单,

缺点是会造成数据冗余;

●新增一张包含关联双方主键的关联表,这时,在取数据时,需要链接该关联表和数据

表,优点是没有数据冗余,缺点是带来了一定的时限复杂度。

所应该注意的是,由于多对多关联的性能不佳(因为引入了中间表,一次读取操作需要反复数次查询),因此在设计中应该避免大量使用。下面的示例采用第二种实现方案。(3)具体的应用说明

在一个权限管理系统中,一个常见的多对多的映射关系就是Group 与Role,以及Role 与Privilege之间的映射。

●Group代表“组”(如“业务主管”);

●Role代表“角色”(如“出纳”、“财务”);

●Privilege 代表某个特定资源的访问权限(如“修改财务报表”,“查询财务报表”)。

这里我们以Group和Role之间的映射为例:

●一个Group中包含了多个Role,如某个“业务主管”拥有“出纳”和“财务”的双

重角色。

●而一个Role也可以属于不同的Group。

2、基于连接表的多对多关联

注意:多对多的关联也同样可以采用Set、List等多种方式来配置。

create table Person ( personId bigint not null primary key )

create table PersonAddress ( personId bigint not null, addressId bigint not null, primary key (personId, addressId) )

create table Address ( addressId bigint not null primary key )

1.1.2实现本例中的“多对多”实体之间的关联

1、在MS SQLServer的本例的数据库中增加一个数据库表BookAuthor

CREATE DATABASE DataBase;

USE DataBase;

drop table BookAuthor;

CREATE TABLE BookAuthor

(

author_id smallint NOT NULL,

authorAge smallint NOT NULL,

firstName nvarchar(20) NOT NULL,

lastName nvarchar(20) NOT NULL,

constraint pk_BookAuthor PRIMARY KEY (author_id)

);

insert BookAuthor values(1, 30, 'xxx','yyyy');

insert BookAuthor values(2, 20, 'xxx','yyyy');

2、决定BookAuthor和Book之间的关系

(1)显然,BookAuthor可以拥有一系列的Book,而某个Book也可以属于不同的作者BookAuthor(合作写的书)。

(2)很显然的,这个关联是双向的,而且在这个关联的两端都是“多”。我们将该形式的关联称为“多对多(many-to-many)关联”。因此,下面我们将使用Hibernate的many-to-many 映射。

注意:

关联表的主键实际上是个复合主键,同时使用了2个字段。这也暗示了对于同一个BookAuthor不能有重复的Book,这正是下面的代码中使用Set时候所需要的语义(Set里元素不能重复)。

1.1.3设计示例相关的POJO类

1、新增一个BookAuthor类,包名称为com.px1987.hexample.pobject

并且在BookAuthor类增加一组Book,这样我们可以轻松的通过调用aPerson.getBooks() 得到一个BookAuthor所拥有的Book列表,而不必执行一个显式的查询(一个单向的Set-based 关联)。

2、为POJO类添加相关的属性方法

下面我们使用一个Java的集合类:一个Set-----因为Set 不允许包括重复的元素而且排序和我们无关。

package com.px1987.hexample.pobject; import java.util.*;

public class BookAuthor

{

private int id;

private int authorAge;

private String firstName;

private String lastName;

public BookAuthor()

{

}

public int getId()

{

return id;

}

private void setId(int newId)

{

this.id = newId;

}

public int getAuthorAge()

{

return authorAge;

}

public void setAuthorAge(int newAuthorAge) {

this.authorAge = newAuthorAge;

}

public String getFirstName()

{

return firstName;

}

public void setFirstName(String newFirstName) {

this.firstName = newFirstName;

}

public String getLastName()

{

return lastName;

}

public void setLastName(String newLastName) {

https://www.doczj.com/doc/095209431.html,stName = newLastName;

}

public boolean equals(Object other)

{

if (this == other)

{

return true;

}

if ( !(other instanceof BookAuthor) )

{

return false;

}

return true;

}

private Set books = new HashSet();

public Set getBooks()

{

return books;

}

public void setBooks(Set newBooks)

{

this.books = newBooks;

}

}

1.1.4为实体类创建数据库表与实体之间的映射文件

为该实体类创建一个BookAuthor.hbm.xml映射文件1、新建一个BookAuthor.hbm.xml映射文件

2、该BookAuthor.hbm.xml映射文件的内容如下

PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"https://www.doczj.com/doc/095209431.html,/hibernate-mapping-3.0.dtd">

class="com.px1987.hexample.pobject.Book"/>

注意:

set的table参数决定用于关联的数据库表名,并且其name属性的值“books”应该与BookAuthor类中的books属性同名。key元素定义了在集合表中使用的外键。

同时由于BookAuthor表中的Author_ID的产生方式设置为“increment”,因此应该在该数据库表中首先有数据(本例给出下面的示例数据)。

3、的说明

一般情况下,cascade应该设置为“save-update”,对于多对多逻辑而言,很少出现删除一方需要级联删除所有关联数据的情况,如删除一个BookAuthor,一般不会删除其中包含的

Book(这些Book可能还被其他的BookAuthor所引用)。反之删除Book一般也不会删除其所关联的所有BookAuthor。

4、在hibernate.cfg.xml配置文件中增加对该文件的定义

"https://www.doczj.com/doc/095209431.html,/hibernate-configuration-3.0.dtd">

name="connection.datasource">java:comp/env/jdbc/datasource

false

org.hibernate.dialect.SQLServerDialect

5、设计中间的关联数据库表

(1)设计一个储存关联的表(association table),表名称为Author_Book

●对于多对多(many-to-many)关联(或者叫n:m实体关系), 需要一个用来储存关联的

表(association table)。

●表里面的每一行代表从一个Author到一个Book的一个关联。

●表名是由set元素的table属性值配置的。

●关联里面的标识字段名,Author的一端,是由元素定义,Book一端的字段名

是由元素的column属性定义的。

●我们也必须告诉Hibernate集合中对象的类(也就是位于这个集合所代表的关联另外

一端的类,本例为Book类)。

注意:

关联的表中的所有属性即为主键又为外键,并且分别参照原来的A,B两个表;关联的表中不可以有其他属性。

1.1.5实现BookAuthor与Book之间的关联

1、在HibernateDAOBean.java中增加一个产生中间关联数据库表中的各个关联数据的方法-------该方法一般应该设计在后台管理中

public void addAuthorToBook (int authorId, String bookId) throws HibernateException

{

Session session = HibernateUtil.currentSession();

Transaction tx = session.beginTransaction();

BookAuthor onePerson = (BookAuthor) session.load(BookAuthor.class, new Integer(authorId));

Book anBook = (Book) session.load(Book.class, bookId);

onePerson.getBooks().add(anBook);

https://www.doczj.com/doc/095209431.html,mit();

HibernateUtil.closeSession();

}

注意:

(1)通过该方法实现BookAuthor与Book之间的关联,从而产生出Author_Book关联表中的数据。

(2)在加载一个BookAuthor和一个Book之后,简单的使用普通的方法修改集合-------没有显式的update()或者save(), Hibernate自动检测到集合已经被修改并需要保存。这个叫做automatic dirty checking。

(3)只要他们处于persistent状态,也就是被绑定在某个Hibernate Session上,Hibernate监视任何改变并在后台隐式执行SQL。同步内存状态和数据库的过程,通常只在一个单元操作结束的时候发生,这个过程被叫做flushing。

2、在Web应用的组件中添加下面的代码

<%@ page contentType="text/html;charset=gb2312" %>

class="com.px1987.hexample.dao.HibernateDAOBean" />

<%

//************************************不带关联的测试代码***********************

int authorId =1234;

String bookId="402880ec118d2d7d01118d2d8b860001"; //根据实际的值来决定

hibernateDAOBean.addAuthorToBook (authorId, bookId);

%>

3、执行该组件

如果在前面的BookAuthor和Book两个表中都有相应的数据,只要执行该组件中的上面的代码,将产生出关联数据。

同时在数据库表中将增加一条记录

4、实现关联查询--------根据BookAuthor获得其关联的各个Book的信息

(1)在HibernateDAOBean.java中增加一个获得关联数据的方法

public Set getAuthorBooks(int authorId) throws HibernateException

{

Session session = HibernateUtil.currentSession();

BookAuthor onePerson = (BookAuthor) session.load(BookAuthor.class, new Integer(authorId));

java.util.Set allBooksByOnePerson=onePerson.getBooks();

return allBooksByOnePerson;

}

注意:由于我们希望能够采用延迟加载的技术,因此不应该在DAO中关闭Session。

(2)在Web应用的组件中添加下面的代码

<%@ page contentType="text/html;charset=gb2312" %>

class="com.px1987.hexample.dao.HibernateDAOBean" />

<%

//************************************不带关联的测试代码***********************

int authorId =1234;

java.util.Set allBooksByOnePerson =hibernateDAOBean.getAuthorBooks (authorId);

java.util.Iterator item = allBooksByOnePerson.iterator();

while (item.hasNext())

{

com.px1987.hexample.pobject.Book oneBook = (com.px1987.hexample.pobject.Book) item.next();

out.print("Book ID="+ oneBook.getId()+"    ");

out.print("Book Name="+ oneBook.getBookName()+"    ");

out.print("Book Kind="+ oneBook.getBookKind()+"    ");

out.print("Book Price="+ oneBook.getBookPrice()+"
");

}

%>

(3)部署并执行该组件

输入http://127.0.0.1:8080/HWebMapping/index.jsp

出现的状态提示内容

5、实现本示例在的双向关联

(1)映射一个双向关联(bi-directional association)

通过映射一个双向关联(bi-directional association),从而实现在Java程序中让BookAuthor 和Book可以从关联的任何一端访问另一端。当然,数据库表定义没有改变,我们仍然需要多对多(many-to-many)的阶数(multiplicity)。

(2)实现的过程-----首先,把一个拥有者(BookAuthor)的集合加入Book类中package com.px1987.hexample.pobject;

import java.util.*;

public class Book

{

private String id;

private String bookName;

private char bookKind;

private float bookPrice;

public Book()

{

}

public String getId()

{

return id;

}

private void setId(String id)

{

this.id = id;

}

public String getBookName()

{

return bookName;

}

public void setBookName(String newBookName) {

this.bookName = newBookName;

}

public char getBookKind()

{

return bookKind;

}

public void setBookKind(char newBookKind) {

this.bookKind = newBookKind;

}

public float getBookPrice()

{

return bookPrice;

}

public void setBookPrice(float newBookPrice) {

this.bookPrice = newBookPrice;

}

public boolean equals(Object other)

{

if (this == other)

{

return true;

}

if ( !(other instanceof Book) )

{

return false;

}

return true;

}

private Set authors = new HashSet(); public Set getAuthors()

{

return authors;

}

public void setAuthors(Set newAuthors) {

this.authors = newAuthors;

}

public void addToAuthor(BookAuthor oneAuthor)

{

this.getAuthors().add(oneAuthor);

oneAuthor.getBooks().add(this);

}

public void removeFromAuthor(BookAuthor oneAuthor)

{

this.getAuthors().remove(oneAuthor);

oneAuthor.getBooks().remove(this);

}

}

同时,也修改BookAuthor.java中的代码,加下面的代码package com.px1987.hexample.pobject;

import java.util.*;

public class BookAuthor

{

private int id;

private int authorAge;

private String firstName;

private String lastName;

public BookAuthor()

{

}

public int getId()

{

return id;

}

Hibernate配置文件的DTD

Hibernate中有两个配置文件 映射文件Xxx.hbm.xml 映射文件的的文件头DTD文件内容:

配置文件hibernate.cfg.xml 配置文件的文件头DTD文件内容: org.hibernate.dialect.MySQLDialect com.mysql.jdbc.Driver jdbc:mysql://localhost/minmin?characterEncoding=gb2312 root minmin true create

Hibernate练习题

Hibernate&EJB考试试题 1、下面关于Hibernate说法正确的是()(选择两项) A)Hibernate是ORM的一种实现方式 B)Hibernate不要JDBC的支持 C)属于控制层 D)属于数据持久层 2、下面关于ORM的说法错误的是()(选择两项) A)对象关系映射,让现实中的对象同数据库的表产生映射(类与表产生映射) B)对象关系映射,让类同表产生关系 C)对象关系映射,让类同记录产生关系(类的实例与记录(表中的一行数据)产生关系) D)对象关系映射,让类中的属性同表中的列产生关系 3、下面关于Hibernate中Session的说法正确的是()(选择两项) A)Session是轻量级的,可以随意的创建和销毁 B)Session是重量级的,不能随意的创建和销毁 C)Session是线程安全的 D)Session不是线程安全的 4、在Hibernate中,以下()不属于session的方法 A、close() B. open() C. update() D. delete() 5、下面关于Hibernate中load和get方法说法正确的是() A)这两个方法是一样的,没有任何的区别 B)这两个方法不一样,load先找缓存,再找数据库

C)这两个方法不一样,get先找缓存,再找数据库 D)以上说法都不对 注:load()和get()都是先找缓存,再找数据库。 不同点是在检索时: load()是延迟检索,先返回代理对象,访问对象时在发出sql命令Get()是立即检索,直接发出sql命令,返回对象 6、在Hibernate中修改对象的说话错误的是() A)只能利用update方法来做修改 B)可以利用saveOrUpdate方法来做修改 C)可以利用HQL语句来做修改 D)不能利用HQL语句来修改 7、下面关于Hibernate中Transaction的使用说法正确的是()(选择两项) A)Transaction是可有可无的 B)Transaction在做查询的时候是可有可无的 C)Transaction在做修改的时候是可有可无的 D)Transaction在做修改的时候是必须的 8、使用Hibernate技术实现数据持久化时,下面()内容不在 Hibernate配置文件中配置(选择一项) A) 数据库连接信息 B) 数据库类型(dialect) C) show_sql参数 D) 数据库表和实体的映射信息

Hibernate3.6(开发必看)

1.Java对象持久化概述 1.1.应用程序的分层体系结构 1.1.1.基于B/S的典型三层架构 说明: 1,展现层:提供与用户交互的界面。 2,业务逻辑层:实现各种业务逻辑。 3,数据访问层:负责存放和管理应用程序的持久化业务数据。 1.1. 2.数据访问层与Hibernate在Java应用程序中的 角色 数据访问层(持久化层)封装了数据访问的细节,为业务逻辑层提供了面向对象的API。完善的持久化层应该达到的目标: 1,代码重用性高,可完成所有的数据访问操作。 2,如果需要的话,能够支持多种数据库平台。 3,具有相对独立性,当持久化层变化时,不会影响上层实现。 在数据访问层(持久化层)中可以使用Hibernate框架以实现要求,如下图所示:

1.2.软件模型 1.2.1.各种模型的说明 概念模型: 模拟问题域中的真实实体。描述每个实体的概念和属性及实体间关系。不描述实体行为。实体间的关系有一对一、一对多和多对多。。 关系数据模型: 在概念模型的基础上建立起来的,用于描述这些关系数据的静态结构。有以下内容组成:1,若干表 2,表的所有索引 3,视图 4,触发器 5,表与表之间的参照完整性

域模型: 在软件的分析阶段创建概念模型,在软件设计阶段创建域模型。 组成部分: 1,具有状态和行为的域对象。 2,域对象之间的关联。 域对象(domain object): 构成域模型的基本元素就是域对象。对真实世界的实体的软件抽象,也叫做业务对象(Business Object,BO)。域对象可代表业务领域中的人、地点、事物或概念。 域对象分为以下几种: 1,实体域对象:通常是指业务领域中的名词。(plain old java object,简单Java 对象)。 2,过程域对象:应用中的业务逻辑或流程。依赖于实体域对象,业务领域中的动词。如发出订单、登陆等。 3,事件域对象:应用中的一些事件(警告、异常)。 1.2.2.域对象间的关系 关联: 类间的引用关系。以属性定义的方式表现。

用MyEclipse如何自动生成hibernate的.hbm.xml文件

用MyEclipse如何自动生成hibernate的.hbm.xml文件(2010-07-29 17:36:01) 今天在网上看到很多人都不知道怎么用MyEclipse自动生成hibernate的.hbm.xml文件。我甚至看到有位兄弟竟然自己写出那个格式的文件来。首先我不得不佩服那位兄弟的记忆力。可是我这边有更直接的方法希望能对那些入门级别的人一点帮助! 在hibernate中,每个数据表对应的其实是一个实体类,每个实体类有一个对应的hbm.xml 配置文件和你匹配,myeclipse中其实有个MyEclipse Database Explorer视图,它提供了myeclipse与数据库直接连接的内置窗口,并且通过此窗口可以生成hibernate的mapping文件。 1.在项目上点击右键选择MyEclipse选项,为应用增加Hibernate特性. 2.在出现的配置窗口中,选中“Add Hibernate 2.1 libraries to project?”,然后设定存放Hibernate 库文件的目录为:/WEB-INF/lib 目录,默认会选择创建一个新的Hibernate配置文件hibernate.cfg.xml。 3.点击下一步,进入Hibernate数据库连接配置界面,在Connection Profile选项中直接选择在MyEclipse Database Explorer中配置的vipdata选项,然后就会自动生成其他的配置,可以选择“Copy JDBC Driver and add to classpath”,这样就会将JDBC驱动拷贝到WEB-INF/lib目录中。: 4.点击下一步,来创建Hibernate的SessionFactory类,这是一个简单的集中管理Hibernate 会话的工厂类,填写类的全名称。 5.点击完成,然后MyEclipse就会将Hibernate相关的jar包拷贝到lib目录下,同时会生成Hibernate的配置文件:hibernate.cfg.xml,和SessionFactory类。 现在要利用MyEclipse Database Explorer视图中的工具来生成Hibernate的映射文件。切换到MyEclipse Database Explorer视图,在表vipdata上点击右键,选择Create Hibernate Mapping.

Hibernate(V)——一对多与多对多关联关系映射(xml与注解)总结

Hibernate(6)——一对多和多对多关联关系映射(xml和注解)总结 涉及的知识点总结如下: ?One to Many 映射关系 o多对一单向外键关联(XML/Annotation) o一对多单向外键关联(XML/Annotation) o懒加载和积极加载 o一对多双向外键关联(XML/Annotation) ?Many to Many 映射关系 o多对多单向外键关联(XML/Annotation) o多对多双向外键关联(XML/Annotation) o set的inverse元素详解 ?问题小结 ?关联关系的优缺点 多对一单向外键关联关系 注意多对一关联是多方持有一方的引用。看一个例子,去淘宝购物,那么一个淘宝用户可以对应多个购物订单,如图所示: 多的一方是Orders,持有一方的引用,也就是Users,而在Users中无需作任何定义,从订单到用户的关系是单向多对一关联。对应数据库就是: 还有比如说学生和班级的关系,多个学生可以属于同一个班级,这就是从学生到班级也是典型的单向多对一关系,看代码实现: 基于注解的多对一单向外键关联: 单向多对一关联中,多方需要持有一方的引用,那么多方(学生类)需要额外配置,需要对持有的一方引用使用注解@ManyToOne (cascade={CascadeType.ALL}, fetch=FetchType.EAGER),设置为级联操作和饥渴的抓取策略,@JoinColumn(name="cid"),而一方(教室类)无需做任何多方的定义。 注意;多方必须保留一个不带参数的构造器! import ; import ; import ; //班级类,在多对一关系中属于一的方,不持有其他多余的配置,反而是被多方持有

如何根据hibernate的实体类和实体类配置文件生成数据库的表

网络地址: 主题:如何根据hibernate的实体类和实体类配置文件生成数据库的表 内容部分 [c-sharp]view plaincopyprint? 1. 4. 5. 6. jdbc:mysql://12 7.0.0.1/lianxi 7. com.mysql.jdbc.Driver 8. root 9. root 10. org.hibernate.dialect.MySQLDialect 11. true 12. update 13. 14. 15. 16. 17. 18. 19.

hibernate关系映射注解配置

1. Hibernate Annotation关系映射有下面几种类型: 1)一对一外键关联映射(单向) 2)一对一外键关联映射(双向) 3)一对一主键关联映射(不重要,有需要看下文档即可) 在实际中很少用,使用注解@PrimaryKeyJoinColumn 意思是说,我的主键去参考另外一张表中的主键,作为我的主键,但是在我测试使用 注解一对一主键关联映射,在生成表的时候,数据库中并没有生成关联,使用XML 映射可以生成。Annotation注解一对一主键关联映,有些bug。不过没空去研究它。 因为在实际开发中一对一很少用。在实际开发中我机会没有用过,主键关联就更少了 4)多对一关联映射(单向) 5)一对多关联映射(单向) 6)一对多关联映射(双向) 7)多对多关联映射(单向) 8)多对多关联映射(双向) 2.介绍各种映射用法 1)一对一外键关联映射(单向)Husband ---> Wife public class Husband{ private Wife wife; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="wife_id",unique=true) public Wife getWife(){…} … } public class Wife{ } 一对一外键关联,使用@OneToOne,并设置了级联操作 @JoinColum设置了外键的名称为wife_id(数据库字段名),如果不设置,则默认为另一类的属性名+ _id 外键的值是唯一的(unique),不可重复,与另一类的主键一致 2)一对一外键关联映射(双向)Husband <---> Wife public class Husband{ private Wife wife; @OneToOne(cascade=CascadeType.ALL) @JoinColumn(name="wife_id",unique=true) public Wife getWife(){…} ... } public class Wife{ private Husband husband; @OneToOne(mappedBy="wife",cascade=CascadeType.ALL) public Husband getHusband(){…} ... } 一对一双向关联关系,使用@OneToOne 注意:需要加上mappedBy="wife",如果不加上的话,Wife也会生成一个外键(husband_id)。mappedby="wife"需要指向与他关联对象的一个属性(即Husband类里面的wife属性),这里的会在Husband表里面生成个外键wife_id字段,而Wife表里则不会生成。这里Husband作为维护端即主

利用轻量对象关系映射技术Hibernate提高开发效率

利用轻量对象关系映射技术Hibernate提高开发效率 Enhancing Development Efficiency with Hibernate a Lightweight Object/Relational Mapping Technology 谢挺 周维民 (上海大学机电工程与自动化学院,上海 200072) 摘 要 Hibernate是一种轻量对象关系映射技术。文章通过实例,介绍了Hibernate的一些关键特性,并阐述了该技术的一些局限性。 关键词 Hibernate 对象关系映射企业级JavaBeans 持久化 Abstract Hibernate is a lightweight Object/Relational Mapping(ORM) technology. Some key features of Hibernate are illustrated, and some limits of this technology are expounded. Keywords Hibernate Object/Relational Mapping (ORM) EJB Permanence 0 引言 随着internet的发展,应用服务程序已经从集中式、C/S模式过渡到B/S、分布式模式;无论是用户或是供应商都迫切希望缩短开发周期、提高开发效率,Hibernate应运而生。 1 Hibernate简介 Hibernate是一个面向Java环境的对象/关系数据库映射工具。对象/关系数据库映射(Object/Relational Mapping , ORM)这个术语表示一种技术,用来把对象模型表示的对象映射到基于SQL的关系模型中去。 Hibernate不仅提高Java类到数据库的映射,还提供数据查询和获取数据的方法。Hibernate在英语中的意思是“冬眠”,顾名思义它使得商务逻辑的开发和数据库最大程度地分离,可以大幅度减少开发时人工使用SQL和JDBC处理数据的时间。Hibernate的目标是解放开发者通常与数据持久化相关的编程任务的95%。对于那些在基于Java的中间层应用中,它们实现面向对象的业务模型和商业逻辑的应用,Hibernate是很有用的。 图1是Hibernate的体系结构图,从图中可以Array看到,系统为3层B/S模式,应用程序在客户端运 行将持久化的对象交由Hibernate。Hibernate通过 properties属性设置和XML Mapping实现商务逻 辑,调用和存储低层数据库后将返回的结果送给 客户端。 Hibernate对每一种数据库都有对应的 Dialect进行操作优化,从而提高它在各种情况 下的效率。目前,它的版本为3.0、支持的数据 库有Oracle、DB2、MySQL、PostgreSQL、Sybase,Interbase、Pointbase、Microsoft SQL Server、

Hibernate映射解决问题

Hibernate映射解决问题 做Hibernate映射已经做了五天了,期间遇到了不少错误,有的时候错误很细小,很难发现.现在就来总结一下,常见的错误,有的也是在网上搜了看到的! 第一种问题:Could not execute JDBC batch update 网上说有两种可能: 1.因为Hibernate Tools(或者Eclipse本身的Database Explorer)生成*.hbn.xml工具中包含有catalog="***"(*表示数据库名称)这样的属性,将该属性删除就可以了 2.估计是你的列名里面有关键字的原因吧,命名列的时候不要单独使用date,ID...这种关键字 但是,我觉得他写得不完全啦!我遇到的就不是两种原因,而是List映射时,对应表的索引项没有设成主键,所以就出错了.虽然找了蛮长时间的.同样, 它也会出现Duplicate entry '1' for key 1的错误啦! 第二种问题(归纳下): 1.Caused by: org.dom4j.DocumentException: Invalid byte 2 of 2-byte UTF-8 sequence. Nested exception: Invalid byte 2 of 2-byte UTF-8 sequence. 如果出现这行错误说明你的XML配置文件有不规范的字符,检查下。 2.net.sf.hibernate.MappingException: Error reading resource: hibernate/Hello_Bean.hbm.xml 如果出现这行错误说明你的hibernate的XML配置文件有错 3.net.sf.hibernate.MappingException: Resource: hibernate/Hello_Bean.hbm.xml not found 如果出现这行错误说明hibernate的XML配置文件没有找到,你应该把XML文件放在与你的类文件同个目录下,一般跟同名的java持久化类放在一起,也就是跟Hello_Bean.class类文件一起。4.net.sf.hibernate.PropertyNotFoundException: Could not find a setter for property name in class hibernate.Hello_Bean 如果出现这行错误说明你的xml文件里设置的字段名name的值与Hello_Bean.Java类里的getXXX 或setXXX方法不一致。 5.net.sf.hibernate.HibernateException: JDBC Driver class not found: org.gjt.mm.mysql.Driver:没有找到数据库驱动程序 6.The database return no natively generate indentity value。主键没有添加增量 7.net.sf.hibernate.PropertyValueException:not-null property references a null or transient value:com.pack.Rordercontent. 异常产生原因:Rordercontent对象的非空属性Rordertable引用了一个临时对象。 8.net.sf.hibernate.TransientobjectException:objiect references an unsaved transient instance –save the transient instance before flushing: com.pack.Rordertable 持久化对象的某个属性引用了一个临时对象Rordertable https://www.doczj.com/doc/095209431.html,.sf.hibernate.MappingException

Hibernate一对多映射

hibernate一对多关联映射—单向 一、简述 一对多关联映射(one-to-many) 1、在对象模型中,一对多的关联关系,使用集合表示 比如Classes(班级)和Student(学生)之间是一对多的关系 public class Classes{ private String id; private String name; private Set students; } public class Student{ public String id; public String name; } 2、我们以前学过学生对班级是多对一,返过来,班级对学生就是一对多。 3、我们多对一的关系是用户和组。返过来看,从组这边来看,就是一对多了。 下面学生的示例是班级和学生。和用户和组是一样的。 一个班级有多个学生,这是一对多的关系;返过来,多个学生属于一个班级,这就是多对一了。 4、建立对象模型 5、这两个对象模型之间是有关系的。我们现在讲的是一对多。一的一端是班级。多的一端是学生。那么怎么样能体现出这种关系呢? 我们在学习多对一时,是在多的一端加上一个字段。这个字段做为外键关联一的一端。多对一,就是我们在看到学生的时候,能够知道这个学生是哪个班级的。或者是当我们看到用户的时候,知道这个用户是哪个组的。所以在用户里面持有组的引用。 6、那么一对多,就是一个组里面有多少个用户。所以要维护这种关系,必须在组里面持有用户的集合。 班级和学生也是一样的。一个班级有多少学生,所以在班级里面要持有相应的学生的集合。如下图 我们用Set,通常用户Set做映射。

箭头表示两者之间是有关系的。 7、上面的是对象模型,那么这种模型要映射成什么样呢? 当我们定义多对一的关系时,在加载多的一端时,能够把1的一端加载上来。因为两者之间是有关系的。 同理,一对多也是一样的,它要维护这种关系。这种关系就是一对多。一的一端要指向多。在维护这种关系时,在加载一的时候,就会把一的一端加载上来。 也就是说,在我在加载班级时,这个班级有多少个学生,它会把所有的学生自动查询上来,放到Set集合里面。这就是维护这个关系的目的。 8、我们知道,实体类要映射成表。所在下面画两个表。 依我们来看,是先有班级。再分配学生。 学生有了,班级有了。要保证知道一个班级有多少学生。 因为students这个集合是在Classes上,要映射它的时候,那么我们是要在t_classes表上加一个字段,然后将所有的学生用,表达式表达出来吗?可是这样做不符合数据库的设计范式。 9、所以说,这种关系的维护应该是在t_student这一端。也就是说,在t_student表中加一个字段,这个字段就是classesid。 也就是说,一对多关联映射,要把两个表的关联字段加到多的一端。 10、所以说,一对多与多对一的映射是一样的。没有区别。都在多的一端加一个外键,指向一的一端。 但是两者也是有区别的。区别就是关系。如果维护的是多对一,则加载多的时候,能把1加上来。如果维护的是一对多,则加载班级时,能把WHSD1011对应的两个学生加载上来。 我的理解:对于要相关联的表来说,如果一个表想要看到对方的表内容,则就要在自己的实体类中持有对方的引用。 如果只有一方看到另一方,就是单向的。 如果要双方都看到,就要在实体模型中彼此都持有对方的引用。

hibernate映射文件property 元素属性

hibernate映射文件property 元素属性 property 元素 name:映射类属性的名字 可选属性: 1.column:对应数据库表的字段名默认值为属性名 2.type:字段的类型 3.update:update操作时是否包含本字段的数据默认值为true 4.insert:insert操作时是否包含本字段的数据默认值为true 5.formula:定义一个SQL来计算这个属性的值 6.access:Hibernate访问这个属性的策略默认值为property 7.unique:设置该字段值是否唯一默认值为false 8.not-null:设置该字段值是否可以为空默认值为false 9.property-ref:设置关联类的属性名,此属性和本类的关联相对应默认 值为关联类的主键 10.optimistic-lock:指定此属性做更新操作时是否需要乐观锁定默认值为 true https://www.doczj.com/doc/095209431.html,zy:指定是否采用延迟加载及加载策略默认值为proxy通过代理进行 关联可选值为 true此对象采用延迟加载并在变量第一次被访问时抓 取、false此关联对象不采用延迟加载 12.not-found:指定外键引用的数据不存在时如何让处理默认值为 exception产生异常可选值为ignore对不存在的应用关联到null 13.entity-name:被关联类的实体名 hibernate映射文件one-to-one 元素属性 1.one-to-one 元素 属性: https://www.doczj.com/doc/095209431.html,:映射类属性的名字 2.class:映射的目标类 3.cascade:设置操作中的级联策略可选值为 all所有操作情况均进行级 联、none所有操作情况均不进行级联、save-update执行更新操作时级联、delete执行删除操作时级联 4.constrained:表明当前类对应的表与被关联的表之间是否存在着外键约 束默认值为false

Hibernate 映射关联关系

Hibernate 映射关联关系 一、映射多对一关联关系。 1.单向的多对一 (1)以Customer 和Order 为例:一个用户可以发出多个订单,而一个订单只能属于一个客户。从Order 到Customer 是多对一关联关系。 (2)创建Customer 和Order 表。 Create (3)用Intellij Idea 自动生成关联关系,以及对应的Entitiy.hbm.xml 和持久化类。 说明: 其中Type 是用来修饰对应的Attribute Name 的。 在Order 端,定义Customer 类,一个订单属于一个客户。而在Customer 端,一个客户可以有多个订单,因为是单向的,所以这里放弃属性的添加。 在Join Columns 定义了Order 和Customer 之间的关联关系,order 表中的customer_id 外键和customer 表中的customer_id 主键关联。 来看生成的Schema: 没有勾选customer_id,是因为Intellij Idea 没法直接映射为Customer 类型的customer。 Order.hbm.xml 使用 节点来维护多对一关联关系。 name 属性:多这一端关联的一那一端的属性的名称。 class 属性:关联的一端的属性的类型。 column 属性:一那一端在多的一端对应的数据表中的外键。可以任意命名,但需要和数据表中的字段对应。 (4)单向多对一的CRUD 以及需要注意的问题。 <1> 新增

①先保存一的一端Customer,后保存多的一端Order。 Save.java 打印SQL: Output 结论:发送了3条INSERT 语句。 ②先保存多的一端Order,再保存一的一端Customer。 Save2.java 打印SQL: Output2 结论:发送了3条INSERT 语句,2条UPDATE 语句。 总结:在单向多对一的关联关系下,先插入 1 的一端会减少SQL 语句的执行,性能更高。 <2>删除 先删除1的一端。 Delete.java 控制台打印: Cannot delete or update a parent row: a foreign key constraint fails (`hibernate`.`order`, CONSTRAINT `FK_m6q2ofkj1g5aobtb2p00ajpqg` FOREIGN KEY (`customer_id`) REFERENCES `customer` (`customer_id`)) 结论:在不设置级联关系的前提下,不能删除 1 的一端。 <3>更新 Update.java Output <4>查询 ①查询n 的一端,但是不使用查询出来关联的 1 的一端的对象。 @Test public void testMany2OneGet() { Order order = (Order) session.get(Order.class, 1); System.out.println(order.getCustomer().getClass().getName()); } 复制代码

Hibernate考试试卷

Hibernate考试试题(题库) 1、在Hibernate中,下列说法正确的有()。【选三项】 A.Hibernate是一个开放源代码的对象关系映射框架 B.Hibernate对JDBC进行了轻量级的对象封装 C.Hibernate可以大大减少操作数据库的工作量 D.Hibernate提供了数据查询机制,但没有提供恢复机制 2、关于Hibernate,下列说法错误的是()。 A.Hibernate是一个对象-关系映射工具 B.在MVC模式中,Hibernate属于控制层 C.Hibernate在JDBC的方式上进行封装,以简化JDBC方式繁琐的编码工作 D.在Hibernate中,可以通过xml格式的配置文件保存对象-关系的映射信息 3、在Hibernate中,下列关于SessionFactory说法正确的有()。【选两项】 A.它是线程安全的 B.它不是线程安全的 C.它是轻量级的 D.一个SessionFactory实例对应一个数据存储源 4、在Hibernate中,下列关于Session说法正确的有()。【选三项】 A.它是线程安全的 B.它不是线程安全的 C.它是轻量级的 D.Session也被称为持久化管理器,它提供了和持久化相关的操作 5、在Hibernate中,下列关于Transaction说法正确的有()。【选三项】 A.事务Transaction为应用程序指定以原子操作单元为范围的对象 B.在对数据库进行增加、修改和删除操作时一定要加上Transaction C.在对数据库进行查询操作时一定要加上Transaction D.获得Transaction的方法:Transactiontr=session.beginTransaction(); 6、在Hibernate中,如果数据库是MySql或者SQLServer,则generator属性值不可 以使用()。 A.hilo B.native C.sequence D.indentity 7、在Hibernate中,如果数据库是Oracle或者DB2,则generator属性值不可以使用 ()。 A.hilo B.native C.sequence D.indentity 8、在Hibernate中,下列哪个选项不属于Session的方法()。 A.load B.save C.open

hibernate映射关系学习笔记

对象关联关系 一对一 单向:一方引用,在引用方加入被引用对象字段,注解@OneToOne 默认引用外键字段名为“被引用类名_id”,使用@JoinColumn(name=”your_name”)更改外键字段名 联合主键: @JoinColumns({ @JoinColumn(name="add_id",referencedColumnName="id"), @JoinColumn(name="add_code",referencedColumnName="areaCode") }) 双向:双方各自引用,都加入对方的引用,注解@OneToOne,表之间各自外键引用,不符合设计要求,通常一方引用,所以在被引用方法注解: @OneToOne(MappedBy=”引用方字段名”)。双向一般都设MappedBy 组件映射:一对一关系通常处理为在同一张表中存储数据,若程序端需要拆分成多个实体,使用组件映射方式@Embeded(在包含实体中注解) 若需要属性重写(改列名): @AttributeOverrides({ @AttributeOverride(name="fname",column=@Column(name="firstname")), @AttributeOverride(name="lname",column=@Column(name="lastname")) }) 多对一和一对多 多对一单向:在多方有一方的引用,注解@ManyToOne 一对多单向:在一的一方存在多方的集合(set),在一方注解@OneToMany 注意,Hibernate将一对多处理为多对多的特例,默认为两个关系表建中间表关联,所以加@JoinColumn 双向:多方注解@ManyToOne,一方注解@OneToMany(mappedBy="st")(st为多方引用一方对象名),注意一方不需再注解@JoinColumn 多对多 单向:在其中一方引用另外一方,类型为集合(set),注解@ManyToMany,若要改变中间表的表名及列名, 注解@JoinTable(name,joinColumns={@JoinColumn(name=”table1_id”)}, reverseJoinColumns={@JoinColumn(name=””)}) 双向:

在ECLIPSE中用HIBERNATE工具生成映射文件

总结的:在ECLIPSE中用HIBERNATE工具生成映射文件有截图 我们都知道HIBERNATE提供了工具供我们在ECLIPSE中使用生成对应的映射文件,但我一直用的都是myeclipse,兼容了需要导入的包,所以我对eclipse操作根本不熟,现在我在网上找了个案例,以后就不会头痛过了,(*^__^*) 嘻嘻…… 1.首先当然是从HIBERNATE官网上把工具下下来,放在ECLIPSE的对应的插件目录下 2.新建一个项目 3.把相应的JAR包加到你项目里 4.右击项目-〉new->Hibernate 选择Hibernate Configuration File(cfg.xml) 创建hibernate.cfg.xml文 件 5.(5)填写对应的数据库连接信息 如:Database dialet, connection URL, Default Schema, username, password等 记着:把下面那个Create a console configuration前面的钩钩上,下面会用它来创建映设文件 (6)点击NEXT,给你的Console Configuration 命个名,如test (7)FINISH你的hibernate.cfg.xml文件就建好了 下面是利用你的配置文件生成对应的映射JAVA文件 (8)进入hibernate Code Generation控制台,在Console configuration里选中你刚建的Console Configuration,如test (9)然后创建hibernate.reveng.xml 文件,选择新建 点击Refresh按钮,你的DB中的TABLE会列出来,然后将你要映射的表用INCLUDE按钮包含到右边的TABLE FILTERS中,点击FINISH (10)如下图,看看你要生成那些代码,把对应的钩打上,Apply-> Run ,OK,你对应的JAVA代码生成好了 注意:在我做以上步骤时曾发生过一下错误,重视下:

Hibernate之one-to-one主键关联映射

Hibernate之one-to-one主键关联映射one-to-one映射的例子为一个人拥有一个身份证,一个身份证属于一个人。 先创建po类 Person.java 1.package po; 2. 3.public class Person { 4.private int id; 5.private String name; //姓名 6.public int getId() { 7.return id; 8. } 9.public void setId(int id) { 10. this.id = id; 11. } 12. public String getName() { 13. return name; 14. } 15. public void setName(String name) { 16. https://www.doczj.com/doc/095209431.html, = name; 17. } 18. 19.} Card.java

1.package po; 2. 3.public class Card { 4.private int id; //身份证ID 5.private String number; //身份证号码 6.private Person person; //一个身份证号对应一个人 7. 8.public int getId() { 9.return id; 10. } 11. public void setId(int id) { 12. this.id = id; 13. } 14. public String getNumber() { 15. return number; 16. } 17. public void setNumber(String number) { 18. this.number = number; 19. } 20. public Person getPerson() { 21. return person; 22. } 23. public void setPerson(Person person) { 24. this.person = person; 25. } 26. 27. 28. 29. 30.}

Hibernate一对一映射配置详解

Hibernate一对一映射配置详解 雪飘寒 目录 Hibernate一对一映射配置详解 (1) 一、xml文件配置 (2) 1. 主键关联 (3) 2. 单方外键关联 (4) 3. 双方外键关联 (5) 二、注释方式配置(Annotation) (6) 1、主键关联 (6) 2. 单方外键关联 (7) 3. 双方外键关联 (8)

一对一关联分为主键关联与外键关联。 主键关联:不必加额外的字段,只是主表和辅表的主键相关联,即这两个主键的值是一样的。 外键关联:辅表有一个额外的字段和主表相关联,或者两个表都有额外的字段与对应表的相关联。一、xml文件配置 官方文档解释 (1) name: 属性的名字。 (2) class (可选 - 默认是通过反射得到的属性类型):被关联的类的名字。 (3) cascade(级联) (可选):表明操作是否从父对象级联到被关联的对象。 (4) constrained(约束) (可选):表明该类对应的表对应的数据库表,和被关联的对象所对应的数据库表之间,通过一个外键引用对主键进行约束。这个选项影响save()和delete()在级联执行时的先后顺序以及决定该关联能否被委托(也在schema export tool中被使用). (5) fetch (可选 - 默认设置为选择): 在外连接抓取或者序列选择抓取选择其一. (6) property-ref (可选):指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键。 (7) access (可选 - 默认是 property): Hibernate用来访问属性的策略。 (8) formula (可选):绝大多数一对一的关联都指向其实体的主键。在一些少见的情况中,你可能会指向其他的一个或多个字段,或者是一个表达式,这些情况下,你可以用一个SQL公式来表示。(可以在org.hibernate.test.onetooneformula找到例子) (9) lazy (可选 - 默认为 proxy): 默认情况下,单点关联是经过代理的。lazy="no-proxy"指定此属性应该在实例变量第一次被访问时应该延迟抓取(fetche lazily)(需要运行时字节码的增强)。lazy="false"指定此关联总是被预先抓取。注意,如果constrained="false", 不可能使用代理,Hibernate会采取预先抓取! (10) entity-name (可选): 被关联的类的实体名。

相关主题
文本预览
相关文档 最新文档