【IT168 技术文档】首先,建一个web project,然后添加对hibernate和spring的支持,我们使用的是hibernate3.1和spring2.0,然后导入dwr.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(Long id, String name, String isbm) { this.id = id; this.name = name; this.isbm = isbm; } /** *//** full constructor */ public Book(Long id, String name, String isbm, String author) { this.id = id; 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; } public String toString(){ return "[id=" + id + ",name=" + name + ",isbm=" + isbm + ",author=" + author + "]"; } } edu.jlu.fuliang.dao.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(java.lang.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"> < !-- Mapping file autogenerated by MyEclipse Persistence Tools --> < hibernate-mapping> < class name="edu.jlu.fuliang.domain.Book" table="BOOK" schema="CLASSICCARS"> < id name="id" type="java.lang.Long"> < column name="ID" /> < generator class="identity" /> < /id> < property name="name" type="java.lang.String"> < column name="NAME" length="20" not-null="true" /> < /property> < property name="isbm" type="java.lang.String"> < column name="ISBM" length="20" not-null="true" unique="true" /> < /property> < property name="author" type="java.lang.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/beanshttp://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> < prop key="hibernate.show_sql"> true < /prop> < /props> < /property> < property name="mappingResources"> < list> < value>edujlufuliangdomainBook.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/beanshttp://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层:
edu.jlu.fuliang.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); } edu.jlu.fuliang.service.impl.BookManageServiceImpl.java: package edu.jlu.fuliang.serviceImpl; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import edu.jlu.fuliang.dao.BookDAO; import edu.jlu.fuliang.domain.Book; import edu.jlu.fuliang.service.BookManageService; public class BookManageServiceImpl implements BookManageService{ private static final Log log = LogFactory.getLog(BookManageServiceImpl.class); 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) { log.info(book); bookDAO.attachDirty(book); } public BookDAO getBookDAO() { return bookDAO; } public void setBookDAO(BookDAO bookDAO) { this.bookDAO = bookDAO; } }
然后我们来配置Service和事务:
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/beanshttp://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="sessionFactory"/> < /bean> < bean id="bookManageService" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> < property name="transactionManager" ref="transactionManager"/> < property name="target" ref="bookManageServiceTarget"/> < property name="transactionAttributes"> < props> < prop key="add*">PROPAGATION_REQUIRED< /prop> < prop key="delete*">PROPAGATION_REQUIRED< /prop> < prop key="update*">PROPAGATION_REQUIRED< /prop> < prop key="get*">PROPAGATION_REQUIRED,readOnly< /prop> < /props> < /property> < /bean> < /beans>
最后我们来把dwr整合进来:
我们在web.xml添加ContextLoaderListener来加载applicationContext-db.xml,applicationContext-dao.xm,applicationContext-service.xml,以及配置DwrServlet:
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"> < 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> < servlet> < servlet-name>dwr-invoker< /servlet-name> < servlet-class>org.directwebremoting.servlet.DwrServlet< /servlet-class> < init-param> < param-name>debug< /param-name> < param-value>true< /param-value> < /init-param> < /servlet> < servlet-mapping> < servlet-name>dwr-invoker< /servlet-name> < url-pattern>/dwr/*< /url-pattern> < /servlet-mapping> < /web-app>
在dwr.xml中配制bean的创建方式,类型转换,以及Service要暴露的接口:
< dwr> < allow> < convert converter="bean" match="edu.jlu.fuliang.domain.Book"/> < create creator="spring" javascript="BookManageService" > < param name="beanName" value="bookManageService"/> < include method="getAllBooks"/> < include method="getBookByName"/> < include method="updateBook"/> < include method="addBook"/> < include method="deleteBook"/> < /create> < /allow> < /dwr>
最后,我们编写jsp页面index.jsp:
< html> < head>< title>DWR test< /title> < script type='text/javascript' src='/DWRTest/dwr/interface/BookManageService.js'>< /script> < script type='text/javascript' src='/DWRTest/dwr/engine.js'>< /script> < script type='text/javascript' src='/DWRTest/dwr/util.js'>< /script> < script type="text/javascript"> var bookCache = ...{}; var currentBook = null; function loadAllBooks(){ BookManageService.getAllBooks(handleGetAllBooks,handleGetAllBooksError); } function handleGetAllBooks(books){ dwr.util.removeAllRows("booksBody",{ filter:function(tr) ...{ return (tr.id != "pattern"); }}); var book,id; for(var i = 0; i < books.length; i++){ book = books[i]; id = book.id; dwr.util.cloneNode("pattern", { idSuffix:id }); dwr.util.setValue("t_name" + id, book.name); dwr.util.setValue("t_isbm" + id, book.isbm); dwr.util.setValue("t_author" + id,book.author); $("pattern" + id).style.display = "block"; bookCache[id] = book; } } function handleGetAllBooksError(msg){ alert("Error: " + msg); } function addBook(){ var book = ...{name:null,isbm:null,author:null}; dwr.util.getValues(book); dwr.engine.beginBatch(); BookManageService.addBook(book); loadAllBooks(); dwr.engine.endBatch(); } function editBook(btId){ currentBook = bookCache[btId.substring(4)]; dwr.util.setValues(currentBook); } function updateBook(){ var book = {id:null,name:null,isbm:null,author:null}; dwr.util.getValues(book); book.id = currentBook.id; BookManageService.updateBook(book,handleUpdateBook,handleUpdateBookError); } function handleUpdateBook(){ alert("Update book successfully!"); loadAllBooks(); } function handleUpdateBookError(msg){ alert("Error: " + msg); } function deleteBook(btId){ var i = confirm("Are you sure to delete the book?"); if(i == true) BookManageService.deleteBook(btId.substring(6),handleDeleteBook,handleDeleteBookError); } function handleDeleteBook(){ alert("The book has been delete successfully!"); loadAllBooks(); } function handleDeleteBookError(msg){ alert("Error: " + msg); } < /script> < /head> < body onload="loadAllBooks()"> < div> < h2>Add book< /h2> < table> < tr> < td>Name:< /td>< td>< input type="text" id="name">< /td> < /tr> < tr> < td>ISBN:< /td> < td>< input type="text" id="isbm">< /td> < /tr> < tr> < td>Author:< /td> < td>< input type="text" id="author">< /td> < /tr> < tr> < td colspan="2"> < input type="button" id="add" value="Add" onclick="addBook()"> < input type="button" id="update" value="Update" onclick="updateBook()"> < /td> < /tr> < /table> < /div> < hr> < div id="list"> < table border="1"> < thead> < tr> < th>Name< /th> < th>ISBN< /th> < th>Author< /th> < th>Action< /th> < /tr> < /thead> < tbody id="booksBody"> < tr id="pattern" style="display:none;"> < td> < span id="t_name">< /span> < /td> < td> < span id="t_isbm">< /span> < /td> < td> < span id="t_author">< /span> < /td> < td> < span id="action"> < input id="edit" type="button" value="Edit" onclick="editBook(this.id)"/> < input id="delete" type="button" value="Delete" onclick="deleteBook(this.id)"/> < /span> < /td> < /tr> < /tbody> < /table> < /div> < /body>