📄 用hibernate和spring开发事务持久层.htm
字号:
BIGINT not null,<BR>FK_ROLE_ID BIGINT not
null<BR>)</P></TD></TR>
<TR bgColor=#ffffff>
<TD
height=25><STRONG>雇员是用户</STRONG><BR>Inheritance<BR>用户<BR>雇员</TD>
<TD height=25>[User.java]<BR>/**<BR>*
@hibernate.class table="TBL_USER" <BR>*
discriminator-value="2" <BR>*
@hibernate.discriminator column="USER_TYPE"<BR>*
<BR>...<BR>...<BR>...<BR>*/<BR>public class User {
<P>[Employee.java]<BR>/**<BR>* @hibernate.subclass
discriminator-value = "1"<BR>*/<BR>public class
Employee extends User{</P></TD>
<TD height=25>create table TBL_USER
(<BR>PK_USER_ID BIGINT NOT NULL
AUTO_INCREMENT,<BR>USER_TYPE VARCHAR(255) not
null,<BR>FK_GROUP_ID BIGINT,<BR>VC_EMAIL
VARCHAR(82) not null unique,<BR>primary key
(PK_USER_ID)<BR>)</TD></TR></TBODY></TABLE>
<P> <STRONG>Hibernate 中的查询</STRONG></P>
<P> Hibernate 有三种类型的查询:</P>
<P> ☆ Criteria, object composition <BR> ☆ SQL <BR> ☆
HQL</P>
<P> 在下面的例子中将只使用 HQL。本节还要使用 Spring,用它的 AOP-driven
HibernateTemplate 简化 Hibernate 会话的处理。在本节将开发一个 DAO(Data
Access Object)。要了解更多关于 DAO 的内容,请参阅 参考资料。</P>
<P> 清单 2 展示了两个方法:一个使用 HQL
查询的组查询,另一个是后面接一个操作的组查询。注意在第二个方法中,Spring
HibernateTemplate 是如何简化会话管理的。</P>
<P> 清单 2. 使用查询</P>
<P style="BACKGROUND: #eeeeee">import
net.sf.hibernate.HibernateException;<BR>import
net.sf.hibernate.Session;<BR>import
net.sf.hibernate.Query;<BR>import
org.springframework.orm.hibernate.HibernateCallback;<BR>import
org.springframework.orm.hibernate.support.HibernateDaoSupport;<BR><BR>/**<BR> *
@author Richard Hightower<BR> * ArcMind Inc.
http://www.arc-mind.com<BR> */<BR>public class
UserDAO extends HibernateDaoSupport{<BR><BR>
.<BR> .<BR> .<BR><BR> /**<BR> *
Demonstrates looking up a group with a HQL
query<BR> * @param email<BR> *
@return<BR> */ <BR> public Group
findGroupByName(String name) {<BR>
return (Group) getHibernateTemplate().find("from Group g
where
g.name=?",name).get(0);<BR> }<BR> <BR> /**<BR>
* Demonstrates looking up a group and forcing it to
populate users (relationship was lazy)<BR> *
@param email<BR> * @return<BR>
*/ <BR> public Group
findPopulatedGroupByName(final String name)
{<BR> HibernateCallback callback = new
HibernateCallback(){<BR><BR>
public Object doInHibernate(Session session) throws
HibernateException, SQLException
{<BR> Group group
=null;<BR> String query = "from Group g
where g.name=?";<BR> Query queryObject
= getHibernateTemplate().createQuery(session,
query);<BR> queryObject.setParameter(0,
name);<BR> group = (Group)
queryObject.list().get(0);<BR> group.getUsers().size();//force
load<BR> return
group;<BR> }<BR> <BR> };<BR> <BR> return
(Group)
getHibernateTemplate().execute(callback);<BR> }<BR>
.<BR> .<BR> .<BR>} </P>
<P> 您可能会注意到第二个方法比第一个方法复杂得多,因为它强迫加载 users 集合。因为
Group->Users 之间的关系设置为 lazy initialize(即表 2 中
lazy="true"),组对象需要一个活跃的会话以查询用户。在定义 Group 和 Users
之间关系时设置这个属性为 lazy="false",则不需要第二个方法。在这种情况下,可能使用第一种方法
(findGroupByName)
列出组,用第二种方法(findPopulatedGroupByName)查看组细节。</P>
<P> <STRONG>Spring IOC 和 Hibernate</STRONG></P>
<P> 使用 Spring 时,在 J2EE 容器内和容器外工作一样容易。比如在最近的项目中,我在
Eclipse 中,使用 HSQL 和本地数据库对使用 Hibernate 事务管理器的 Hypersonic
SQL 数据库进行持久性单元测试。然后,在部署到 J2EE 服务器时,将持久层转换为使用 J2EE 数据源(通过
JNDI)、JTA 事务和使用 FireBird (一个开放源代码版本的 Interbase)。这是用
Spring 作为 IOC 容器完成的。</P>
<P> 从清单 3 中可以看出,Spring 允许加入依赖性。注意清单中应用程序上下文文件是如何配置
dataSource 的。dataSource 传递给
sessionFactory,sessionFactory 传递给 UserDAO。</P>
<P> 清单 3. Spring IOC 和 Hibernate</P>
<P
style="BACKGROUND: #eeeeee"><beans><BR><BR> <!--
Datasource that works in any application
server<BR> You could easily use J2EE data
source instead if this were<BR> running
inside of a J2EE container.<BR>
--><BR> <bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"><BR> <property
name="driverClassName"><value>com.mysql.jdbc.Driver</value></property><BR> <property
name="url"><value>jdbc:mysql://localhost:3306/mysql</value></property><BR> <property
name="username"><value>root</value></property><BR> <property
name="password"><value></value></property><BR> </bean><BR><BR> <!--
Hibernate SessionFactory --><BR> <bean
id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean"><BR> <property
name="dataSource"><ref
local="dataSource"/></property><BR> <BR> <!--
Must references all OR mapping files.
--><BR> <property
name="mappingResources"><BR> <list><BR>
<value>net/sf/hibernateExamples/User.hbm.xml</value><BR>
<value>net/sf/hibernateExamples/Group.hbm.xml</value><BR>
<value>net/sf/hibernateExamples/Role.hbm.xml</value>
<BR>
<value>net/sf/hibernateExamples/ContactInfo.hbm.xml</value><BR> </list><BR> </property><BR> <BR> <!--
Set the type of database; changing this one property
will port this to Oracle, <BR> MS SQL
etc. --><BR> <property
name="hibernateProperties"><BR> <props><BR>
<prop
key="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</prop><BR> </props><BR> </property><BR> </bean><BR> <BR> <!--
Pass the session factory to our UserDAO
--><BR> <bean id="userDAO"
class="net.sf.hibernateExamples.UserDAO"><BR> <property
name="sessionFactory"><ref
local="sessionFactory"/></property><BR> </bean><BR> <BR></beans> </P>
<P> 设置了 UserDAO 后,下一步就是定义并使用更多的查询以展示可以完成的操作。Hibernate
可以用预定义查询将查询存储到源代码之外,如清单 4 所示。</P>
<P> 清单 4. 预定义查询<BR> [User.java]</P>
<P style="BACKGROUND: #eeeeee">/**<BR> * @author
Richard Hightower<BR> * ArcMind Inc.
http://www.arc-mind.com<BR> * @hibernate.class
table="TBL_USER" discriminator-value="2" <BR> *
@hibernate.discriminator column="USER_TYPE"<BR> *
<BR> * @hibernate.query name="AllUsers" query="from
User user order by user.email asc"<BR> *
<BR> * @hibernate.query name="OverheadStaff"
<BR> * query="from Employee employee join
employee.group g where g.name not in
('ENGINEERING','IT')"<BR> * <BR> *
@hibernate.query name="CriticalStaff" <BR> *
query="from Employee employee join employee.group g
where g.name in ('ENGINEERING','IT')"<BR> *
<BR> * @hibernate.query name="GetUsersInAGroup"
<BR> * query="select user from Group g join g.users
user"<BR> * <BR> * @hibernate.query
name="GetUsersNotInAGroup" <BR> * query="select
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -