Ajax+Struts2+Spring+Hibernate整合

 我们沿用Spring+Hibernate+DWR的例子,做一个Ajax+Struts2.0+Spring+Hibernate整合,许多步骤大体相似,
我就直接搬过来了:
首先,建一个web project,然后添加对hibernate和spring的支持,我们使用的是hibernate3.2和spring2.0,然后导入xwork-2.0.3.jar struts2-core-2.0.8.jar struts2-spring-plugin-2.0.8.jar ognl-2.6.11.jar  freemarker-2.3.8.jar commons-logging-api-1.1.jar和commons-pool-1.3.jar(不知道myeclipse怎么搞的,添加Spring功能支持的时候就有了commons-dbcp.jar,居然没有其依赖的commons-pool-x.jar,只好单独添加了,另外,需要将Spring2.0 AOP Liberaries里的asm2.2.3.jar删除,因为好像和Hiberate中的生成代理用的asm.jar冲突,我把Spring2.0 AOP Liberaries排到最后仍然有冲突,所以只好删掉了,不知道大家遇到过这种情况么)。
我们使用myeclise自带的Derby数据库,在里面建一个表BOOK:
ID bigint primary key,autoincrement
NAME varchar(20)
ISBM varchar(20)
AUTHOR varchar(15)
然后利用myeclipse的hibernate反向工程生成领域模型:Book.java, DAO:BookDAO.jar, Book 的映射文件Book.hbm.xml:
生成的代码及配置文件如下:

Book.java:

package  edu.jlu.fuliang.domain;

/**
 * Book generated by MyEclipse Persistence Tools
 
*/


public   class  Book  implements  java.io.Serializable  {

    
// Fields

    
private long id;
    
private String name;
    
private String isbm;
    
private String author;

    
// Constructors

    
/** default constructor */
    
public Book() {
    }


    
/** minimal constructor */
    
public Book(String name, String isbm) {
        
this.name = name;
        
this.isbm = isbm;
    }


    
/** full constructor */
    
public Book(String name, String isbm, String author) {
        
this.name = name;
        
this.isbm = isbm;
        
this.author = author;
    }


    
// Property accessors

    
public long getId() {
        
return this.id;
    }


    
public void setId(long id){
        
this.id = id;
    }


    
public String getName() {
        
return this.name;
    }


    
public void setName(String name) {
        
this.name = name;
    }


    
public String getIsbm() {
        
return this.isbm;
    }


    
public void setIsbm(String isbm) {
        
this.isbm = isbm;
    }


    
public String getAuthor() {
        
return this.author;
    }


    
public void setAuthor(String author) {
        
this.author = author;
    }


}

BookDAO.java:

package  edu.jlu.fuliang.dao;

import  java.util.List;
import  org.apache.commons.logging.Log;
import  org.apache.commons.logging.LogFactory;
import  org.hibernate.LockMode;
import  org.springframework.context.ApplicationContext;
import  org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import  edu.jlu.fuliang.domain.Book;

/**
 * Data access object (DAO) for domain model class Book.
 * 
 * 
@see edu.jlu.fuliang.domain.Book
 * 
@author MyEclipse Persistence Tools
 
*/


