1. 两种配置文件
Hibernate配置文件如下:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- MySQL connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/shopping_cart</property>
<property name="connection.username">chujq</property>
<property name="connection.password">7729</property>
<!--使用数据源-->
<!-->
<property name="connection.datasource">java:comp/env/jdbc/mysql</property>
-->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="show_sql">true</property>
<property name="format_sql">true</property>
<property name="cache.provider_class">
org.hibernate.cache.NoCacheProvider</property>
<mapping resource="com/chu/shopping/model/entity/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
在以上的配置文件中的内容包括以下部分:
(1) 配置数据库连接的信息以及数据库使用的言
(2) 运行中SQL语句的显示与格示
(3) 是否使用缓存
(4) 映射类配置文件
(5) 若在META-INF的context.xml中配置数据源则使用:
<property name="connection.datasource">java:comp/env/jdbc/mysql</property>
Context.xml文件如下:
<Context>
<Resource name="jdbc/mysql" auth="Container" type="javax.sql.DataSource"
maxActive="10" maxIdle="5" maxWait="-1"
username="root" password="1234" driverClassName="com.mysql.jdbc.Driver" url="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=gbk"/>
</Context>
类映射文件Student.hbm.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.allanlxf.hbn.o2o">
<class name="Car" table="car_o2o_pk">
<id name="id" column="id" type="integer">
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<property name="manufacture" column="manufacture" type="string"/>
<one-to-one name="engine" class="Engine" cascade="all"/>
</class>
</hibernate-mapping>
2. Hibernate的编程步骤
具体可以分为以下七个步骤:
1.Configuration = new Configuration();
2.SessionFactory sessionFactory = config.configure().buildSessionFactory();
3.Session session = sessionFactory.openSession();
4.Transaction trans = session.beginTrasation();
5.Session.save(),session.update(),session.createQuery(hql).executeUpdate()等
6.trans.commit()或发生异常时执行trans.rollback()
7.session.close()
说明:其中第五步的session操作可以按以下两种方式进行:
(1)先得到一个Query,再通过Query来执行相关操作,如query.list(), query.setString().executeUpdate()
hql = "delete from Order where id = :id";
session.createQuery(hql).setInteger("id", 1).executeUpdate();
(2)直接操作session.save(),session.update(),session.delete(),session.get().
session.load(),session.saveOrUpdate()
String hql = "update Employee e set e.salary = e.salary + 1000";
query.executeUpdate(hql);
3. 5种ID策略
下面以表一个用户名为例:
<id name=”id” column=”id” type=”integer”>
<!-- Id的相关生成策略,有时需要相应参数à
<generator class=”XXX” > //ID的生成方式
</generator>
</id>
其中配置文件中的ID生成策略有:
1.通用策略
<generator class="native" />
说明:Mysql中应将id列定义为auto_increment, SQL Server中定义为identity(1,1)
Oracle中应有名为Hibernate_sequence的sequence。
2.<generator class=”identity”/>
说明:仅适用于Mysql和SQL server.
Mysql中应将id列定义为auto_increment, SQL Server中定义为identity(1,1)
3. <generator class=”hilo”>
<param name=”table”>id_values</param>
<param name=”column”>current_id</param>
<param name=”max_lo”>10</param>
</generator>
说明:在数据库有一个单行单列(current_id)的表(id_values)用于存储一个高位值。
4. <generator class=”sequence”>
<param name=”sequence”>users_sc_se</param>
</generator>
说明:仅适用于支持sequence的数据库,如:Oracle,DB2
5.<generator class="seqhilo">
<param name="sequence">users_sc_se</param>
<param name="max_lo">10</param>
</generator>
说明:(1)sequence的作用相当于使用hilo中表id_values中所存储的currentid,
(2)适用于支持sequence的数据库,如:Oracle,DB2
4. 3种映射关系
1. 一对一关联
1.1 共享主键
一个表使用的主键引用另一个表的主键,而不是自己产生的。也就是说一个表主键的产生要依赖另外一个表的主键。所以:
对表中记录而言,只有主表中有相应记录,其从表才可以有记录并使用主表的主键
对类对象而言只有被参照的对象存在了,才能创建参照对象
(1)建表
假设有汽车和引擎两个实体,它们存在着一对一的关系,我们可以通过共享主键来建立两者的关系。其DDL语名如下:
(2)写对象关系映射文件car.hbm.xml和Engine.hbm.xml
汽车类的配置文件:Car.hbm.xml
<hibernate-mapping package="com.allanlxf.hbn.o2o">
<class name="Car" table="car_o2o_pk">
<id name="id" column="id" type="integer">
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<property name="manufacture" column="manufacture" type="string"/>
<one-to-one name="engine" class="Engine" cascade="all"/>
</class>
</hibernate-mapping>
引擎类的配置文件:Engine.hbm.xml
<hibernate-mapping package="com.allanlxf.hbn.o2o">
<class name="Engine" table="engine_o2o_pk">
<id name="id" column="id" type="integer">
<generator class="foreign">
<param name="property">car</param>
</generator>
</id>
<property name="model" column="model" type="string"/>
<property name="manufacture" column="manufacture" type="string"/>
<one-to-one name="car" class="Car" constrained="true" foreign-key="fk_engine_car_pk"/>
</class>
</hibernate-mapping>
说明:id产生器中指明了使用foreign方式产生,参数指出使用属性car的相关内容。
在<one-to-one>节中的car属性就是generator参数中的car.该节把类Car对应的表与Engine对就的表关联起来。注意配置文件的依据依然是Car类与Engine类定义的各个属性。
1.2 使用外键关联
(1)建表
(2) 写对象关系映射文件
汽车类的配置文件:Car.hbm.xml
<hibernate-mapping package="com.allanlxf.hbn.o2o">
<class name="Car" table="car_o2o_fk">
<id name="id" column="id" type="integer">
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<property name="manufacture" column="manufacture" type="string"/>
<one-to-one name="engine" class="Engine" property-ref="car" cascade="save-update"/>
</class>
</hibernate-mapping>
注:其中property-ref="car" 指定关联类Engine类的car属性与本类主键对应。如果没有指定,会使用对方关联类 Engine的主键关联。它是可选的。
Cascade=”save_update”指出删除不级联。
引擎类的配置文件:Engine.hbm.xml
<hibernate-mapping package="com.allanlxf.hbn.o2o">
<class name="Engine" table="engine_o2o_fk">
<id name="id" column="id" type="integer">
<generator class="native" />
</id>
<property name="model" column="model" type="string"/>
<property name="manufacture" column="manufacture" type="string"/>
<many-to-one name="car" class="Car" column="carid"/>
</class>
</hibernate-mapping>
本身属性car可以多对一。但时在表中使用了Unique限制,且在Car.hbm.xml中也使用了<one-to-one>进行了限制.
2. 一对多关联
使用订单(Order)与订单项(Item)作为模型来讨论。一个订单包含多个订单项。
单向关联:在单的一方不需要设置存放多方的集合属性。
双向关联:在单的一方需要有一个set属性来存储多的一方
(1)建表
(2)写对象关系映射文件
<hibernate-mapping package="com.allanlxf.hbn.o2m">
<class name="Order" table="order_o2m">
<id name="id" column="id" type="integer">
<generator class="sequence">
<param name="sequence">order_o2m_seq</param>
</generator>
</id>
<property name="no" column="no" type="string"/>
<property name="owner" column="owner" type="string"/>
<property name="sendDate" column="sdate" type="date"/>
<set name="items" cascade="all" inverse="true">
<key column="orderid" />
<one-to-many class="Item"/>
</set>
</class>
</hibernate-mapping>
注意:一定要加上inverse=”true”,来说明关联(那外键约束)只需一方来维护。当关联类Iitem改变时,不会调用Update来更新本类的主键。
建立关联时,只要在关联类中加入属性OrderId作为关联类表的外键,并以此来与本类关联。
<hibernate-mapping package="com.allanlxf.hbn.o2m">
<class name="Item" table="item_m2o">
<id name="id" column="id" type="integer">
<generator class="sequence">
<param name="sequence">item_m2o_seq</param>
</generator>
</id>
<property name="product" column="product" type="string"/>
<property name="price" column="price" type="double"/>
<property name="amount" column="amount" type="integer"/>
<many-to-one name="order" class="Order" column="orderid"/>
</class>
</hibernate-mapping>
3. 多对多关联
这时选择班级(TarenaClass)与课程(Course)的对应关系作为讲座多对多关系的模型,不同的班级开设不同的课程。
实质上多对多的关系就相当于两个一对多的关系。
(1)建表
(2) 写对象关系映射文件
<hibernate-mapping package="com.allanlxf.hbn.m2m">
<class name="Course" table="course_m2m">
<id name="id" column="id" type="integer">
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<set name="classes" table="cl_cou_m2m" inverse="true">
<key column="courseid" />
<many-to-many class="TarenaClass" column="classid"/>
</set>
</class>
</hibernate-mapping>
<hibernate-mapping package="com.allanlxf.hbn.m2m">
<class name="TarenaClass" table="class_m2m">
<id name="id" column="id" type="integer">
<generator class="native" />
</id>
<property name="name" column="name" type="string"/>
<set name="courses" table="cl_cou_m2m">
<key column="classid" />
<many-to-many class="Course" column="courseid"/>
</set>
</class>
</hibernate-mapping>
说明: a.多对多有双向关联。
b. 多对多引用的是集合对象
c.需要用第三张表来维持多对多关系。
d.写配置文件的时候many-to-many标签要放在set标签内, <key column =””>总是和本类的主键id对应
d. 同样也要加上inverse=”true”,在多对多关联时,如果一方改变,则会另一方也会执行额外的操作来维护外键约束.应让一方来维护数据库的完整性即可。