新来公司要做一个小项目,本来打算用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>
<dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-entitymanager</artifactId> <version>4.1.8.Final</version> </dependency> <dependency> <groupId>org.sitemesh</groupId> <artifactId>sitemesh</artifactId> <version>3.0-alpha-1</version> </dependency>
</dependencies> <build> <plugins> <plugin> <artifactId>maven-compiler-plugin</artifactId> <configuration> <source>1.6</source> <target>1.6</target> </configuration> </plugin> </plugins> </build>
<repositories> <repository> <id>java</id> <name>java official repository</name> <url>http://download.java.net/maven/2/</url> </repository> </repositories>
用到的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 /><bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="prefix"> <value>/WEB-INF/views/</value> </property> <property name="suffix"> <value>.jsp</value> </property> </bean> <!-- spring mvc end --> <!-- spring jpa start--> <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="username" value="root" /> <property name="password" value="000000" /> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost/offline" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <!-- <property name="persistenceUnitName" value="coreJpa" /> --> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> <property name="database" value="MYSQL"/> <property name="showSql" value="true"/> <property name="generateDdl" value="true" /> </bean> </property> <property name="jpaProperties"> <props> <prop key="hibernate.max_fetch_depth" >3</prop> <!--自动输出schema创建DDL语句 --> <prop key="hibernate.hbm2ddl.auto" >update</prop> <prop key="hibernate.show_sql" >true</prop> <prop key="hibernate.format_sql" >true</prop> <prop key="javax.persistence.validation.mode" >none </prop> </props> </property> </bean> <jpa:repositories base-package="cn.mucang.offlineModule.dao" query-lookup-strategy="create-if-not-found" /> <!-- TX Manager --> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory" /> </bean> <tx:annotation-driven/> <!-- spring jpa end -->
这里主要配置了 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<WebAppContext>() { @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,这里就很简单了
<div><sitemesh:write property="body"/>
</div>
<footer> bottom copyright</footer>
</body>
</html><html>
<head>
<title ><sitemesh:write property="title"/>- my company</title>
<sitemesh:write property="head"/>
</head>
<body>
<h2>top</h2>
然后访问 项目打包放到tomcat中,启动tomcat即可。访问 127.0.0.1:port/appname/hello.do
然后就看到了 top hell2 0 bottom这些任容吧,如果有问题欢迎发邮件。 所有的代码就是这样了