public   class  BookDAO  extends  HibernateDaoSupport  {
    
private static final Log log = LogFactory.getLog(BookDAO.class);
    
// property constants
    public static final String NAME = "name";
    
public static final String ISBM = "isbm";
    
public static final String AUTHOR = "author";

    
protected void initDao() {
        
// do nothing
    }


    
public void save(Book transientInstance) {
        log.debug(
"saving Book instance");
        
try {
            getHibernateTemplate().save(transientInstance);
            log.debug(
"save successful");
        }
 catch (RuntimeException re) {
            log.error(
"save failed", re);
            
throw re;
        }

    }


    
public void delete(Book persistentInstance) {
        log.debug(
"deleting Book instance");
        
try {
            getHibernateTemplate().delete(persistentInstance);
            log.debug(
"delete successful");
        }
 catch (RuntimeException re) {
            log.error(
"delete failed", re);
            
throw re;
        }

    }


    
public Book findById(Long id) {
        log.debug(
"getting Book instance with id: " + id);
        
try {
            Book instance 
= (Book) getHibernateTemplate().get(
                    
"edu.jlu.fuliang.domain.Book", id);
            
return instance;
        }
 catch (RuntimeException re) {
            log.error(
"get failed", re);
            
throw re;
        }

    }


    
public List findByExample(Book instance) {
        log.debug(
"finding Book instance by example");
        
try {
            List results 
= getHibernateTemplate().findByExample(instance);
            log.debug(
"find by example successful, result size: "
                    
+ results.size());
            
return results;
        }
 catch (RuntimeException re) {
            log.error(
"find by example failed", re);
            
throw re;
        }

    }


    
public List findByProperty(String propertyName, Object value) {
        log.debug(
"finding Book instance with property: " + propertyName
                
+ ", value: " + value);
        
try {
            String queryString 
= "from Book as model where model."
                    
+ propertyName + "= ?";
            
return getHibernateTemplate().find(queryString, value);
        }
 catch (RuntimeException re) {
            log.error(
"find by property name failed", re);
            
throw re;
        }

    }


    
public List findByName(Object name) {
        
return findByProperty(NAME, name);
    }


    
public List findByIsbm(Object isbm) {
        
return findByProperty(ISBM, isbm);
    }


    
public List findByAuthor(Object author) {
        
return findByProperty(AUTHOR, author);
    }


    
public List findAll(){
        log.debug(
"finding all Book instances");
        
try {
            String queryString 
= "from Book";
            
return getHibernateTemplate().find(queryString);
        }
 catch (RuntimeException re) {
            log.error(
"find all failed", re);
            
throw re;
        }

    }


    
public Book merge(Book detachedInstance) {
        log.debug(
"merging Book instance");
        
try {
            Book result 
= (Book) getHibernateTemplate().merge(detachedInstance);
            log.debug(
"merge successful");
            
return result;
        }
 catch (RuntimeException re) {
            log.error(
"merge failed", re);
            
throw re;
        }

    }


    
public void attachDirty(Book instance) {
        log.debug(
"attaching dirty Book instance");
        
try {
            getHibernateTemplate().saveOrUpdate(instance);
            log.debug(
"attach successful");
        }
 catch (RuntimeException re) {
            log.error(
"attach failed", re);
            
throw re;
        }

    }


    
public void attachClean(Book instance) {
        log.debug(
"attaching clean Book instance");
        
try {
            getHibernateTemplate().lock(instance, LockMode.NONE);
            log.debug(
"attach successful");
        }
 catch (RuntimeException re) {
            log.error(
"attach failed", re);
            
throw re;
        }

    }


    
public static BookDAO getFromApplicationContext(ApplicationContext ctx) {
        
return (BookDAO) ctx.getBean("BookDAO");
    }

}

Book.hbm.xml:

xml version="1.0" encoding="utf-8" ?>
DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>

< hibernate-mapping >
    
< class  name ="edu.jlu.fuliang.domain.Book"  table ="BOOK"  schema ="CLASSICCARS" >
        
< id  name ="id"  type ="long" >
            
< column  name ="ID"   />
            
< generator  class ="identity" > generator >
        
id >
        
< property  name ="name"  type ="string" >
            
< column  name ="NAME"  length ="20"  not-null ="true"   />
        
property >
        
< property  name ="isbm"  type ="string" >
            
< column  name ="ISBM"  length ="20"  not-null ="true"  unique ="true"   />
        
property >
        
< property  name ="author"  type ="string" >
            
< column  name ="AUTHOR"  length ="15"   />
        
property >
    
class >
hibernate-mapping >

下面我们配置一下Spring,我们把applicationContext.xml分成了三个,分别是applicationContext-db.xml,applicationContext-dao.xml,applicationContext-service.我们看看如何配置:

applicationContext-db.xml:

xml version="1.0" encoding="UTF-8" ?>
< beans
    
xmlns ="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" >

    
< bean  id ="dataSource"
        class
="org.apache.commons.dbcp.BasicDataSource" >
        
< property  name ="driverClassName"
            value
="org.apache.derby.jdbc.ClientDriver" >
        
property >
        
< property  name ="url"
            value
