`
huang3218755
  • 浏览: 6199 次
  • 性别: Icon_minigender_1
  • 来自: 安徽
最近访客 更多访客>>
文章分类
社区版块
存档分类
最新评论

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
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics