对象关系映射(Object Relational Mapping)是将关系数据库中表的数据映射成对象,方便开发人员以面向对象思想操作数据库的技术。Hibernate是Java领域内的一款开源的ORM框架技术,与Spring,Struts组成大名鼎鼎的SSH,在JavaEE中占有重要地位。
1,Hibernate对JDBC进行非常轻量级的封装。
(从本质上而言,最终Hibernate还是通过JDBC来进行对数据库的操作,只不过在JDBC的基础上进行了一定的封装)
2,与EBJ(本身是JavaEE的规范,重量级的ORM框架技术)不同,Hibernate属于轻量级的ORM框架技术。
3,Hibernate介于数据库层和业务逻辑层之间,起到持久化层的作用。
4. Hibernate3 提供了属性的延迟加载功能
当Hibernate在查询数据的时候,数据并没有存在于内存中,当程序真正对数据的操作时,对象才存在于内存中,就实现了延迟加载,他节省了服务器的内存开销,从而提高了服务器的性能。
5. hibernate使用Java反射机制,而不是字节码增强程序来实现透明性。
Hibernate中,按照数据的管理方式分为单向和双向,单向就是一方控制另一方,双向就是互相都可以控制。根据数据的实际联系又可以分为一对一,一对多,多对一和多对多。,因为双向的一对多和多对一是一样的,所以最终有7种映射关系。
单向:一对一,多对一,一对多,多对多
双向:一对一,多对一(一对多),多对多
有两种策略可以实现一对一的关联映射:
主键关联:即让两个对象具有相同的主键值,以表明它们之间的一一对应的关系;数据库表不会有额外的字段来维护它们之间的关系,仅通过表的主键来关联
唯一外键关联:外键关联,本来是用于多对一的配置,但是加上唯一的限制之后(采用标签来映射,指定多的一端unique为true,这样就限制了多的一端的多重性为一),也可以用来表示一对一关联关系,其实它就是多对一的特殊情况。
public class IdCard {
private int id;
private String cardNo;
/**setters & getters**/
}
public class User {
private int id;
private String name;
private IdCard idCard;
/**setters & getters**/
}
IdCard.hbm.xml映射文件:
<hibernate-mapping>
<class name="com.hibernate.IdCard" table="t_idCard">
<id name="id">
<column name="id"/>
<generator class="native">generator>
id>
<property name="cardNo" type="jave.long.String">
<column name="card_no"/>
property>
class>
hibernate-mapping>
User.hbm.xml映射文件:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.User" table="t_user">
<id name="id">
<column name="id"/>
<generator class="native">
<param name="property">idCardparam>
generator>
id>
<property name="name" type="java.long.String">
<column name="name"/>
property>
<many-to-one name="idCard" class="com.hibernate.IdCard" column="id_card" unique="true"/>
<one-to-one name="idCard" class="com.hibernate.IdCard" constrained="true"/>
class>
hibernate-mapping>
一个例子是员工分组,把所有的员工分到不同的部门
public User{
private Integer id;
private String name;
private Integer idGroup;
}
publiv Group{
private Integer id;
private String name;
}
User.hbm.xml
<class name="com.hibernate.User" table="t_user">
<id name="id" type="java.long.Integer">
name="id"/>
class="native">
id>
<property name="name" type="java.long.String">
name="name"/>
property>
to-one name="idGroup" column="id_group" class="com.hibernate.Group"/>
class>
Group.hbm.xml
<hibernate-mapping>
<class name="com.hibernate.Group" table="t_group">
<id name="id" type="java.long.Integer">
<column name="id"/>
<generator class="native">generator>
id>
<property name="name" type="java.long.String">
<column name="name"/>
property>
class>
hibernate-mapping>
public class Goods{
private Integer id;
private String name;
private Set transHistory = new HashSet();
}
public class TransHistory{
private Integer id;
private Integer sum;
private Double price;
private Integer idGoods;
}
Goods.hbm.xml
<class name="com.hibernate.Goods" table="t_goods">
<id name="id" type="java.long.Integer" >
name="id"/>
class="native">
id>
<property name="name" type="java.long.String">
name="name"/>
property>
<set name="transHistory">
"id_goods"/>
to-many class="com.hibernate.TransHistory"/>
set>
class>
TransHistory.hbm.xml
<class name="com.hibernate.TransHistory" table="t_trans_history">
<id name="id" type="java.long.Integer" >
name="id"/>
class="native">
id>
<property name="sum" type="java.long.Integer">
name="sum"/>
property>
<property name="price" type="java.long.Double">
name="price"/>
property>
class>
一对多与多对一的区别是维护的关系不同
*多对一维护的关系是:多指向一的关系,有了此关系,加载多的时候可以将一加载上来
*一对多维护的关系是:一指向多的关系,有了此关系,在加载一的时候可以将多加载上来
较好的例子是员工任务分配,每个员工可能要负责多个任务,负责每项任务都需要多名员工共同完成
和前面的员工分组略有区别,变成了多对多的关系
多对多需要一张额外的数据表来关联两组数据的主键,关联表要取合适的表名来说明是关联表,例如“id_表一表二”,或者“表一表二_xref”
依然使用上面的类
public User{
private Integer id;
private String name;
//不在使用单一ID作为对应
//private Integer groupId;
//转使用set进行多对多映射
private Set<Group> group=new HashSet<Group>();
}
publiv Group{
private Integer id;
private String name;
private Set<User> user=new HashSet<User>();
}
User.hbm.xml
<class name="com.hibernate.User" table="t_user">
<id name="id" type="java.long.Integer">
name="id"/>
class="native">
id>
<property name="name" type="java.long.String">
name="name"/>
property>
<set name="group" table="t_user_group">
"id_user"/>
to-many class="com.hibernate.Group" column="id_group"/>
set>
class>
Group.hbm.xml
<class name="com.hibernate.Group" table="t_group">
<id name="id" type="java.long.Integer">
name="id"/>
class="native">
id>
<property name="name" type="java.long.String">
name="name"/>
property>
<set name="user" table="t_user_group">
"id_group"/>
to-many class="com.hibernate.User" column="id_user"/>
set>
class>
就是将两个关联类都加上标签:
public class IdCard {
private int id;
private String cardNo;
/**setters & getters**/
}
public class User {
private int id;
private String name;
private IdCard idCard;
/**setters & getters**/
}
IdCard.hbm.xml映射文件:
<class name="com.hibernate.IdCard" table="t_idCard">
<id name="id">
name="id"/>
class="native">
id>
<property name="cardNo" type="jave.long.String">
name="card_no"/>
property>
to-one name="idCard"/>
class>
User.hbm.xml映射文件:
<hibernate-mapping>
<class name="com.bjpowernode.hibernate.User" table="t_user">
<id name="id">
<column name="id"/>
<generator class="native">
<param name="property">idCardparam>
generator>
id>
<property name="name" type="java.long.String">
<column name="name"/>
property>
<one-to-one name="idCard" class="com.hibernate.IdCard">
<one-to-one name="idCard" class="com.hibernate.IdCard" property-ref="idCard"/>
class>
hibernate-mapping>
就是将单向的一对多和多对一结合起来即可
同理也是在两个配置文件中写两个
即可
可能有错误,欢迎批评指正,之后会继续深入学习