="jdbc:derby://localhost:1527/myeclipse;create=true" >
        
property >
        
< property  name ="username"  value ="classiccars" > property >
        
< property  name ="password"  value ="myeclipse" > property >
    
bean >
    
    
< bean  id ="sessionFactory"
        class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean" >
        
< property  name ="dataSource" >
            
< ref  bean ="dataSource"   />
        
property >
        
< property  name ="hibernateProperties" >
            
< props >
                
< prop  key ="hibernate.dialect" >
                    org.hibernate.dialect.DerbyDialect
                
prop >
            
props >
        
property >
        
< property  name ="mappingResources" >
            
< list >
                
< value > edu/jlu/fuliang/domain/Book.hbm.xml value > list >
        
property >
    
bean >
beans >

applicationContext-dao.xml:

xml version="1.0" encoding="UTF-8" ?>
< beans
    
xmlns ="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" >
    
    
< bean  id ="bookDAO"  class ="edu.jlu.fuliang.dao.BookDAO" >
        
< property  name ="sessionFactory" >
            
< ref  bean ="sessionFactory"   />
        
property >
    
bean >

beans >

接下来我们来写我们的Service层:

BookManageService.java:

package  edu.jlu.fuliang.service;
import  java.util.List;

import  edu.jlu.fuliang.domain.Book;

public   interface  BookManageService  {
    
public List<Book> getAllBooks();
    
public List<Book> getBookByName(String name);
    
public void updateBook(Book book);
    
public void addBook(Book book);
    
public void deleteBook(long id);
    
public Book getBookById(Long id);
}

BookManageServiceImpl.java:

package  edu.jlu.fuliang.serviceImpl;

import  java.util.List;

import  edu.jlu.fuliang.dao.BookDAO;
import  edu.jlu.fuliang.domain.Book;
import  edu.jlu.fuliang.service.BookManageService;

public   class  BookManageServiceImpl  implements  BookManageService {
    
private BookDAO bookDAO;
    @Override
    
public void addBook(Book book) {
        bookDAO.save(book);
    }


    @Override
    
public void deleteBook(long id) {
        Book book 
= bookDAO.findById(id);
        bookDAO.delete(book);        
    }


    @Override
    
public List<Book> getAllBooks() {
        
return bookDAO.findAll();
    }


    @Override
    
public List<Book> getBookByName(String name) {
        
return bookDAO.findByName(name);
    }


    @Override
    
public void updateBook(Book book) {
        bookDAO.attachDirty(book);
    }

    
    
public void setBookDAO(BookDAO bookDAO){
        
this.bookDAO = bookDAO;
    }


    @Override
    
public Book getBookById(Long id) {
        
return bookDAO.findById(id);
    }

}


然后写一个struts的Action,他完全是一个POJO:

package  edu.jlu.fuliang.action;

import  java.util.List;

import  com.opensymphony.xwork2.Action;
import  com.opensymphony.xwork2.Preparable;

import  edu.jlu.fuliang.domain.Book;
import  edu.jlu.fuliang.service.BookManageService;

public   class  BookAction  implements  Preparable {
    
private BookManageService bookManageService;
    
private List<Book> books;
    
private Book book;
    
private Long id;
    
    
public String execute(){
        
this.books = bookManageService.getAllBooks();
        
return Action.SUCCESS;
    }

    
    
public String save(){
        
this.bookManageService.addBook(book);
        
return execute();
    }

    
    
public void prepare()throws Exception{
        
if(id != null)
            book 
= bookManageService.getBookById(id);
    }

    
    
public String remove(){
        bookManageService.deleteBook(id);
        
return execute();
    }

    
    
public List<Book> getBooks() {
        
return books;
    }

    
    
public void setBooks(List<Book> books) {
        
this.books = books;
    }

    
public Book getBook() {
        
return book;
    }

    
public void setBook(Book book) {
        
this.book = book;
    }

    
public Long getId() {
        
return id;
    }

    
public void setId(Long id) {
        
this.id = id;
    }

    
public void setBookManageService(BookManageService bookManageService) {
        
this.bookManageService = bookManageService;
    }

}

然后我们来配置Service、事务以及struts的action:

 applicationContext-service.xml:

