新来公司要做一个小项目,本来打算用nutz做的,结果老大让用spring jpa hibernate框架, 这里hibernate只是托管jpa而已, dao层主要还是用jpa的查询接口,而spring-data做这些系统的粘合剂,很自然mvc层用spring-mvc整合方便配置简单,页面用了bootstrap做样式和sitemesh做模块控制。


下面就谈些具体的步骤吧
我使用的maven管理项目, pom.xml 内容为

<properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
  </properties>

<dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.8.1</version> <scope>test</scope> </dependency> <dependency> <groupId>org.springframework.data</groupId> <artifactId>spring-data-jpa</artifactId> <version>1.1.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-webmvc</artifactId> <version>3.1.3.RELEASE</version> </dependency> <dependency> <groupId>org.springframework</groupId> <artifactId>spring-hibernate3</artifactId> <version>2.0.8</version> <exclusions> <exclusion> <artifactId>hibernate</artifactId> <groupId>org.hibernate</groupId> </exclusion> </exclusions> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>servlet-api</artifactId> <scope>compile</scope> <version>2.5</version> </dependency> <dependency> <groupId>commons-dbcp</groupId> <artifactId>commons-dbcp</artifactId> <version>1.4</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.21</version> </dependency>

&lt;dependency&gt;
	&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
	&lt;artifactId&gt;hibernate-entitymanager&lt;/artifactId&gt;
	&lt;version&gt;4.1.8.Final&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
	&lt;groupId&gt;org.sitemesh&lt;/groupId&gt;
	&lt;artifactId&gt;sitemesh&lt;/artifactId&gt;
	&lt;version&gt;3.0-alpha-1&lt;/version&gt;
&lt;/dependency&gt;

</dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build>

&lt;repositories&gt;  
&lt;repository&gt;  
    &lt;id&gt;java&lt;/id&gt;  
    &lt;name&gt;java official repository&lt;/name&gt;  
    &lt;url&gt;http://download.java.net/maven/2/&lt;/url&gt;  
&lt;/repository&gt;  
&lt;/repositories&gt;  

用到的jar包很明显有spring-mvc ,spring-data-jpa,hibernate 等,这里要注意有几个包会冲突,spring默认依赖的hibernate包版本太低,我这里手动指定了hibernate4,而且hibernate-entitymanager这个是必须的包,还有jpa这个包下载的问题, 需要添加一个源如上


