`

hibernate对象关系映射

 
阅读更多

(一)、Hibernate中持久化类的访问者有两个:

  1. Java应用程序
  2. hibernate(何时调用getset方法?)
  3. 注意:Java应用程序不能访问持久化类的private方法,而hibernate没有这个限制,它可以访问各种级别的方法。(例如提供私有的getXxx和setXxx方法,解决数据库字段跟domain属性不一致的问题而不影响设计)。
public class User {
	private Long id;
	private String name;
	private String firstName;
	private String secondName;

	/*
	 * 问题:domain设计成了firstName 和
	 * secondName,但是数据库表中我们设计成了fullName,在hibernate中我们如何对应字段关系?
	 * 
	 * 解决方案: 提供fullName的getter和setter,为了不影响业务需要(不被其他类访问),我们将其设置为private的,这样,
	 * 我们只需要将domain对应的映射文件中,对应的数据表的字段名称修改为fullName,就可以解决该问题
	 */
	private String getFullName() {
		return firstName + "," + secondName;
	}

	private void setFullName(String fullName) {
		String[] names = fullName.split(",");
		this.firstName = names[0];
		this.secondName = names[1];
	}

	...省略其他字段的getter和setter和tostring方法...

}
在映射文件中的配置:
<hibernate-mapping package="sun.domain">
	<class name="User" table="user">
		<id name="id" column="id">
			<generator class="native" />
		</id>
		<property name="name" column="NAME" />
		<!-- name为fullName,则hibernate会根据该名字去找getFullName和setFullName方法,即时是私有的方法 -->
		<property name="fullName" column="FULL_NAME" />
	</class>
</hibernate-mapping>

测试代码:

@Test
public void testSave() {
	Session s = util.getSession();
	for (int i = 0; i < 100; i++) {
		Transaction tx = s.beginTransaction();
		User e = new User();
		e.setName("userName" + i);
		e.setFirstName("firstName" + i);
		e.setSecondName("secondName" + i);
		// 保存
		s.save(e);
		tx.commit();
	}
	s.close();
}
结果:
mysql> select * from user;
+-----+------------+--------------------------+
| id  | NAME       | FULL_NAME                |
+-----+------------+--------------------------+
|   1 | userName0  | firstName0,secondName0   |
|   2 | userName1  | firstName1,secondName1   |
|   3 | userName2  | firstName2,secondName2   |
|   4 | userName3  | firstName3,secondName3   |
|   5 | userName4  | firstName4,secondName4   |
…………


(二)、Hibernate访问持久化类属性的策略

  • property默认值:表明hibernate通过getXXX和setXXX来访问类属性。推荐使用。提高域模型透明性。
  • field:hibernate通过java反射机制直接访问类属性。对于没有javabean方法的属性可设置该访问策略。

如:

<property name=“name” access=“field” />

注意:除了设置property属性的access为field和property之外,还可以自定义访问策略,需要创建实现org.hibernate.

property.PropertyAccessor接口的类.然后把类的完整名字赋值给<property>元素的access属性。


(三)、基本数据类型和包装类型的映射

基本数据类型和包装类型对应的hibernate映射类型相同.type属性为我们提供指定特殊的类型的入口,我们可以修改type

性来重新修改数据表的字段属性。

<property name=“price” type=“double” column=“PRICE” />

  • 基本类型可直接运算、无法表达null、数字类型的默认值为0
  • 包装类默认值是null。当对于默认值有业务意义的时候需要使用包装类。

hibernate的type属性与java数据类型对照表:

Java数据类型

Hibernate数据类型

标准SQL数据类型

对于不同的DB可能有所差异)

java.util.Date、java.sql.Timestamp

timestamp

TIMESTAMP

java.util.Calendar

calendar

TIMESTAMP

java.util.Calendar

calendar_date

DATE

byte[]

binary

VARBINARY、BLOB

java.lang.String

text

CLOB

java.io.Serializable

serializable

VARBINARY、BLOB

java.sql.Clob

clob

CLOB

java.sql.Blob

blob

BLOB

java.lang.Class

class

VARCHAR

java.util.Locale

locale

VARCHAR

java.util.TimeZone

timezone

VARCHAR

java.util.Currency

currency

VARCHAR

如:
private Date birthday;
private Date registerTime;

<property name="birthday" column="birthday" type="date"/>
<property name="registerTime" type="timestamp"/>

(四)、控制insert、update语句

Java数据类型

Hibernate数据类型

标准SQL数据类型

对于不同的DB可能有所差异)

byte、java.lang.Byte

byte

TINYINT

short、java.lang.Short

short

SMALLINT

int、java.lang.Integer

integer

INGEGER

long、java.lang.Long

long

BIGINT

float、java.lang.Float

float

FLOAT

double、java.lang.Double

double

DOUBLE

java.math.BigDecimal

big_decimal

NUMERIC

char、java.lang.Character

character

CHAR(1)

boolean、java.lang.Boolean

boolean

BIT

java.lang.String

string

VARCHAR

boolean、java.lang.Boolean

yes_no

CHAR(1)('Y'或'N')

boolean、java.lang.Boolean

true_false

CHAR(1)('Y'或'N')

java.util.Date、java.sql.Date

date

DATE

java.util.Date、java.sql.Time

time

TIME

映射属性

作用

<property>

insert属性

若为false,在insert语句中不包含该字段,该字段永远不能被插入。默认值true。

<property>

update属性

若为false,update语句不包含该字段,该字段永远不能被更新。默认值为true。

<class>

mutable属性

若为false,等价于所有的<property>元素的update属性为false,整个实例不能被更新。默认为true。

<class>

dynamic-insert属性

若为true,保存一个对象时,动态生成insert语句,语句中仅包含取值不为null的字段。默认false。

<class>

dynamic-update属性

若为true,更新一个对象时,动态生成update语句,语句中仅包含取值不为null的字段。默认false。

我们知道,sql语句如果传递的字段值为null,则数据库中表字段的值为null,这样我们表中存在许多null的数据,以上属性为我们提供解决此类问题的办法。

(五)、处理sql标示符、关键字

SQL语法中,标识符是指用于为数据库表、视图、字段或索引等命名的字符串,常规标识符不包括空格,也不包含特殊字符,因此无需使用引用符号。如果数据库表名或列名包含特殊字符,可以使用引用标识符。

<property name=“description” column=“`CUSTOMER DESCRIPTION`” />


(六)手动导入类

当我们的项目在不同的包下有相同名称的两个类时,在插入数据的时候会出现错误:

java.lang.ExceptionInInitializerError
	at sun.domain2.TestUser.test(TestUser.java:15)
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
	at java.lang.reflect.Method.invoke(Method.java:597)
	at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:44)
	at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
	at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
	at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:27)
	at org.junit.runners.BlockJUnit4ClassRunner.runNotIgnored(BlockJUnit4ClassRunner.java:79)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:71)
	at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:49)
	at org.junit.runners.ParentRunner$3.run(ParentRunner.java:193)
	at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:52)
	at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
	at org.junit.runners.ParentRunner.access$000(ParentRunner.java:42)
	at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:184)
	at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
	at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
	at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
	at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)
Caused by: org.hibernate.InvalidMappingException: Could not parse mapping document from resource sun/domain2/User.hbm.xml
	at org.hibernate.cfg.Configuration.addResource(Configuration.java:671)
	at org.hibernate.cfg.Configuration.parseMappingElement(Configuration.java:1679)
	at org.hibernate.cfg.Configuration.parseSessionFactory(Configuration.java:1647)
	at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1626)
	at org.hibernate.cfg.Configuration.doConfigure(Configuration.java:1600)
	at org.hibernate.cfg.Configuration.configure(Configuration.java:1520)
	at org.hibernate.cfg.Configuration.configure(Configuration.java:1506)
	at sun.util.HibernateUtil.<init>(HibernateUtil.java:12)
	at sun.util.HibernateUtil.<clinit>(HibernateUtil.java:8)
	... 24 more
Caused by: org.hibernate.DuplicateMappingException: duplicate import: User refers to both sun.domain2.User and sun.domain.User (try using auto-import="false")
	at org.hibernate.cfg.Configuration$MappingsImpl.addImport(Configuration.java:2418)
	at org.hibernate.cfg.HbmBinder.bindPersistentClassCommonValues(HbmBinder.java:667)
	at org.hibernate.cfg.HbmBinder.bindClass(HbmBinder.java:581)
	at org.hibernate.cfg.HbmBinder.bindRootClass(HbmBinder.java:319)
	at org.hibernate.cfg.HbmBinder.bindRoot(HbmBinder.java:172)
	at org.hibernate.cfg.Configuration.add(Configuration.java:771)
	at org.hibernate.cfg.Configuration.addInputStream(Configuration.java:606)
	at org.hibernate.cfg.Configuration.addResource(Configuration.java:668)
	... 32 more

问题分析:hibernate为这两个相同类名的类生成了相同的简写名称,所以我们在Insert into User values(。。。)的时候,不能区别当前的User是对应哪一个类。

解决方案:将hibernate的自动导入功能取消,而改为手动导入,并为其指定不同的别名。

修改后的配置:

<!-- auto-import属性标示hibernate的导入类的方式,默认为true -->
<hibernate-mapping package="sun.domain2" auto-import="false">
	<!-- 手动导入类并指定别名 -->
	<import class="sun.domain2.User" rename="User2" />
	<class name="User" table="user">
		<id name="id" column="id">
			<generator class="native" />
		</id>
		<property name="name" column="NAME" />
		<!-- name为fullName,则hibernate会根据该名字去找getFullName和setFullName方法,即时是私有的方法 -->
		<property name="fullName" column="FULL_NAME" />
	</class>
</hibernate-mapping>
分享到:
评论

相关推荐

    Hibernate对象关系映射

    Hibernate对象关系映射一对多 很基础等文档

    hibernate对象关系映射实例

    标题“Hibernate对象关系映射实例”表明我们将探讨的是使用Hibernate框架进行对象关系映射(ORM)的实际应用。ORM是将数据库表结构映射为Java类对象的一种技术,它使得开发者可以使用面向对象的方式来操作数据库,而...

    基于Java的Hibernate对象关系映射框架设计源码

    该项目是基于Java的Hibernate对象关系映射框架设计源码,包含11786个文件,其中Java源文件10296个,XML配置文件794个,SQL脚本235个,AsciiDoc文档71个,HTML文件60个,CSS样式表59个,JavaScript脚本59个,属性文件...

    hibernate对象关系映射案例demo

    **hibernate对象关系映射案例demo** 在Java开发领域,对象关系映射(ORM)是一种将数据库中的数据与程序中的对象进行关联的技术,它极大地简化了数据操作。Hibernate作为一款流行的ORM框架,使得开发者无需关注底层...

    Hibernate 对象关系映射

    本人在厦门邦初培训时候用的ppt 快速入门文档 内容: 建立一对多的关联关系域模型 建立一对多的参照关系的模型 映射一对多关联关系 通过hibernateAPI级联操作关联对象 其它关系的映射:一对一,多对多

    基于Java语言的Hibernate对象关系映射技术课程设计源码

    该项目是一个基于Java语言的Hibernate对象关系映射技术课程设计源码,共计48个文件,包括24个JAR包文件、13个XML配置文件、8个Java源文件、2个Git忽略文件以及1个Idea项目文件。该课程设计旨在让学生深入理解对象...

    对象-关系映射—Hibernate 培训 (中文)

    对象-关系映射—Hibernate 培训 (中文) 目录 一、持久化层-O/R Mapping 二、Hibernate入门 三、Hibernate映射申明(Mapping declaration) 四、持久化对象的状态和生命周期 五、Hibernate查询 六、Hibernate最佳...

    hibernate的关系映射

    在Java编程领域,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,将Java对象与数据库表之间的交互转化为简单的API调用。关系映射是Hibernate的核心特性之一,它允许我们将复杂的数据库结构与...

    hibernate关联关系映射

    在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者将数据库操作转换为面向对象的方式,从而简化了数据访问层的编程。"hibernate关联关系映射"是Hibernate的核心概念之一,它定义了如何...

    JAVA数据类型与Hibernate的类型映射

    在Java编程语言中,...这涉及到对Java基本类型、复杂类型以及自定义对象的映射,还包括对数据库NULL值的处理、对象关系映射以及工具的使用策略。熟悉这些知识,可以帮助开发者更高效地利用Hibernate进行数据持久化。

    对象/关系映射

    对象/关系映射 —Hibernate 对象/关系映射 —Hibernate 对象/关系映射 —Hibernate

    hibernate的多种映射关系

    Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库,消除了直接编写 SQL 的需要。在 Hibernate 中,映射关系是将数据库表与 Java 类之间的关联方式,使得对象模型可以与关系...

    Hibernate关系映射

    在Java世界中,Hibernate是一个强大的对象关系映射(ORM)框架,它允许开发者将数据库操作转化为面向对象的方式,极大地简化了数据持久化的复杂性。"多对一"关系映射是Hibernate支持的四种基本关联类型之一,包括一...

    Hibernate教程09_关系映射之组件映射

    Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,它允许开发人员以面向对象的方式处理数据库操作,极大地简化了数据层的开发。组件映射是Hibernate中的一种高级映射策略,用于将一个类的属性组织成一个...

    Hibernate继承关系映射.pdf

    标题:“Hibernate继承关系映射.pdf” 描述:“简明扼要地介绍了Hibernate中继承关系的映射方式,深入探讨了三种不同的映射策略及其优缺点,同时解析了多态查询的概念。” 知识点: ### Hibernate继承关系映射...

    Hibernate对象关系详解

    **Hibernate对象关系详解** 在Java世界中,Hibernate作为一款强大的对象关系映射(ORM)框架,使得开发者可以方便地在Java对象与数据库表之间进行数据操作。本篇将深入探讨Hibernate中的对象关系映射,包括一对一...

    开源对象关系映射框架Hibernate知识培训

    标题和描述都在强调"开源对象关系映射框架Hibernate知识培训",这意味着主要内容将围绕Hibernate这一框架,探讨如何进行对象关系映射(ORM)以及相关的学习和应用。 **对象关系映射(ORM)** 对象关系映射(Object...

    hibernate中的对象关系映射

    【hibernate中的对象关系映射】是Java开发中一种重要的技术,它允许开发者使用面向对象的方式来处理数据库操作,从而避免了直接与SQL打交道的复杂性。Hibernate是Java领域的一个ORM框架,它提供了数据持久化的解决...

    hibernate map 集合映射

    在Java的持久化框架Hibernate中,集合映射是将数据库中的表关系映射到对象的集合属性上,以便更好地管理和操作数据。这篇文章将深入探讨Hibernate中的集合映射机制,包括其基本概念、类型以及如何在实际开发中进行...

Global site tag (gtag.js) - Google Analytics