xml version="1.0" encoding="UTF-8" ?>
< beans
    
xmlns ="http://www.springframework.org/schema/beans"
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation
="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd" >
    
< bean  id ="bookManageServiceTarget"  class ="edu.jlu.fuliang.serviceImpl.BookManageServiceImpl" >
        
< property  name ="bookDAO" >
            
< ref  bean ="bookDAO" />
        
property >
    
bean >
    
< bean  id ="transactionManager"  class ="org.springframework.orm.hibernate3.HibernateTransactionManager" >
        
< property  name ="sessionFactory" >
            
< ref  bean ="sessionFactory" />
        
property >
    
bean >
    
< bean  id ="bookManageService"  class ="org.springframework.transaction.interceptor.TransactionProxyFactoryBean" >
        
< property  name ="transactionManager" >
            
< ref  bean ="transactionManager" />
        
property >
        
< property  name ="target" >
            
< ref  bean ="bookManageServiceTarget" />
        
property >
        
< property  name ="transactionAttributes" >
            
< props >
                
< prop  key ="get*" > PROPAGATION_REQUIRED,readOnly prop >
                
< prop  key ="*" > PROPAGATION_REQUIRED prop >
            
props >
        
property >
    
bean >
    /* configure struts action as bean in spring*/
    
< bean  id ="bookAction"  scope ="prototype"  class ="edu.jlu.fuliang.action.BookAction" >
        
< property  name ="bookManageService" >
            
< ref  bean ="bookManageService" />
        
property >
    
bean >
    
beans >

配置struts.xml:

xml version="1.0" encoding="UTF-8"  ?>
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.objectFactory"  value ="spring" />
    
< constant  name ="struts.devMode"  value ="true" />
    
    
< package  name ="book"  extends ="struts-default" >
        
< action  name ="list"  method ="execute"  class ="bookAction" >
            
< result > list.jsp result >
            
< result  name ="input" > list.jsp result >
        
action >
        
< action  name ="remove"  method ="remove"  class ="bookAction" >
            
< result > list.jsp result >
            
< result  name ="input" > list.jsp result >
        
action >
        
< action  name ="save"  method ="save"  class ="bookAction" >
            
< result > list.jsp result >
            
< result  name ="input" > list.jsp result >
        
action >
    
package >
struts >

配置WEB-INF/web.xml:

xml version="1.0" encoding="UTF-8" ?>
< web-app  version ="2.4"  
    xmlns
="http://java.sun.com/xml/ns/j2ee"  
    xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"  
    xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee 
    http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd"
>
 
< filter >
     
< filter-name > struts filter-name >
     
< filter-class >
         org.apache.struts2.dispatcher.FilterDispatcher
     
filter-class >
 
filter >
 
< filter-mapping >
     
< filter-name > struts filter-name >
     
