GWT 2 Spring 3 JPA 2 Hibernate 3.5源码下载
GWT 2 Spring 3 JPA 2 Hibernate 3.5源码下载
展示使用谷歌的Web工具包(GWT)的丰富的客户端结合Spring如何开发一个简单的Web应用程序,主要是CRUD(创建,检索,更新,删除)操作数据库。
- Eclipse 下载: here
- GWT Plugin for Eclipse 下载: here
- Spring 下载: here
- Hibernate 下载: here
- Hypersonic 下载: here
- Apache commons-logging 下载: here
- AOP Alliance 下载: here
- SLF4J 下载: here
- Apache log4j下载: here
- download the GWT – Spring “glue” library spring4gwt from here
实体对象代码:
package com.javacodegeeks.gwtspring.shared.dto;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "EMPLOYEE")
public class EmployeeDTO implements java.io.Serializable {
private static final long serialVersionUID = 7440297955003302414L;
@Id
@Column(name="employee_id")
private long employeeId;
@Column(name="employee_name", nullable = false, length=30)
private String employeeName;
@Column(name="employee_surname", nullable = false, length=30)
private String employeeSurname;
@Column(name="job", length=50)
private String job;
public EmployeeDTO() {
}
public EmployeeDTO(int employeeId) {
this.employeeId = employeeId;
}
public EmployeeDTO(long employeeId, String employeeName, String employeeSurname,
String job) {
this.employeeId = employeeId;
this.employeeName = employeeName;
this.employeeSurname = employeeSurname;
this.job = job;
}
public long getEmployeeId() {
return employeeId;
}
public void setEmployeeId(long employeeId) {
this.employeeId = employeeId;
}
public String getEmployeeName() {
return employeeName;
}
public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}
public String getEmployeeSurname() {
return employeeSurname;
}
public void setEmployeeSurname(String employeeSurname) {
this.employeeSurname = employeeSurname;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
}
Spring配置:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context"
xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:component-scan base-package="com.javacodegeeks.gwtspring"/>
<task:annotation-driven executor="myExecutor" scheduler="myScheduler"/>
<task:executor id="myExecutor" pool-size="5"/>
<task:scheduler id="myScheduler" pool-size="10"/>
<tx:annotation-driven/>
<bean class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean" id="entityManagerFactory">
<property name="persistenceUnitName" value="MyPersistenceUnit"/>
</bean>
<bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
</beans>
Hibernate配置 /resources/META-INF/persistence.xml :
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
version="2.0">
<persistence-unit name="MyPersistenceUnit" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<properties>
<property name="hibernate.hbm2ddl.auto" value="update"/>
<property name="hibernate.show_sql" value="false"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect"/>
<property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver"/>
<property name="hibernate.connection.url" value="jdbc:hsqldb:mem:javacodegeeks"/>
<property name="hibernate.connection.username" value="sa"/>
<property name="hibernate.connection.password" value=""/>
<property name="hibernate.c3p0.min_size" value="5"/>
<property name="hibernate.c3p0.max_size" value="20"/>
<property name="hibernate.c3p0.timeout" value="300"/>
<property name="hibernate.c3p0.max_statements" value="50"/>
<property name="hibernate.c3p0.idle_test_period" value="3000"/>
</properties>
</persistence-unit>
</persistence>
DAO通用接口:
package com.javacodegeeks.gwtspring.server.dao;
import java.lang.reflect.ParameterizedType;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceException;
import javax.persistence.Query;
import org.springframework.orm.jpa.JpaCallback;
import org.springframework.orm.jpa.support.JpaDaoSupport;
public abstract class JpaDAO<K, E> extends JpaDaoSupport {
protected Class<E> entityClass;
@SuppressWarnings("unchecked")
public JpaDAO() {
ParameterizedType genericSuperclass = (ParameterizedType) getClass()
.getGenericSuperclass();
this.entityClass = (Class<E>) genericSuperclass
.getActualTypeArguments()[1];
}
public void persist(E entity) {
getJpaTemplate().persist(entity);
}
public void remove(E entity) {
getJpaTemplate().remove(entity);
}
public E merge(E entity) {
return getJpaTemplate().merge(entity);
}
public void refresh(E entity) {
getJpaTemplate().refresh(entity);
}
public E findById(K id) {
return getJpaTemplate().find(entityClass, id);
}
public E flush(E entity) {
getJpaTemplate().flush();
return entity;
}
@SuppressWarnings("unchecked")
public List<E> findAll() {
Object res = getJpaTemplate().execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
Query q = em.createQuery("SELECT h FROM " +
entityClass.getName() + " h");
return q.getResultList();
}
});
return (List<E>) res;
}
@SuppressWarnings("unchecked")
public Integer removeAll() {
return (Integer) getJpaTemplate().execute(new JpaCallback() {
public Object doInJpa(EntityManager em) throws PersistenceException {
Query q = em.createQuery("DELETE FROM " +
entityClass.getName() + " h");
return q.executeUpdate();
}
});
}
}
服务代码:
package com.javacodegeeks.gwtspring.server.services;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import com.javacodegeeks.gwtspring.server.dao.EmployeeDAO;
import com.javacodegeeks.gwtspring.shared.dto.EmployeeDTO;
import com.javacodegeeks.gwtspring.shared.services.EmployeeService;
@Service("employeeService")
public class EmployeeServiceImpl implements EmployeeService {
@Autowired
private EmployeeDAO employeeDAO;
@PostConstruct
public void init() throws Exception {
}
@PreDestroy
public void destroy() {
}
public EmployeeDTO findEmployee(long employeeId) {
return employeeDAO.findById(employeeId);
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void saveEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception {
EmployeeDTO employeeDTO = employeeDAO.findById(employeeId);
if(employeeDTO == null) {
employeeDTO = new EmployeeDTO(employeeId, name,surname, jobDescription);
employeeDAO.persist(employeeDTO);
}
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void updateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception {
EmployeeDTO employeeDTO = employeeDAO.findById(employeeId);
if(employeeDTO != null) {
employeeDTO.setEmployeeName(name);
employeeDTO.setEmployeeSurname(surname);
employeeDTO.setJob(jobDescription);
}
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void deleteEmployee(long employeeId) throws Exception {
EmployeeDTO employeeDTO = employeeDAO.findById(employeeId);
if(employeeDTO != null)
employeeDAO.remove(employeeDTO);
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void saveOrUpdateEmployee(long employeeId, String name, String surname, String jobDescription) throws Exception {
EmployeeDTO employeeDTO = new EmployeeDTO(employeeId, name,surname, jobDescription);
employeeDAO.merge(employeeDTO);
}
}
下面是GWTSpring 代码:
import com.google.gwt.core.client.EntryPoint;
import com.google.gwt.core.client.GWT;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.KeyCodes;
import com.google.gwt.event.dom.client.KeyUpEvent;
import com.google.gwt.event.dom.client.KeyUpHandler;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.DialogBox;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.RootPanel;
import com.google.gwt.user.client.ui.TextBox;
import com.google.gwt.user.client.ui.VerticalPanel;
import com.javacodegeeks.gwtspring.shared.dto.EmployeeDTO;
import com.javacodegeeks.gwtspring.shared.services.EmployeeService;
import com.javacodegeeks.gwtspring.shared.services.EmployeeServiceAsync;
/**
* Entry point classes define <code>onModuleLoad()</code>.
*/
public class GWTSpring implements EntryPoint {
/**
* The message displayed to the user when the server cannot be reached or
* returns an error.
*/
private static final String SERVER_ERROR = "An error occurred while "
+ "attempting to contact the server. Please check your network "
+ "connection and try again. The error is : ";
/**
* Create a remote service proxy to talk to the server-side Employee service.
*/
private final EmployeeServiceAsync employeeService = GWT
.create(EmployeeService.class);
/**
* This is the entry point method.
*/
public void onModuleLoad() {
final Button saveOrUpdateButton = new Button("SaveOrUpdate");
final Button retrieveButton = new Button("Retrieve");
final TextBox employeeInfoField = new TextBox();
employeeInfoField.setText("Employee Info");
final TextBox employeeIdField = new TextBox();
final Label errorLabel = new Label();
// We can add style names to widgets
saveOrUpdateButton.addStyleName("sendButton");
retrieveButton.addStyleName("sendButton");
// Add the nameField and sendButton to the RootPanel
// Use RootPanel.get() to get the entire body element
RootPanel.get("employeeInfoFieldContainer").add(employeeInfoField);
RootPanel.get("updateEmployeeButtonContainer").add(saveOrUpdateButton);
RootPanel.get("employeeIdFieldContainer").add(employeeIdField);
RootPanel.get("retrieveEmployeeButtonContainer").add(retrieveButton);
RootPanel.get("errorLabelContainer").add(errorLabel);
// Focus the cursor on the name field when the app loads
employeeInfoField.setFocus(true);
employeeInfoField.selectAll();
// Create the popup dialog box
final DialogBox dialogBox = new DialogBox();
dialogBox.setText("Remote Procedure Call");
dialogBox.setAnimationEnabled(true);
final Button closeButton = new Button("Close");
// We can set the id of a widget by accessing its Element
closeButton.getElement().setId("closeButton");
final Label textToServerLabel = new Label();
final HTML serverResponseLabel = new HTML();
VerticalPanel dialogVPanel = new VerticalPanel();
dialogVPanel.addStyleName("dialogVPanel");
dialogVPanel.add(new HTML("<b>Sending request to the server:</b>"));
dialogVPanel.add(textToServerLabel);
dialogVPanel.add(new HTML("
<b>Server replies:</b>"));
dialogVPanel.add(serverResponseLabel);
dialogVPanel.setHorizontalAlignment(VerticalPanel.ALIGN_RIGHT);
dialogVPanel.add(closeButton);
dialogBox.setWidget(dialogVPanel);
// Add a handler to close the DialogBox
closeButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
dialogBox.hide();
saveOrUpdateButton.setEnabled(true);
saveOrUpdateButton.setFocus(true);
retrieveButton.setEnabled(true);
}
});
// Create a handler for the saveOrUpdateButton and employeeInfoField
class SaveOrUpdateEmployeeHandler implements ClickHandler, KeyUpHandler {
/**
* Fired when the user clicks on the saveOrUpdateButton.
*/
public void onClick(ClickEvent event) {
sendEmployeeInfoToServer();
}
/**
* Fired when the user types in the employeeInfoField.
*/
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
sendEmployeeInfoToServer();
}
}
/**
* Send the employee info from the employeeInfoField to the server and wait for a response.
*/
private void sendEmployeeInfoToServer() {
// First, we validate the input.
errorLabel.setText("");
String textToServer = employeeInfoField.getText();
// Then, we send the input to the server.
saveOrUpdateButton.setEnabled(false);
textToServerLabel.setText(textToServer);
serverResponseLabel.setText("");
String[] employeeInfo = textToServer.split(" ");
long employeeId = Long.parseLong(employeeInfo[0]);
String employeeName = employeeInfo[1];
String employeeSurname = employeeInfo[2];
String employeeJobTitle = employeeInfo[3];
employeeService.saveOrUpdateEmployee(employeeId, employeeName, employeeSurname, employeeJobTitle,
new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
dialogBox
.setText("Remote Procedure Call - Failure");
serverResponseLabel
.addStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(SERVER_ERROR + caught.toString());
dialogBox.center();
closeButton.setFocus(true);
}
public void onSuccess(Void noAnswer) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel
.removeStyleName("serverResponseLabelError");
serverResponseLabel.setHTML("OK");
dialogBox.center();
closeButton.setFocus(true);
}
});
}
}
// Create a handler for the retrieveButton and employeeIdField
class RetrieveEmployeeHandler implements ClickHandler, KeyUpHandler {
/**
* Fired when the user clicks on the retrieveButton.
*/
public void onClick(ClickEvent event) {
sendEmployeeIdToServer();
}
/**
* Fired when the user types in the employeeIdField.
*/
public void onKeyUp(KeyUpEvent event) {
if (event.getNativeKeyCode() == KeyCodes.KEY_ENTER) {
sendEmployeeIdToServer();
}
}
/**
* Send the id from the employeeIdField to the server and wait for a response.
*/
private void sendEmployeeIdToServer() {
// First, we validate the input.
errorLabel.setText("");
String textToServer = employeeIdField.getText();
// Then, we send the input to the server.
retrieveButton.setEnabled(false);
textToServerLabel.setText(textToServer);
serverResponseLabel.setText("");
employeeService.findEmployee(Long.parseLong(textToServer),
new AsyncCallback<EmployeeDTO>() {
public void onFailure(Throwable caught) {
// Show the RPC error message to the user
dialogBox
.setText("Remote Procedure Call - Failure");
serverResponseLabel
.addStyleName("serverResponseLabelError");
serverResponseLabel.setHTML(SERVER_ERROR + caught.toString());
dialogBox.center();
closeButton.setFocus(true);
}
public void onSuccess(EmployeeDTO employeeDTO) {
dialogBox.setText("Remote Procedure Call");
serverResponseLabel
.removeStyleName("serverResponseLabelError");
if(employeeDTO != null)
serverResponseLabel.setHTML("Employee Information Id : " + employeeDTO.getEmployeeId() + " Name : " + employeeDTO.getEmployeeName() + " Surname : " + employeeDTO.getEmployeeSurname() + " Job Title : " + employeeDTO.getJob());
else
serverResponseLabel.setHTML("No employee with the specified id found");
dialogBox.center();
closeButton.setFocus(true);
}
});
}
}
// Add a handler to send the employee info to the server
SaveOrUpdateEmployeeHandler saveOrUpdateEmployeehandler = new SaveOrUpdateEmployeeHandler();
saveOrUpdateButton.addClickHandler(saveOrUpdateEmployeehandler);
employeeInfoField.addKeyUpHandler(saveOrUpdateEmployeehandler);
// Add a handler to send the employee id to the server
RetrieveEmployeeHandler retrieveEmployeehandler = new RetrieveEmployeeHandler();
retrieveButton.addClickHandler(retrieveEmployeehandler);
employeeIdField.addKeyUpHandler(retrieveEmployeehandler);
}
}
相应的Html:
<!doctype html>
<!-- The DOCTYPE declaration above will set the -->
<!-- browser's rendering engine into -->
<!-- "Standards Mode". Replacing this declaration -->
<!-- with a "Quirks Mode" doctype may lead to some -->
<!-- differences in layout. -->
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<!-- -->
<!-- Consider inlining CSS to reduce the number of requested files -->
<!-- -->
<link type="text/css" rel="stylesheet" href="GWTSpring.css">
<!-- -->
<!-- Any title is fine -->
<!-- -->
<title>Spring GWT Web Application Starter Project</title>
<!-- -->
<!-- This script loads your compiled module. -->
<!-- If you add any GWT meta tags, they must -->
<!-- be added before this line. -->
<!-- -->
<script type="text/javascript" language="javascript" src="gwtspring/gwtspring.nocache.js"></script>
</head>
<!-- -->
<!-- The body can have arbitrary html, or -->
<!-- you can leave the body empty if you want -->
<!-- to create a completely dynamic UI. -->
<!-- -->
<body>
<!-- OPTIONAL: include this if you want history support -->
<iframe src="javascript:''" id="__gwt_historyFrame" tabIndex='-1' style="position:absolute;width:0;height:0;border:0"></iframe>
<!-- RECOMMENDED if your web app will not function without JavaScript enabled -->
<noscript>
<div style="width: 22em; position: absolute; left: 50%; margin-left: -11em; color: red; background-color: white; border: 1px solid red; padding: 4px; font-family: sans-serif">
Your web browser must have JavaScript enabled
in order for this application to display correctly.
</div>
</noscript>
<h1>Spring GWT Web Application Starter Project</h1>
<table align="center">
<tr>
<td colspan="2" style="font-weight:bold;">Please enter employee info (id name surname job):</td>
</tr>
<tr>
<td id="employeeInfoFieldContainer"></td>
<td id="updateEmployeeButtonContainer"></td>
</tr>
<tr>
<tr>
<td colspan="2" style="font-weight:bold;">Please enter employee id:</td>
</tr>
<tr>
<td id="employeeIdFieldContainer"></td>
<td id="retrieveEmployeeButtonContainer"></td>
</tr>
<tr>
<td colspan="2" style="color:red;" id="errorLabelContainer"></td>
</tr>
</table>
</body>
</html>
部署访问:
http://localhost:8080/GWTSpring/