- Spring 4.0.6.RELEASE
- Hibernate Core 4.3.6.Final
- validation-api 1.1.0.Final
- hibernate-validator 5.1.3.Final
- MySQL Server 5.6
- Maven 3
- JDK 1.7
- Tomcat 8.0.21
- Eclipse JUNO Service Release 2
- TestNG 6.9.4
- Mockito 1.10.19
- DBUnit 2.2
- H2 Database 1.4.187
现在,让我们开始
第1步:创建目录结构
第2步:更新 pom.xml,包括所需的依赖关系
<?xml version="1.0"?> <project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <modelVersion>4.0.0</modelVersion> <groupId>com.yiibai.springmvc</groupId> <artifactId>SpringHibernateExample</artifactId> <packaging>war</packaging> <version>1.0.0</version> <name>SpringHibernateExample</name> <properties> <springframework.version>4.0.6.RELEASE</springframework.version> <hibernate.version>4.3.6.Final</hibernate.version> <mysql.connector.version>5.1.31</mysql.connector.version> <joda-time.version>2.3</joda-time.version> <testng.version>6.9.4</testng.version> <mockito.version>1.10.19</mockito.version> <h2.version>1.4.187</h2.version> <dbunit.version>2.2</dbunit.version> </properties> <dependencies> <!-- Spring --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-core</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-web</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-tx</artifactId> <version>${springframework.version}</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-orm</artifactId> <version>${springframework.version}</version> </dependency> <!-- Hibernate --> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-core</artifactId> <version>${hibernate.version}</version> </dependency> <!-- jsr303 validation --> <dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>1.1.0.Final</version> </dependency> <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId> <version>5.1.3.Final</version> </dependency> <!-- MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>${mysql.connector.version}</version> </dependency> <!-- Joda-Time --> <dependency> <groupId>joda-time</groupId> <artifactId>joda-time</artifactId> <version>${joda-time.version}</version> </dependency> <!-- To map JodaTime with database type --> <dependency> <groupId>org.jadira.usertype</groupId> <artifactId>usertype.core</artifactId> <version>3.0.0.CR1</version> </dependency> <!-- Servlet+JSP+JSTL --> <dependency> <groupId>javax.servlet</groupId> <artifactId>javax.servlet-api</artifactId> <version>3.1.0</version> </dependency> <dependency> <groupId>javax.servlet.jsp</groupId> <artifactId>javax.servlet.jsp-api</artifactId> <version>2.3.1</version> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <version>1.2</version> </dependency> <!-- Testing dependencies --> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-test</artifactId> <version>${springframework.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.testng</groupId> <artifactId>testng</artifactId> <version>${testng.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-all</artifactId> <version>${mockito.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>com.h2database</groupId> <artifactId>h2</artifactId> <version>${h2.version}</version> <scope>test</scope> </dependency> <dependency> <groupId>dbunit</groupId> <artifactId>dbunit</artifactId> <version>${dbunit.version}</version> <scope>test</scope> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <version>2.4</version> <configuration> <warSourceDirectory>src/main/webapp</warSourceDirectory> <warName>SpringHibernateExample</warName> <failOnMissingWebXml>false</failOnMissingWebXml> </configuration> </plugin> </plugins> </pluginManagement> <finalName>SpringHibernateExample</finalName> </build> </project>
首先要注意这里是%uA0maven-war-plugin%uA0插件声明。由于我们使用的是全注解的配置,所以不包函 web.xml 文件在项目中,所以我们需要配置这个插件以避免 Maven 构建 war 包失败。因为在这个例子中,我们将用一个表单来接受来自用户的输入,我们也需要验证用户的输入。在这里我们将选择JSR303验证,所以我们包括验证,API 代表了规范,hibernate-validator它代表本规范的实现。hibernate-validator%uA0还提供了一些它自己的注解(@Email,@NotEmpty等)不属于规范的一部分。
伴随着这一点,我们也包括%uA0JSP/Servlet/Jstl%uA0依赖关系,也将需要为使用的 servlet%uA0API和JSTL视图在代码中。在一般情况下,容器可能已经包含了这些库,从而在 pom.xml 中“提供”了我们可以设置的范围。
步骤3:配置Hibernate
com.yiibai.springmvc.configuration.HibernateConfiguration
package com.yiibai.springmvc.configuration import java.util.Properties import javax.sql.DataSource import org.hibernate.SessionFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.annotation.Bean import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration import org.springframework.context.annotation.PropertySource import org.springframework.core.env.Environment import org.springframework.jdbc.datasource.DriverManagerDataSource import org.springframework.orm.hibernate4.HibernateTransactionManager import org.springframework.orm.hibernate4.LocalSessionFactoryBean import org.springframework.transaction.annotation.EnableTransactionManagement @Configuration @EnableTransactionManagement @ComponentScan({ "com.yiibai.springmvc.configuration" }) @PropertySource(value = { "classpath:application.properties" }) public class HibernateConfiguration { @Autowired private Environment environment @Bean public LocalSessionFactoryBean sessionFactory() { LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean() sessionFactory.setDataSource(dataSource()) sessionFactory.setPackagesToScan(new String[] { "com.yiibai.springmvc.model" }) sessionFactory.setHibernateProperties(hibernateProperties()) return sessionFactory } @Bean public DataSource dataSource() { DriverManagerDataSource dataSource = new DriverManagerDataSource() dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName")) dataSource.setUrl(environment.getRequiredProperty("jdbc.url")) dataSource.setUsername(environment.getRequiredProperty("jdbc.username")) dataSource.setPassword(environment.getRequiredProperty("jdbc.password")) return dataSource } private Properties hibernateProperties() { Properties properties = new Properties() properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect")) properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql")) properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql")) return properties } @Bean @Autowired public HibernateTransactionManager transactionManager(SessionFactory s) { HibernateTransactionManager txManager = new HibernateTransactionManager() txManager.setSessionFactory(s) return txManager } }%uA0
@Configuration表示该类包含注解为%uA0@Bean生产Bean管理是由Spring容器的一个或多个bean的方法。在我们的例子中,这个类代表hibernate配置。
@ComponentScan%uA0相当于%uA0context:component-scan base-package="..."%uA0在xml文件中配置,%uA0提供Spring在哪里寻找管理ꂾans/classes。
@EnableTransactionManagement%uA0相当于%uA0Spring’s tx:* XML 命名空间,%uA0使Spring注解驱动事务管理能力。
@PropertySource%uA0用于声明一组属性(在属性中定义的应用程序类路径文件)在Spring运行时%uA0Environment,%uA0提供了灵活性,可以在不同的应用环境的不同值。
/src/main/resources/application.properties
jdbc.driverClassName = com.mysql.jdbc.Driver jdbc.url = jdbc:mysql://localhost:3306/yiibai jdbc.username = root jdbc.password = passwd123 hibernate.dialect = org.hibernate.dialect.MySQLDialect hibernate.show_sql = true hibernate.format_sql = true
第4步:配置Spring%uA0MVC
com.yiibai.springmvc.configuration.AppConfig
package com.yiibai.springmvc.configuration import org.springframework.context.MessageSource import org.springframework.context.annotation.Bean import org.springframework.context.annotation.ComponentScan import org.springframework.context.annotation.Configuration import org.springframework.context.support.ResourceBundleMessageSource import org.springframework.web.servlet.ViewResolver import org.springframework.web.servlet.config.annotation.EnableWebMvc import org.springframework.web.servlet.view.InternalResourceViewResolver import org.springframework.web.servlet.view.JstlView @Configuration @EnableWebMvc @ComponentScan(basePackages = "com.yiibai.springmvc") public class AppConfig { @Bean public ViewResolver viewResolver() { InternalResourceViewResolver viewResolver = new InternalResourceViewResolver() viewResolver.setViewClass(JstlView.class) viewResolver.setPrefix("/WEB-INF/views/") viewResolver.setSuffix(".jsp") return viewResolver } @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource() messageSource.setBasename("messages") return messageSource } }
在这篇文章中,我们提交表单并验证用户输入(通过JSR303注解)。在校验失败后,默认的错误消息会显示。要通过自己的自定义覆盖默认的[国际化]从外部消息包的消息[.properties文件],我们需要配置一个ResourceBundleMessageSource。messageSource方法有同样的目的。请注意,以basename方法提供的参数(消息)。Spring将搜索应用程序类路径中一个名为 messages.properties 的文件。让我们添加的文件:
/src/main/resources/messages.properties
Size.employee.name=Name must be between {2} and {1} characters long NotNull.employee.joiningDate=Joining Date can not be blank NotNull.employee.salary=Salary can not be blank Digits.employee.salary=Only numeric data with max 8 digits and with max 2 precision is allowed NotEmpty.employee.ssn=SSN can not be blank typeMismatch=Invalid format non.unique.ssn=SSN {0} already exist. Please fill in different value.
{ValidationAnnotationClass}.{modelObject}.{fieldName}%uA0
此外,根据具体注解(如@Size),你也可以用传递参数给这些消息{0},{1},..{i}索引。
步骤5:配置初始化器类
com.yiibai.springmvc.configuration.AppInitializer
package com.yiibai.springmvc.configuration import javax.servlet.ServletContext import javax.servlet.ServletException import javax.servlet.ServletRegistration import org.springframework.web.WebApplicationInitializer import org.springframework.web.context.support.AnnotationConfigWebApplicationContext import org.springframework.web.servlet.DispatcherServlet public class AppInitializer implements WebApplicationInitializer { public void onStartup(ServletContext container) throws ServletException { AnnotationConfigWebApplicationContext ctx = new AnnotationConfigWebApplicationContext() ctx.register(AppConfig.class) ctx.setServletContext(container) ServletRegistration.Dynamic servlet = container.addServlet( "dispatcher", new DispatcherServlet(ctx)) servlet.setLoadOnStartup(1) servlet.addMapping("/") } }%uA0
上面的内容类似于web.xml,因为我们使用的是前端控制器%uA0DispatcherServlet%uA0的内容,分配映射(URL模式的XML),而不是提供给Spring配置文件(spring-servlet.xml)的路径,在这里我们正在注册的配置类。
更新:请注意,上面的类可以写成更加简洁[最佳方法],通过扩展ꂫstractAnnotationConfigDispatcherServletInitializer%uA0基类,如下所示:
package com.yiibai.springmvc.configuration import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer { @Override protected Class<?>[] getRootConfigClasses() { return new Class[] { AppConfig.class } } @Override protected Class<?>[] getServletConfigClasses() { return null } @Override protected String[] getServletMappings() { return new String[] { "/" } } }
第6步:添加控制器来处理请求
com.yiibai.springmvc.controller.AppController
package com.yiibai.springmvc.controller import java.util.List import java.util.Locale import javax.validation.Valid import org.springframework.beans.factory.annotation.Autowired import org.springframework.context.MessageSource import org.springframework.stereotype.Controller import org.springframework.ui.ModelMap import org.springframework.validation.BindingResult import org.springframework.validation.FieldError import org.springframework.web.bind.annotation.PathVariable import org.springframework.web.bind.annotation.RequestMapping import org.springframework.web.bind.annotation.RequestMethod import com.yiibai.springmvc.model.Employee import com.yiibai.springmvc.service.EmployeeService @Controller @RequestMapping("/") public class AppController { @Autowired EmployeeService service @Autowired MessageSource messageSource /* * This method will list all existing employees. */ @RequestMapping(value = { "/", "/list" }, method = RequestMethod.GET) public String listEmployees(ModelMap model) { List<Employee> employees = service.findAllEmployees() model.addAttribute("employees", employees) return "allemployees" } /* * This method will provide the medium to add a new employee. */ @RequestMapping(value = { "/new" }, method = RequestMethod.GET) public String newEmployee(ModelMap model) { Employee employee = new Employee() model.addAttribute("employee", employee) model.addAttribute("edit", false) return "registration" } /* * This method will be called on form submission, handling POST request for * saving employee in database. It also validates the user input */ @RequestMapping(value = { "/new" }, method = RequestMethod.POST) public String saveEmployee(@Valid Employee employee, BindingResult result, ModelMap model) { if (result.hasErrors()) { return "registration" } /* * Preferred way to achieve uniqueness of field [ssn] should be implementing custom @Unique annotation * and applying it on field [ssn] of Model class [Employee]. * * Below mentioned peace of code [if block] is to demonstrate that you can fill custom errors outside the validation * framework as well while still using internationalized messages. * */ if(!service.isEmployeeSsnUnique(employee.getId(), employee.getSsn())){ FieldError ssnError =new FieldError("employee","ssn",messageSource.getMessage("non.unique.ssn", new String[]{employee.getSsn()}, Locale.getDefault())) result.addError(ssnError) return "registration" } service.saveEmployee(employee) model.addAttribute("success", "Employee " + employee.getName() + " registered successfully") return "success" } /* * This method will provide the medium to update an existing employee. */ @RequestMapping(value = { "/edit-{ssn}-employee" }, method = RequestMethod.GET) public String editEmployee(@PathVariable String ssn, ModelMap model) { Employee employee = service.findEmployeeBySsn(ssn) model.addAttribute("employee", employee) model.addAttribute("edit", true) return "registration" } /* * This method will be called on form submission, handling POST request for * updating employee in database. It also validates the user input */ @RequestMapping(value = { "/edit-{ssn}-employee" }, method = RequestMethod.POST) public String updateEmployee(@Valid Employee employee, BindingResult result, ModelMap model, @PathVariable String ssn) { if (result.hasErrors()) { return "registration" } if(!service.isEmployeeSsnUnique(employee.getId(), employee.getSsn())){ FieldError ssnError =new FieldError("employee","ssn",messageSource.getMessage("non.unique.ssn", new String[]{employee.getSsn()}, Locale.getDefault())) result.addError(ssnError) return "registration" } service.updateEmployee(employee) model.addAttribute("success", "Employee " + employee.getName() + " updated successfully") return "success" } /* * This method will delete an employee by it&aposs SSN value. */ @RequestMapping(value = { "/delete-{ssn}-employee" }, method = RequestMethod.GET) public String deleteEmployee(@PathVariable String ssn) { service.deleteEmployeeBySsn(ssn) return "redirect:/list" } }%uA0
这是一个非常直接的基于Spring的控制器。%uA0@Controller表明这个类是一个控制器在处理与模式映射@RequestMapping请求。这里用“/”,它被作为默认的控制器。
listEmployees方法标注了@%uA0RequestMethod.GET,同时处理默认的网址%uA0“/”%uA0和%uA0‘/list’。它充当处理应用初始页面,显示现有雇员的列表。
newEmployee方法处理新员工注册页面的GET请求,%uA0表示通过模型 Employee 对象支持页面。
方法%uA0saveEmployee%uA0被注解为@%uA0RequestMethod.POST,并且将处理新员工登记表单提交%uA0POST 请求%uA0(‘/new’)。注间这个方法的参数和它们的顺序。
@Valid要求Spring来验证相关的对象(Employee)。%uA0BindingResult包含此验证,并可能在此验证过程中发生任何错误的结果。请注意,BindingResult必须出现在验证对象,否则Spring将无法验证并且抛出一个异常。%uA0如果验证失败,自定义错误信息(因为我们已经配置在步骤4)中显示。
我们还包括代码检查SSN唯一性,因为它声明要在数据库中具有唯一必。保存/更新员工之前要检查,如果SSN是否独一无二。如果没有,我们生成验证错误和重定向到注册页面。%uA0这个代码展示出一种方式来填充在自定义错误校验框架之外,同时仍使用国际化的信息。
第7步:添加DAO层
com.yiibai.springmvc.dao.AbstractDao
package com.yiibai.springmvc.dao import java.io.Serializable import java.lang.reflect.ParameterizedType import org.hibernate.Criteria import org.hibernate.Session import org.hibernate.SessionFactory import org.springframework.beans.factory.annotation.Autowired public abstract class AbstractDao<PK extends Serializable, T> { private final Class<T> persistentClass @SuppressWarnings("unchecked") public AbstractDao(){ this.persistentClass =(Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[1] } @Autowired private SessionFactory sessionFactory protected Session getSession(){ return sessionFactory.getCurrentSession() } @SuppressWarnings("unchecked") public T getByKey(PK key) { return (T) getSession().get(persistentClass, key) } public void persist(T entity) { getSession().persist(entity) } public void delete(T entity) { getSession().delete(entity) } protected Criteria createEntityCriteria(){ return getSession().createCriteria(persistentClass) } }%uA0
这个通用类是所有的DAO实现类的基类。它提供包装方法也是常见的hibernate%uA0操作。
com.yiibai.springmvc.dao.EmployeeDao
package com.yiibai.springmvc.dao import java.util.List import com.yiibai.springmvc.model.Employee public interface EmployeeDao { Employee findById(int id) void saveEmployee(Employee employee) void deleteEmployeeBySsn(String ssn) List<Employee> findAllEmployees() Employee findEmployeeBySsn(String ssn) }
com.yiibai.springmvc.dao.EmployeeDaoImpl
package com.yiibai.springmvc.dao import java.util.List import org.hibernate.Criteria import org.hibernate.Query import org.hibernate.criterion.Restrictions import org.springframework.stereotype.Repository import com.yiibai.springmvc.model.Employee @Repository("employeeDao") public class EmployeeDaoImpl extends AbstractDao<Integer, Employee> implements EmployeeDao { public Employee findById(int id) { return getByKey(id) } public void saveEmployee(Employee employee) { persist(employee) } public void deleteEmployeeBySsn(String ssn) { Query query = getSession().createSQLQuery("delete from Employee where ssn = :ssn") query.setString("ssn", ssn) query.executeUpdate() } @SuppressWarnings("unchecked") public List<Employee> findAllEmployees() { Criteria criteria = createEntityCriteria() return (List<Employee>) criteria.list() } public Employee findEmployeeBySsn(String ssn) { Criteria criteria = createEntityCriteria() criteria.add(Restrictions.eq("ssn", ssn)) return (Employee) criteria.uniqueResult() } }
第8步:添加服务层
com.yiibai.springmvc.service.EmployeeService
package com.yiibai.springmvc.service import java.util.List import com.yiibai.springmvc.model.Employee public interface EmployeeService { Employee findById(int id) void saveEmployee(Employee employee) void updateEmployee(Employee employee) void deleteEmployeeBySsn(String ssn) List<Employee> findAllEmployees() Employee findEmployeeBySsn(String ssn) boolean isEmployeeSsnUnique(Integer id, String ssn) }
com.yiibai.springmvc.service.EmployeeServiceImpl
package com.yiibai.springmvc.service import java.util.List import org.springframework.beans.factory.annotation.Autowired import org.springframework.stereotype.Service import org.springframework.transaction.annotation.Transactional import com.yiibai.springmvc.dao.EmployeeDao import com.yiibai.springmvc.model.Employee @Service("employeeService") @Transactional public class EmployeeServiceImpl implements EmployeeService { @Autowired private EmployeeDao dao public Employee findById(int id) { return dao.findById(id) } public void saveEmployee(Employee employee) { dao.saveEmployee(employee) } /* * Since the method is running with Transaction, No need to call hibernate update explicitly. * Just fetch the entity from db and update it with proper values within transaction. * It will be updated in db once transaction ends. */ public void updateEmployee(Employee employee) { Employee entity = dao.findById(employee.getId()) if(entity!=null){ entity.setName(employee.getName()) entity.setJoiningDate(employee.getJoiningDate()) entity.setSalary(employee.getSalary()) entity.setSsn(employee.getSsn()) } } public void deleteEmployeeBySsn(String ssn) { dao.deleteEmployeeBySsn(ssn) } public List<Employee> findAllEmployees() { return dao.findAllEmployees() } public Employee findEmployeeBySsn(String ssn) { return dao.findEmployeeBySsn(ssn) } public boolean isEmployeeSsnUnique(Integer id, String ssn) { Employee employee = findEmployeeBySsn(ssn) return ( employee == null || ((id != null) && (employee.getId() == id))) } }%uA0
上面最有趣的部分是 @Transactional 它开始在每个方法启动一个事务,并提交其上的每个方法退出(或回滚,如果方法失败,会发生是一个错误)。%uA0注意,因为该事务是在方法范围,和内部的方法,我们将使用DAO,DAO方法将在同一事务内执行。
第9步:创建域实体类(POJO)
com.yiibai.springmvc.model.Employee
package com.yiibai.springmvc.model import java.math.BigDecimal import javax.persistence.Column import javax.persistence.Entity import javax.persistence.GeneratedValue import javax.persistence.GenerationType import javax.persistence.Id import javax.persistence.Table import javax.validation.constraints.Digits import javax.validation.constraints.NotNull import javax.validation.constraints.Size import org.hibernate.annotations.Type import org.hibernate.validator.constraints.NotEmpty import org.joda.time.LocalDate import org.springframework.format.annotation.DateTimeFormat @Entity @Table(name="EMPLOYEE") public class Employee { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private int id @Size(min=3, max=50) @Column(name = "NAME", nullable = false) private String name @NotNull @DateTimeFormat(pattern="dd/MM/yyyy") @Column(name = "JOINING_DATE", nullable = false) @Type(type="org.jadira.usertype.dateandtime.joda.PersistentLocalDate") private LocalDate joiningDate @NotNull @Digits(integer=8, fraction=2) @Column(name = "SALARY", nullable = false) private BigDecimal salary @NotEmpty @Column(name = "SSN", unique=true, nullable = false) private String ssn public int getId() { return id } public void setId(int id) { this.id = id } public String getName() { return name } public void setName(String name) { this.name = name } public LocalDate getJoiningDate() { return joiningDate } public void setJoiningDate(LocalDate joiningDate) { this.joiningDate = joiningDate } public BigDecimal getSalary() { return salary } public void setSalary(BigDecimal salary) { this.salary = salary } public String getSsn() { return ssn } public void setSsn(String ssn) { this.ssn = ssn } @Override public int hashCode() { final int prime = 31 int result = 1 result = prime * result + id result = prime * result + ((ssn == null) ? 0 : ssn.hashCode()) return result } @Override public boolean equals(Object obj) { if (this == obj) return true if (obj == null) return false if (!(obj instanceof Employee)) return false Employee other = (Employee) obj if (id != other.id) return false if (ssn == null) { if (other.ssn != null) return false } else if (!ssn.equals(other.ssn)) return false return true } @Override public String toString() { return "Employee [id=" + id + ", name=" + name + ", joiningDate=" + joiningDate + ", salary=" + salary + ", ssn=" + ssn + "]" } }
第10步:添加视图/JSP
WEB-INF/views/allemployees.jsp%uA0[主页包含所有现有员工列表]
<%@ page language="java" contentType="text/html charset=utf-8" pageEncoding="uft-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <meta http-equiv="Content-Type" content="text/html charset=utf-8"> <title>University Enrollments</title> <style> tr:first-child{ font-weight: bold background-color: #C6C9C4 } </style> </head> <body> <h2>List of Employees</h2> <table> <tr> <td>NAME</td><td>Joining Date</td><td>Salary</td><td>SSN</td><td></td> </tr> <c:forEach items="${employees}" var="employee"> <tr> <td>${employee.name}</td> <td>${employee.joiningDate}</td> <td>${employee.salary}</td> <td><a href="<c:url value=&apos/edit-${employee.ssn}-employee&apos />">${employee.ssn}</a></td> <td><a href="<c:url value=&apos/delete-${employee.ssn}-employee&apos />">delete</a></td> </tr> </c:forEach> </table> <br/> <a href="<c:url value=&apos/new&apos />">Add New Employee</a> </body> </html>
WEB-INF/views/registration.jsp%uA0[注册页面用来创建和保存在数据库中的新员工]
<%@ page language="java" contentType="text/html charset=ISO-8859-1" pageEncoding="ISO-8859-1"%> <%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <meta http-equiv="Content-Type" content="text/html charset=ISO-8859-1"> <title>Employee Registration Form</title> <style> .error { color: #ff0000 } </style> </head> <body> <h2>Registration Form</h2> <form:form method="POST" modelAttribute="employee"> <form:input type="hidden" path="id" id="id"/> <table> <tr> <td><label for="name">Name: </label> </td> <td><form:input path="name" id="name"/></td> <td><form:errors path="name" cssClass="error"/></td> </tr> <tr> <td><label for="joiningDate">Joining Date: </label> </td> <td><form:input path="joiningDate" id="joiningDate"/></td> <td><form:errors path="joiningDate" cssClass="error"/></td> </tr> <tr> <td><label for="salary">Salary: </label> </td> <td><form:input path="salary" id="salary"/></td> <td><form:errors path="salary" cssClass="error"/></td> </tr> <tr> <td><label for="ssn">SSN: </label> </td> <td><form:input path="ssn" id="ssn"/></td> <td><form:errors path="ssn" cssClass="error"/></td> </tr> <tr> <td colspan="3"> <c:choose> <c:when test="${edit}"> <input type="submit" value="Update"/> </c:when> <c:otherwise> <input type="submit" value="Register"/> </c:otherwise> </c:choose> </td> </tr> </table> </form:form> <br/> <br/> Go back to <a href="<c:url value=&apos/list&apos />">List of All Employees</a> </body> </html>
WEB-INF/views/success.jsp%uA0[包括成功页面新员工创建一个确认,并链接回员工列表]
<%@ page language="java" contentType="text/html charset=utf-8" pageEncoding="utf-8"%> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <meta http-equiv="Content-Type" content="text/html charset=utf-8"> <title>Registration Confirmation Page</title> </head> <body> message : ${success} <br/> <br/> Go back to <a href="<c:url value=&apos/list&apos />">List of All Employees</a> </body> </html>
第11步:在数据库创建模式
CREATE TABLE EMPLOYEE( id INT NOT NULL auto_increment, name VARCHAR(50) NOT NULL, joining_date DATE NOT NULL, salary DOUBLE NOT NULL, ssn VARCHAR(30) NOT NULL UNIQUE, PRIMARY KEY (id) )
第12步:构建,部署和运行应用程序
现在构建(参考提到的前面Eclipse教程)或通过Maven的命令行(%uA0mvn clean install).%uA0部署War到Servlet3.0容器。
打开浏览器,浏览:%uA0http://localhost:8080/SpringHibernateExample/
到这里,整个教程完成,包教不包会!