< url-pattern > /* url-pattern >
 
filter-mapping >
 
 
< welcome-file-list >
      
< welcome-file > index.jsp welcome-file >
 
welcome-file-list >
 
 
< context-param >
     
< param-name > contextConfigLocation param-name >
     
< param-value > classpath:applicationContext-*.xml param-value >
 
context-param >
 
 
< listener >
     
< listener-class >
         org.springframework.web.context.ContextLoaderListener
     
listener-class >
 
listener >
web-app >

配置一下log:

# This is the configuring for logging displayed in the Application Server
# log4j.rootCategory
= INFO ,  stdout , logfile
log4j.rootCategory
= DEBUG ,  A1

#console configure
log4j.appender.A1 
=  org.apache.log4j.ConsoleAppender
log4j.appender.A1.layout 
=  org.apache.log4j.PatternLayout
log4j.appender.A1.layout.ConversionPattern 
=  %-4r  [ %t ]  %-5p %c %x - %m%n

#stdout configure
log4j.appender.stdout
= org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout
= org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern
=  %d %p  [ %c ]  - <%m>%n

#logfile configure
log4j.appender.logfile
= org.apache.log4j.DailyRollingFileAppender
log4j.appender.logfile.File
= log4j.log
log4j.appender.logfile.layout
= org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern
=  %d %p  [ %c ]  - <%m>%n

# Control logging for other open source packages
# Changing the log level to DEBUG when debug
log4j.logger.org.springframework
= ERROR
log4j.logger.org.springframework.web.context.support.XmlWebApplicationContext
= INFO
log4j.logger.org.hibernate
= ERROR
log4j.logger.org.hibernate.cfg.HbmBinder
= INFO
log4j.logger.org.hibernate.SQL
= ERROR
log4j.logger.org.hibernate.cache
= ERROR
log4j.logger.org.hibernate.transaction
= INFO
log4j.logger.net.sf.ehcache
= ERROR
log4j.logger.org.apache.struts
= ERROR
log4j.logger.com.htxx.service.dao
= INFO
log4j.logger.org.apache.commons
= INFO
log4j.logger.org.directwebremoting
= INFO

写两个页面index.jsp,list.jsp,使用了Ajax--dojo::

index.jsp:

<% @ taglib prefix="s" uri="/struts-tags" %>
< html >
    
< head >
        
< s:head  theme ="ajax"  debug ="true" />
        
< script  type ="text/javascript" >
            dojo.event.topic.subscribe(
"/save"function(data, type, request) {
                
if(type == "load"{
                    dojo.byId(
"id").value = "";
                    dojo.byId(
"name").value = "";
                    dojo.byId(
"isbm").value = "";
                    dojo.byId(
"author").value = "";
                }

            }
);

            dojo.event.topic.subscribe(
"/edit"function(data, type, request) {
                
if(type == "before"{
                    
var id = data.split("_")[1];
                    
var tr = dojo.byId("row_"+id);
                    
var tds = tr.getElementsByTagName("td");

                    dojo.byId(
"id").value = id;
                    dojo.byId(
"name").value = dojo.string.trim(dojo.dom.textContent(tds[0]));
                    dojo.byId(
"isbm").value = dojo.string.trim(dojo.dom.textContent(tds[1]));
                    dojo.byId(
"author").value = dojo.string.trim(dojo.dom.textContent(tds[1]));
                }

            }
);
        
script >
    
head >
    
< body >
        
< s:url  action ="list"  id ="descrsUrl" />

        
< div  style ="width: 300px;border-style: solid" >
            
< div  style ="text-align: right;" >
                
< s:a  theme ="ajax"  notifyTopics ="/refresh" > Refresh s:a >
            
div >
            
< s:div  id ="books"  theme ="ajax"  href ="%{descrsUrl}"  loadingText ="Loading..."  listenTopics ="/refresh" />
        
div >

        
< br />

        
< div  style ="width: 300px;border-style: solid" >
            
< p > Book Data p >
            
< s:form  action ="save"  validate ="true" >
                
< s:textfield  id ="id"  name ="person.id"  cssStyle ="display:none" />
                
< s:textfield  id ="name"  label ="Name"  name ="book.name" />
                
< s:textfield  id ="isbm"  label ="ISBN"  name ="book.isbm" />
                
< s:textfield  id ="author"  label ="Author"  name ="book.author" />
                
< s:submit  theme ="ajax"  targets ="books"  notifyTopics ="/save" />
            
s:form >
        
div >
    
body >
html >

list.jsp:

<% @ taglib prefix="s" uri="/struts-tags" %>
< p > Books p >
< s:if  test ="books.size > 0" >
 
< table >
  
< s:iterator  value ="books" >
   
< tr  id ="row_ id" /> ">
    
< td >
     
< s:property  value ="name"   />
    
td >
    
< td >
     
< s:property  value ="isbm"   />
    
td >
    
< td >
     
< s:property  value ="author" />
    
td >
    
< td >
     
< s:url  id ="removeUrl"  action ="remove" >
      
< s:param  name ="id"  value ="id"   />
     
s:url >
     
< s:a  href ="%{removeUrl}"  theme ="ajax"  targets ="books" > Remove s:a >
     
< s:a  id ="a_%{id}"  theme ="ajax"  notifyTopics ="/edit" > Edit s:a >
    
td >
   
tr >
  
s:iterator >
 
table >
s:if >


在浏览器中输入地址,我们就可以在一个页面进行CRUD操作了.

你可能感兴趣的:(Hibernate,AJAX,Spring)