下面从web.xml入手


	<filter>
		<filter-name>CharacterEncodingFilter</filter-name>
		<filter-class>
		org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
		<param-name>encoding</param-name>
		<param-value>UTF-8</param-value>
		</init-param>
	</filter>
	<filter>
	    <filter-name>sitemesh</filter-name>
	    <filter-class>cn.mucang.offlineModule.filters.MetaSitemeshFilter</filter-class>
	  </filter>
	<filter-mapping>
		<filter-name>CharacterEncodingFilter</filter-name>
		<url-pattern>/*</url-pattern>
	</filter-mapping>
	<!-- Processes application requests -->
	<servlet>
		<servlet-name>mvc-dispatcher</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/applicationContext.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>		
	<servlet-mapping>
		<servlet-name>mvc-dispatcher</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
	<filter-mapping>
    <filter-name>sitemesh</filter-name>
    <url-pattern>/*</url-pattern>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>REQUEST</dispatcher>
  </filter-mapping>



这里配置了 编码防止接收的内容出现乱码问题,还有spring-mvc的入口servlet,还有就是 sitemesh了,这个要放到spring-mvc后面,它只需要拦截mvc 转发的jsp请求即可

下面介绍一下包结构:

src下: your.company.package.domains 领域类,

                                          .dao   领域类操作接口

                                          .controllers 控制器

                                          .services  服务层, 方法上可使用 事务注解

                                          .utils      工具类

                                          .filters    这个包看情况添加吧,这里我把自定义了 MetaSitemeshFilter

webapp下  css/ ,js/ ,img/, WEB-INF/templates/ 布局文件,  WEB-INF/views/ 视图

下面是最重要的applicationContext.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"
	xmlns:mvc="http://www.springframework.org/schema/mvc"
	xmlns:context="http://www.springframework.org/schema/context"
	xmlns:jpa="http://www.springframework.org/schema/data/jpa"   
    xmlns:tx="http://www.springframework.org/schema/tx"  
	xsi:schemaLocation="
        http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-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/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa.xsd
        http://www.springframework.org/schema/tx  http://www.springframework.org/schema/tx/spring-tx-3.1.xsd">
	<!-- DispatcherServlet Context: defines this servlet's request-processing infrastructure -->
	<!-- Scans within the base package of the application for @Components to configure as beans -->
	<!-- @Controller, @Service, @Configuration, etc. -->
	<context:component-scan base-package="cn.mucang.offlineModule" />
	<!-- Enables the Spring MVC @Controller programming model -->
	<mvc:annotation-driven />
    <context:annotation-config />  
&lt;bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"&gt;
	&lt;property name="prefix"&gt;
		&lt;value&gt;/WEB-INF/views/&lt;/value&gt;
	&lt;/property&gt;
	&lt;property name="suffix"&gt;
		&lt;value&gt;.jsp&lt;/value&gt;
	&lt;/property&gt;
&lt;/bean&gt;
&lt;!--  spring mvc end --&gt;

&lt;!-- spring jpa start--&gt;

&lt;bean id="dataSource"  
    class="org.apache.commons.dbcp.BasicDataSource"&gt;  
    &lt;property name="username" value="root" /&gt;  
    &lt;property name="password" value="000000" /&gt;  
    &lt;property name="driverClassName" value="com.mysql.jdbc.Driver" /&gt;  
    &lt;property name="url" value="jdbc:mysql://localhost/offline" /&gt;  
&lt;/bean&gt;  


&lt;bean id="entityManagerFactory"  
    class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"&gt;  
    
   &lt;!--  &lt;property name="persistenceUnitName" value="coreJpa" /&gt; --&gt; 
    &lt;property name="dataSource" ref="dataSource" /&gt;  
    &lt;property name="jpaVendorAdapter"&gt;  
        &lt;bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"&gt;  
            &lt;property name="database" value="MYSQL"/&gt;  
            &lt;property name="showSql" value="true"/&gt;  
            &lt;property name="generateDdl" value="true" /&gt;
        &lt;/bean&gt;  
    &lt;/property&gt;  
    &lt;property name="jpaProperties"&gt;  
        &lt;props&gt;  
            &lt;prop key="hibernate.max_fetch_depth" &gt;3&lt;/prop&gt;
            &lt;!--自动输出schema创建DDL语句 --&gt;
            &lt;prop key="hibernate.hbm2ddl.auto" &gt;update&lt;/prop&gt;    
            &lt;prop key="hibernate.show_sql" &gt;true&lt;/prop&gt;
            &lt;prop key="hibernate.format_sql" &gt;true&lt;/prop&gt;
            &lt;prop key="javax.persistence.validation.mode" &gt;none &lt;/prop&gt; 
        &lt;/props&gt;  
    &lt;/property&gt;  
&lt;/bean&gt;  

&lt;jpa:repositories base-package="cn.mucang.offlineModule.dao" query-lookup-strategy="create-if-not-found" /&gt;  
&lt;!--  TX Manager --&gt;   
&lt;bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"&gt;  
    &lt;property name="entityManagerFactory"  ref="entityManagerFactory" /&gt;  
&lt;/bean&gt;  
&lt;tx:annotation-driven/&gt;  
&lt;!-- spring jpa end --&gt;



这里主要配置了 mvc 注解方式和 视图的简化, 还有datasource 和 spring+jpa+hibernate的结合情况,最后添加注解事务控制

这里我配置 hibernate.hbm2ddl.auto=create ,按说明应该是可以生成表结构的,但我测试时没有生成,控制台也没报错,ddl的sql都打印了,初步判断是事务引起的,这个框架中我没有测试事务,多表联合查询也研究,这些我想跟这个配置应该关系不大了,读者有需求去google吧


对了这里还用到了一个hibernate的配置文件 persistence.xml, 放在 src下 META-INF下,

这里面什么内容也没有, 也有种方式是把数据源的配置放到这个文件中,感觉这样配置就太零散了,这个文件中就是空的,但是没有这个文件的话启动会报错

文件内容



<?xml version="1.0" encoding="UTF-8"?>
<persistence xmlns="http://java.sun.com/xml/ns/persistence" version="1.0">
    <persistence-unit name="Teste"   transaction-type="RESOURCE_LOCAL">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
    </persistence-unit>
</persistence>


基本上所有的配置就完了,

下面挨个放出java代码就行

controllers下 HelloController.java文件


@Controller
public class HelloController {
@Autowired
private RuleDao ruleDao;

@RequestMapping("/hello")
public String hello(Model model){
	model.addAttribute("count", ruleDao.count());
	return "hello";
}

}


domains下 Rule.java 文件


@Entity
@Table(name="rule")
public class Rule {
@Id
private Integer id;
@Column(length=100,name="para_key")
private String key;
@Column(length=100,name="para_value")
private String value;
@Column(length=10)
private String operator;
@Column(name="empty_key")
private Boolean emptyKey ;
@Column(name="empty_value")
private Boolean emptyValue;
public Integer getId() {
	return id;
}
public void setId(Integer id) {
	this.id = id;
}
public String getKey() {
	return key;
}
public void setKey(String key) {
	this.key = key;
}
public String getValue() {
	return value;
}
public void setValue(String value) {
	this.value = value;
}
public String getOperator() {
	return operator;
}
public void setOperator(String operator) {
	this.operator = operator;
}
public Boolean getEmptyKey() {
	return emptyKey;
}
public void setEmptyKey(Boolean emptyKey) {
	this.emptyKey = emptyKey;
}
public Boolean getEmptyValue() {
	return emptyValue;
}
public void setEmptyValue(Boolean emptyValue) {
	this.emptyValue = emptyValue;
}

}


这个文件中没有@id的话也会报错,表中必须存在主键

dao中 RuleDao.java


public interface RuleDao extends CrudRepository<Rule, Integer>{

}

这里只需要实现接口即可,简单查询按规则生成方法名就行,复杂的请用@Query或者@NamedQuery进行手动sq查询



到这里基本上就快完工了,再把页面写一下就ok了, 记得在数据库中添加rule表

映射的url为 /hello.do, 输入的视图为 WEB-INF/views/hello.jsp,内容如下:


<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<html>
<head>
<title>Insert title here</title>
<meta name="layout" content="main">
</head>
<body>
   <h2>h3llo  ${count}</h2>
</body>
</html>



这里就用到了metasitemeshfilter 代码如下


public class MetaSitemeshFilter extends ConfigurableSiteMeshFilter{
private final String DECORATOR_PREFIX = "/WEB-INF/templates/";
private final String DECORATOR_SUFFIX = ".jsp";

@Override
protected void applyCustomConfiguration(SiteMeshFilterBuilder builder) {
	super.applyCustomConfiguration(builder);
	builder.setCustomDecoratorSelector(new DecoratorSelector&lt;WebAppContext&gt;() {

		@Override
		public String[] selectDecoratorPaths(Content content,
				WebAppContext context) throws IOException {
			String decoratorPath = content.getExtractedProperties()
					.getChild("meta").getChild("layout").getValue();
			if (decoratorPath == null || decoratorPath.trim().equals(""))
				return new String[] {};
			else
				return new String[] { DECORATOR_PREFIX + decoratorPath.trim()
						+ DECORATOR_SUFFIX };
		}
	});
}



可以看出把会取得jsp中的meta layout的值,然后做为布局文件进行渲染,

因此还要在WEB-INF/templates/下添加main.jsp,这里就很简单了

<html>
<head>
<title ><sitemesh:write property="title"/>- my company</title>
<sitemesh:write property="head"/>
</head>
<body>
&lt;h2&gt;top&lt;/h2&gt;

<div><sitemesh:write property="body"/> </div> <footer> bottom copyright</footer> </body> </html>



然后访问  项目打包放到tomcat中,启动tomcat即可。访问 127.0.0.1:port/appname/hello.do

然后就看到了 top hell2 0 bottom这些任容吧,如果有问题欢迎发邮件。 所有的代码就是这样了