Struts 2与Hibernate整合(入门)

一、输入界面:input.jsp与控制器
<%@ page contentType="text/html; charset=GBK" language="java"%>

<%@taglib prefix="s" uri="/struts-tags"%>
<HTML>
<HEAD>
<TITLE>添加新家长</TITLE>
</HEAD>
<BODY>
<s:form action="add.action">
<s:textfield name="name" label="父亲名字:"/>
<s:textfield name="gender" label="性别:"/>
<s:textfield name="sonName" label="儿子名:"/>
<s:textfield name="sonAge" label="儿子年龄:"/>
<s:submit value="提交"/>
</s:form>
</BODY>
</HTML>

struts 2配置文件:struts.xml

<?xml version="1.0" encoding="GBK"?>

<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.0//EN" "http://struts.apache.org/dtds/struts-2.0.dtd">

<struts>
<constant name="struts.i18n.encoding" value="GBK"/>
<constant name="struts.custom.i18n.resources" value="messageResource"/>

<package name="lee" extends="struts-default">
<action name="add" class="org.yeeku.action.AddPersonAndSon">
<result>welcome.html</result>
</action>
</package>

</struts>

Action类(控制器):

package org.yeeku.action;
import com.opensymphony.xwork2.ActionSupport;
import javax.servlet.http.*;
import org.yeeku.service.*;
import org.yeeku.factory.*;


public class AddPersonAndSon extends ActionSupport
{
private String name;
private String gender;
private String sonName;
private int sonAge;

public String execute()throws Exception
{
String[] sonNames = {sonName};
int[] sonAges = {sonAge};
//通过业务逻辑工厂取得业务逻辑组件
PersonService ps = (PersonService)AppFactory.instance().getApp("personService");
//调用业务逻辑方法处理用户请求
ps.createPersonAndSon(name , gender , sonNames , sonAges);
return SUCCESS;
}
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
public void setGender(String gender)
{
this.gender = gender;
}
public String getGender()
{
return this.gender;
}
public void setSonName(String sonName)
{
this.sonName = sonName;
}
public String getSonName()
{
return this.sonName;
}
public void setSonAge(int sonAge)
{
this.sonAge = sonAge;
}
public int getSonAge()
{
return this.sonAge;
}
}

我们并不在Struts 2的Action中调用Hibernate API,Action也不直接依赖于任何业务逻辑组件,而只是依赖
于业务逻辑工厂类,面向业务逻辑组件接口编程。这个过程是如何实现的请继续往下看。

运行图:





所填数据将会保存到数据库struts2hibernate中,这个数据库请事先在MYSQL中创建。


从数据中可以看到刚提交的数据:


二、持久层设计
包括Hibernate持久化访问所需的PO和Hibernate映射文件。

父亲实体类代码:

