(一)、Hibernate中持久化类的访问者有两个:
- Java应用程序
- hibernate(何时调用get、set方法?)
- 注意: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框架进行对象关系映射(ORM)的实际应用。ORM是将数据库表结构映射为Java类对象的一种技术,它使得开发者可以使用面向对象的方式来操作数据库,而...
该项目是基于Java的Hibernate对象关系映射框架设计源码,包含11786个文件,其中Java源文件10296个,XML配置文件794个,SQL脚本235个,AsciiDoc文档71个,HTML文件60个,CSS样式表59个,JavaScript脚本59个,属性文件...
**hibernate对象关系映射案例demo** 在Java开发领域,对象关系映射(ORM)是一种将数据库中的数据与程序中的对象进行关联的技术,它极大地简化了数据操作。Hibernate作为一款流行的ORM框架,使得开发者无需关注底层...
本人在厦门邦初培训时候用的ppt 快速入门文档 内容: 建立一对多的关联关系域模型 建立一对多的参照关系的模型 映射一对多关联关系 通过hibernateAPI级联操作关联对象 其它关系的映射:一对一,多对多
该项目是一个基于Java语言的Hibernate对象关系映射技术课程设计源码,共计48个文件,包括24个JAR包文件、13个XML配置文件、8个Java源文件、2个Git忽略文件以及1个Idea项目文件。该课程设计旨在让学生深入理解对象...
对象-关系映射—Hibernate 培训 (中文) 目录 一、持久化层-O/R Mapping 二、Hibernate入门 三、Hibernate映射申明(Mapping declaration) 四、持久化对象的状态和生命周期 五、Hibernate查询 六、Hibernate最佳...
在Java编程领域,Hibernate是一个强大的对象关系映射(ORM)框架,它简化了数据库操作,将Java对象与数据库表之间的交互转化为简单的API调用。关系映射是Hibernate的核心特性之一,它允许我们将复杂的数据库结构与...
在Java世界中,Hibernate是一个非常流行的ORM(对象关系映射)框架,它允许开发者将数据库操作转换为面向对象的方式,从而简化了数据访问层的编程。"hibernate关联关系映射"是Hibernate的核心概念之一,它定义了如何...
在Java编程语言中,...这涉及到对Java基本类型、复杂类型以及自定义对象的映射,还包括对数据库NULL值的处理、对象关系映射以及工具的使用策略。熟悉这些知识,可以帮助开发者更高效地利用Hibernate进行数据持久化。
对象/关系映射 —Hibernate 对象/关系映射 —Hibernate 对象/关系映射 —Hibernate
Hibernate 是一个流行的对象关系映射(ORM)框架,它允许开发者使用 Java 对象来操作数据库,消除了直接编写 SQL 的需要。在 Hibernate 中,映射关系是将数据库表与 Java 类之间的关联方式,使得对象模型可以与关系...
在Java世界中,Hibernate是一个强大的对象关系映射(ORM)框架,它允许开发者将数据库操作转化为面向对象的方式,极大地简化了数据持久化的复杂性。"多对一"关系映射是Hibernate支持的四种基本关联类型之一,包括一...
Hibernate作为Java领域中广泛使用的对象关系映射(ORM)框架,它允许开发人员以面向对象的方式处理数据库操作,极大地简化了数据层的开发。组件映射是Hibernate中的一种高级映射策略,用于将一个类的属性组织成一个...
标题:“Hibernate继承关系映射.pdf” 描述:“简明扼要地介绍了Hibernate中继承关系的映射方式,深入探讨了三种不同的映射策略及其优缺点,同时解析了多态查询的概念。” 知识点: ### Hibernate继承关系映射...
**Hibernate对象关系详解** 在Java世界中,Hibernate作为一款强大的对象关系映射(ORM)框架,使得开发者可以方便地在Java对象与数据库表之间进行数据操作。本篇将深入探讨Hibernate中的对象关系映射,包括一对一...
标题和描述都在强调"开源对象关系映射框架Hibernate知识培训",这意味着主要内容将围绕Hibernate这一框架,探讨如何进行对象关系映射(ORM)以及相关的学习和应用。 **对象关系映射(ORM)** 对象关系映射(Object...
【hibernate中的对象关系映射】是Java开发中一种重要的技术,它允许开发者使用面向对象的方式来处理数据库操作,从而避免了直接与SQL打交道的复杂性。Hibernate是Java领域的一个ORM框架,它提供了数据持久化的解决...
在Java的持久化框架Hibernate中,集合映射是将数据库中的表关系映射到对象的集合属性上,以便更好地管理和操作数据。这篇文章将深入探讨Hibernate中的集合映射机制,包括其基本概念、类型以及如何在实际开发中进行...