package org.yeeku.model;
import java.util.*;
public class Person
{
private int id;
private String name;
private String gender;
private Set< Son> sons = new HashSet< Son>();
public Person()
{
}

public void setId(int id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setGender(String gender) {
this.gender = gender;
}
public void setSons(Set sons)
{
this.sons = sons;
}
public int getId() {
return (this.id);
}
public String getName() {
return (this.name);
}
public String getGender() {
return (this.gender);
}
public Set< Son> getSons()
{
return this.sons;
}
}
对应的映射文件:Person.hbm.xml

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.yeeku.model">
<!-- 每个class元素映射一个持久化类 -->
<class name="Person" table="person">
<id name="id">
<generator class="identity"/>
</id>
<property name="name"/>
<property name="gender"/>
<set name="sons" inverse="true">
<key column="person_id"/>
<one-to-many class="Son"/>
</set>
</class>
</hibernate-mapping>

上面的Person实体存在一个一对多的关联实体:Son,代码如下:

package org.yeeku.model;
import java.io.Serializable;
public class Son implements Serializable
{
private int id;
private String sonName;
private int sonAge;
private Person parent;

public Son()
{
}

public Son(String sonName , int sonAge)
{
this.sonName = sonName;
this.sonAge = sonAge;
}
public void setSonName(String sonName) {
this.sonName = sonName;
}
public void setSonAge(int sonAge) {
this.sonAge = sonAge;
}
public void setId(int id)
{
this.id = id;
}
public void setParent(Person p)
{
this.parent = p;
}
public String getSonName() {
return (this.sonName);
}
public int getSonAge() {
return (this.sonAge);
}
public int getId()
{
return id;
}
public Person getParent()
{
return parent;
}
}

对应的映射文件:Son.hbm.xml
<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="org.yeeku.model">
<!-- 每个class元素映射一个持久化类 -->
<class name="Son" table="son">
<id name="id">
<generator class="identity"/>
</id>
<property name="sonName"/>
<property name="sonAge"/>
<many-to-one name="parent" column="person_id" not-null="true"/>
</class>
</hibernate-mapping>


最后是Hibernate配置文件:hibernate.cfg.xml,指定了数据库连接信息和连接池等。

<?xml version="1.0" encoding="GBK"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>

<session-factory>

<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost/struts2hibernate</property>
<property name="connection.username">root</property>
<property name="connection.password"></property>

<!-- C3P0 connection pool -->
<property name="hibernate.c3p0.max_size">500</property>
<property name="hibernate.c3p0.min_size">2</property>
<property name="hibernate.c3p0.timeout">5000</property>
<property name="hibernate.c3p0.max_statements">100</property>
<property name="hibernate.c3p0.idle_test_period">3000</property>
<property name="hibernate.c3p0.acquire_increment">2</property>
<property name="hibernate.c3p0.validate">true</property>

<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>

<!-- Echo all executed SQL to stdout -->
<property name="show_sql">false</property>

<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>

<mapping resource="Person.hbm.xml"/>
<mapping resource="Son.hbm.xml"/>

</session-factory>

</hibernate-configuration>
三、DAO层设计
由两个DAO组件和一个DAO工厂组成,两个DAO组件的代码大致相同,这里以Person实体对应的DAO组件为例来介绍DAO组件
的实现。

1、Dao接口

package org.yeeku.dao.base;

public interface Dao
{
}

2、PersonDao接口
package org.yeeku.dao;
import org.hibernate.Session;
import org.yeeku.model.*;
import org.yeeku.dao.base.Dao;

import java.util.*;

public interface PersonDao extends Dao {
//包括四个CRUD操作
void save(Session sess , Person p);
void delete(Session sess , Person p);
void delete(Session sess , int id);
void update(Session sess , Person p);
}
3、Dao组件的实现类PersonDaoImpl.java

package org.yeeku.dao.impl;
import org.hibernate.Session;
import org.yeeku.model.*;
import org.yeeku.dao.*;
import java.util.*;
public class PersonDaoImpl implements PersonDao
{
public void save(Session sess , Person p)
{
sess.save(p);
}
public void delete(Session sess , Person p)
{
sess.delete(p);
}
public void delete(Session sess , int id)
{
sess.delete(sess.get(Person.class , new Integer(id)));
}
public void update(Session sess , Person p)
{
sess.update(p);
}
}

4、DAO工厂
DAO工厂是一个简单的工厂类,该工厂类使用XML文件管理DAO组件,采用XML配置文件管理DAO组件可以让DAO工厂灵活
管理所有DAO组件,避免每次增加DAO组件时都要修改代码。这种DAO组件配置文件的代码结构如下:(daoContext.xml)

<?xml version="1.0" encoding="GBK"?>
<daoContext>
<dao id="sonDao" class="org.yeeku.dao.impl.SonDaoImpl"/>
<dao id="personDao" class="org.yeeku.dao.impl.PersonDaoImpl"/>
</daoContext>

可以看出在其中配置了两个DAO组件,因为每个DAO组件在JAVA EE应用中仅需要一个实例就足够了,因此DAO工厂类提供一个
缓存池来缓存每一个DAO实例,并负责在应用启动时创建所有的DAO组件。代码如下:

package org.yeeku.factory;
import org.yeeku.dao.base.Dao;
import org.yeeku.dao.*;
import org.yeeku.dao.impl.*;
import org.yeeku.consttool.*;
import org.dom4j.*;
import org.dom4j.io.*;
import java.util.*;
import java.io.*;
public class DaoFactory
{
private Map daoMap = new HashMap();
private static DaoFactory df;
private DaoFactory()throws Exception
{
Document doc = new SAXReader().read(new File(ConstantsUtil.realPath + "\\daoContext.xml"));
Element root = doc.getRootElement();
List el = root.elements();
for (Iterator it = el.iterator();it.hasNext() ; )
{
Element em = (Element)it.next();
String id = em.attributeValue("id");
String impl = em.attributeValue("class");
Class implClazz = Class.forName(impl);//通过反射,根据类名创建DAO组件的实例
Dao d = (Dao)implClazz.newInstance();
daoMap.put(id , d); //将创建的组件放入缓存池中
}
}
public static DaoFactory instance()throws Exception
{
if (df == null)
{
df = new DaoFactory();
}
return df;
}
public Dao getDao(String id)
{
return daoMap.get(id);
}
}
系统每增加一个DAO组件时,无需要修改任何代码,仅仅需要在daoContext.xml文件中增加配置即可。

四、业务逻辑层设计

业务逻辑组件代码无需与DAO实现类耦合,业务逻辑组件的代码面向DAO组件的接口编程,将业务逻辑组件和DAO组件的耦合
降低到接口层次,业务逻辑层组件设计与DAO层的设计思路大致相同,只是DAO组件实现的是数据库访问功能,而业务逻辑
组件实现的是业务逻辑功能。

1、业务逻辑组件接口代码

package org.yeeku.service;

import org.yeeku.exception.PersonException;

public interface PersonService {//增加父亲和多个子女
void createPersonAndSon(String name , String gender , String[] sonName , int[] sonAge) throws PersonException;
}

2、业务逻辑组件的实现类

package org.yeeku.service.impl;
import org.yeeku.service.*;
import org.yeeku.dao.*;
import org.yeeku.factory.*;
import org.yeeku.model.*;
import org.yeeku.tools.*;
import org.yeeku.exception.PersonException;
import org.hibernate.Session;
import org.hibernate.Transaction;
public class PersonServiceImpl implements PersonService
{
public void createPersonAndSon(String name , String gender , String[] sonName , int[] sonAge)
throws PersonException
{
try
{ //业务逻辑组件依赖于DAO工厂,从工厂中取出两个DAO组件
PersonDao pd = (PersonDao)DaoFactory.instance().getDao("personDao");
SonDao sd = (SonDao)DaoFactory.instance().getDao("sonDao");

//使用HibernateUtil打开Hibernate Session。
Session s = HibernateUtil.currentSession();
Transaction tx = s.beginTransaction();
Person p = new Person();
p.setName(name);
p.setGender(gender);
pd.save(s , p);
for (int i = 0 ; i < sonName.length ; i++ )
{
Son son = new Son(sonName[i] , sonAge[i]);
son.setParent(p);
sd.save(s, son);
}
tx.commit();
HibernateUtil.closeSession();
}
catch (Exception e)
{
e.printStackTrace();
throw new PersonException("业务异常");
}
}
}

本实例中的业务逻辑组件也采用XML配置文件进行管理,业务逻辑组件工厂一样根据XML配置文件来加载系统中的业务逻辑组件。
业务逻辑组件的配置文件如下:(appContext.xml)

<?xml version="1.0" encoding="GBK"?>
<appContext>
<app id="personService" class="org.yeeku.service.impl.PersonServiceImpl"/>
</appContext>

业务逻辑组件工厂根据该文件来初始化所有业务逻辑组件,并将业务逻辑组件放入缓存池中,让控制器Action仅依赖于业务逻辑组件工厂,与业务逻辑组件的耦合降低到接口层次。业务逻辑组件的工厂类代码如下:

package org.yeeku.factory;
import org.yeeku.dao.base.Dao;
import org.yeeku.dao.*;
import org.yeeku.dao.impl.*;
import org.yeeku.service.*;
import org.yeeku.service.impl.*;
import org.yeeku.consttool.*;
import org.dom4j.*;
import org.dom4j.io.*;
import java.util.*;
import java.io.*;
public class AppFactory
{
private Map appMap = new HashMap();
private static AppFactory df;
private AppFactory()throws Exception
{
Document doc = new SAXReader().read(new File(ConstantsUtil.realPath + "\\appContext.xml"));
Element root = doc.getRootElement();
List el = root.elements();
for (Iterator it = el.iterator();it.hasNext() ; )
{
Element em = (Element)it.next();
String id = em.attributeValue("id");
String impl = em.attributeValue("class");
Class implClazz = Class.forName(impl);//用反射根据类名创建业务逻辑组件
Object d = implClazz.newInstance();
appMap.put(id , d); //将业务逻辑组件放入缓存池中
}
}
public static AppFactory instance()throws Exception
{
if (df == null)
{
df = new AppFactory();
}
return df;
}
public Object getApp(String id)//根据业务逻辑组件的ID获取业务逻辑组件
{
return appMap.get(id);//直接从缓存池中取出业务逻辑组件
}
}

系统每增加一个业务组件时,无需要修改任何代码,仅仅需要在appContext.xml文件中增加配置。
http://www.java3z.com/cwbwebhome/article/article2/2939.html?id=1633
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值