您的位置:首页 > 编程语言 > Java开发

121 基于MVC框架下的网上书店系统 003 初始化 Maven 环境

2016-09-12 00:00 363 查看
摘要: 还需要解决 Maven Profiile与IndexController无法访问的问题

关于环境搭建

  我的开发环境是windows,测试环境是我在vmware虚拟机里安装的centos。也就是说在windows上测试通过之后再把代码pull到vmware的centos中测试。毕竟没有钱买服务器,我感觉这样做也不错,且更加接近真实环境。

遇到的问题

  第一个问题是windows环境和Linux环境不一样,这就导致我把代码pull到centos中的时候还要手工修改一些配置。比如说日志生成路径,再比如说文件上传路径。至于解决方法就要看我用的是Maven构建还是Gradle构建了。Maven提供了profile功能,而Gradle虽然没有提供这个功能,不过还是可以解决的,目前想到的Gradle的解决方法就是再打包之前先执行一段脚本,修改配置。

  第二个问题是IndexController在本场可以访问,但是在Linux中就是404,我必须添加一个index.jsp才可以。解决方案就是添加一个首页,再设置转向。不过这个我还没有开始处理。

  第三个问题是初始化数据。其实就现在来说,主要是进行几个路径的检查,比如说文件上传路径等。这个可以实现ApplicationListener的onApplicationEvent方法来实现。

  第四个问题是关于sts的问题。就是那个spring管理文件会有一个蓝色的 s 标记,但是这个标记经常会消失,随之消失的还有aop的标记。虽然这几个标记有或者没有对我没什么影响,不过既然有,为什么不用呢?解决方法就是项目->属性,设置spring插件的配置,这个东西我会稍后写出来。

  第五个问题是关于Eclipse创建Maven项目不支持servlet 3.0 的问题,这个网上的解决方案到处都是,之后记录下来即可。

源码

  我现在的项目是这个样子的:



pom.xml

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.laolang.gongda</groupId>
<artifactId>bookshop</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>bookshop Maven Webapp</name>
<url>http://maven.apache.org</url>

<properties>
<!-- 依赖版本信息 -->
<spring.version>4.1.9.RELEASE</spring.version>
<hibernate.version>4.2.21.Final</hibernate.version>

<!-- 项目相关 -->
<!-- 文件拷贝时的编码 -->
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<!-- 编译时的编码 -->
<maven.compiler.encoding>UTF-8</maven.compiler.encoding>
</properties>

<dependencies>
<!-- test -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hamcrest</groupId>
<artifactId>hamcrest-all</artifactId>
<version>1.3</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.dbunit</groupId>
<artifactId>dbunit</artifactId>
<version>2.5.0</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.github.springtestdbunit</groupId>
<artifactId>spring-test-dbunit</artifactId>
<version>1.2.1</version>
<scope>test</scope>
</dependency>

<!-- java ee -->
<dependency>
<groupId>javax</groupId>
<artifactId>javaee-api</artifactId>
<version>7.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.0.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>jstl</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>taglibs</groupId>
<artifactId>standard</artifactId>
<version>1.1.2</version>
</dependency>

<!-- spring -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-oxm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aop</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>

<!-- spring data -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-commons</artifactId>
<version>1.11.1.RELEASE</version>
</dependency>

<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.9.2.RELEASE</version>
</dependency>

<!-- 数据库 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.30</version>
</dependency>

<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.0.12</version>
</dependency>

<!-- hibernate -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>${hibernate.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-ehcache</artifactId>
<version>${hibernate.version}</version>
</dependency>

<!-- JSR 303 <dependency> <groupId>org.hibernate</groupId> <artifactId>hibernate-validator</artifactId>
<version>4.2.0.Final</version> </dependency> <dependency> <groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId> <version>1.0.0.GA</version> </dependency> -->

<!-- json -->
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-core</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-annotations</artifactId>
<version>2.2.3</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.2.2</version>
</dependency>

<!-- commons -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-lang3</artifactId>
<version>3.0</version>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-io</artifactId>
<version>1.3.2</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3.2</version>
</dependency>

<!-- logback -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.13</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
<version>1.7.12</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.3</version>
</dependency>
<dependency>
<groupId>org.logback-extensions</groupId>
<artifactId>logback-ext-spring</artifactId>
<version>0.1.2</version>
</dependency>

</dependencies>
<build>
<finalName>bookshop</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.tomcat.maven</groupId>
<artifactId>tomcat7-maven-plugin</artifactId>    <!--这里也可以使用tomcat7-maven-plugin -->
<version>2.2</version>   <!--最新版本 -->
<configuration>
<url>http://localhost:8080/manager/text</url>    <!--配置远程tomcat的路劲 -->
<username>admin</username>
<password>admin</password>
<uriEncoding>UTF-8</uriEncoding>   <!--tomcat的url编码 达到和修改server.xml文件一样的功能 -->
</configuration>
</plugin>
</plugins>
</build>

<reporting>
<plugins>
<!-- mvn cobertura:help 查看cobertura插件的帮助 -->
<!-- mvn cobertura:clean 清空cobertura插件运行结果 -->
<!-- mvn cobertura:check 运行cobertura的检查任务 -->
<!-- mvn cobertura:cobertura 运行cobertura的检查任务并生成报表,报表生成在target/site/cobertura目录下 -->
<!-- cobertura:dump-datafile Cobertura Datafile Dump Mojo -->
<!-- mvn cobertura:instrument Instrument the compiled classes -->
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>cobertura-maven-plugin</artifactId>
<version>2.5.1</version>
</plugin>
</plugins>
</reporting>
</project>

配置文件

  由于src/main/resources/与src/test/resource的配置文件除了日志文件名之外基本没有区别,所以这里只贴出src/main/resources中的配置文件

db.propreties

jdbc.user=root
jdbc.password=root
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.jdbcUrl=jdbc:mysql://localhost:3306/bookshop?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true

jdbc.initPoolSize=5
jdbc.maxPoolSize=10

ehcache.xml

  这个其实就是默认配置

<ehcache>

<!-- Sets the path to the directory where cache .data files are created.

If the path is a Java System Property it is replaced by
its value in the running VM.

The following properties are translated:
user.home - User's home directory
user.dir - User's current working directory
java.io.tmpdir - Default temp file path -->
<diskStore path="java.io.tmpdir"/>

<!--Default Cache configuration. These will applied to caches programmatically created through
the CacheManager.

The following attributes are required for defaultCache:

maxInMemory       - Sets the maximum number of objects that will be created in memory
eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.

-->
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>

<!--Predefined caches.  Add your cache configuration settings here.
If you do not have a configuration for your cache a WARNING will be issued when the
CacheManager starts

The following attributes are required for defaultCache:

name              - Sets the name of the cache. This is used to identify the cache. It must be unique.
maxInMemory       - Sets the maximum number of objects that will be created in memory
eternal           - Sets whether elements are eternal. If eternal,  timeouts are ignored and the element
is never expired.
timeToIdleSeconds - Sets the time to idle for an element before it expires. Is only used
if the element is not eternal. Idle time is now - last accessed time
timeToLiveSeconds - Sets the time to live for an element before it expires. Is only used
if the element is not eternal. TTL is now - creation time
overflowToDisk    - Sets whether elements can overflow to disk when the in-memory cache
has reached the maxInMemory limit.

-->

<!-- Sample cache named sampleCache1
This cache contains a maximum in memory of 10000 elements, and will expire
an element if it is idle for more than 5 minutes and lives for more than
10 minutes.

If there are more than 10000 elements it will overflow to the
disk cache, which in this configuration will go to wherever java.io.tmp is
defined on your system. On a standard Linux system this will be /tmp"
-->
<cache name="sampleCache1"
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="300"
timeToLiveSeconds="600"
overflowToDisk="true"
/>

<!-- Sample cache named sampleCache2
This cache contains 1000 elements. Elements will always be held in memory.
They are not expired. -->
<cache name="sampleCache2"
maxElementsInMemory="1000"
eternal="true"
timeToIdleSeconds="0"
timeToLiveSeconds="0"
overflowToDisk="false"
/> -->

<!-- Place configuration for your caches following -->

</ehcache>

logback.xml

  关于logback需要指出的是,如果日志文件的路径写相对路径的话,是不行的。当然也不是不生成文件,只是生成路径的根路径是以eclipse为参照的。所以我这里写的是绝对路径。也可以通过环境变量的方式来解决。

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!--定义日志文件的存储地址 勿在 LogBack 的配置中使用相对路径 -->
<property name="LOG_HOME" value="D:/projectpath/bookshop/logs" />
<property name="LOG_FILE_NAME" value="bookshop" />
<property name="LOG_INFO_FILE_NAME" value="bookshop-info" />
<!-- 控制台输出 -->
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- 日志输出编码 -->
<Encoding>UTF-8</Encoding>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -
%msg%n
</pattern>
</layout>
</appender>
<!-- 按照每天生成日志文件 -->
<appender name="FILE"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<Encoding>UTF-8</Encoding>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!--日志文件输出的文件名 -->
<FileNamePattern>${LOG_HOME}/${LOG_FILE_NAME}.log.%d{yyyy-MM-dd}.log
</FileNamePattern>
<MaxHistory>30</MaxHistory>
</rollingPolicy>
<layout class="ch.qos.logback.classic.PatternLayout">
<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符 -->
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -[%file]:[%line] -
%msg%n
</pattern>
</layout>
<!--日志文件最大的大小 -->
<triggeringPolicy
class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<MaxFileSize>10MB</MaxFileSize>
</triggeringPolicy>
</appender>

<!-- show sql -->
<logger name="org.hibernate.type.descriptor.sql.BasicBinder"
level="TRACE" />
<logger name="org.hibernate.type.descriptor.sql.BasicExtractor"
level="DEBUG" />
<logger name="org.hibernate.SQL" level="DEBUG" />
<logger name="org.hibernate.type" level="TRACE" />
<logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />
<logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />

<!-- info 日志 -->
<appender name="infoAppender"
class="ch.qos.logback.core.rolling.RollingFileAppender">
<Encoding>UTF-8</Encoding>
<file>${LOG_HOME}/${LOG_INFO_FILE_NAME}.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_HOME}/${LOG_INFO_FILE_NAME}.log.%d{yyyy-MM-dd}.log
</fileNamePattern>
</rollingPolicy>
<encoder>
<pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} -[%file]:[%line] -
%msg%n
</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter"><!-- 只打印错误日志 -->
<level>INFO</level>
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>

<logger name="infoLog" level="INFO"
additivity="true">
<appender-ref ref="infoAppender" />
</logger>

<!-- 日志输出级别 -->
<root level="DEBUG">
<appender-ref ref="STDOUT" />
<appender-ref ref="FILE" />
</root>

<!--日志异步到数据库 -->
<!-- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender"> <connectionSource
class="ch.qos.logback.core.db.DriverManagerConnectionSource"> <dataSource
class="com.mchange.v2.c3p0.ComboPooledDataSource"> <driverClass>com.mysql.jdbc.Driver</driverClass>
<url>jdbc:mysql://127.0.0.1:3306/databaseName</url> <user>root</user> <password>root</password>
</dataSource> </connectionSource> </appender> -->
</configuration>

spring-public.xml

  这个文件配置了一些公用的bean,比如说Configuration这个bean主要是配置关于文件上传路径,网站主题风格【现在还没有,但是将来会有的】的配置。

<?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:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> 
<context:component-scan base-package="com.laolang.gongda"></context:component-scan>

<!-- configuration  -->
<bean id="configuration" class="com.laolang.gongda.bookshop.config.Configuration">
<property name="headPicPath" value="D:/projectpath/bookshop/headpic"></property>
</bean>
</beans>

spring-mvc.xml

  这只是一个最简单的配置,之后关于spring mvc 的东西我会记录在这个系列的博客中,比如Enum映射问题。

<?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"
xsi:schemaLocation="http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> 
<!-- 扫描包 -->
<context:component-scan base-package="com.laolang.gongda.bookshop.web"></context:component-scan>

<!-- -->
<mvc:annotation-driven>
</mvc:annotation-driven>

<!-- 静态资源映射 -->
<mvc:resources mapping="/assets/**" location="/assets/" />

<!-- 视图解析器 -->
<bean
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/views/"></property>
<property name="suffix" value=".jsp"></property>
</bean>

<!-- 配置 MultipartResolver -->
<bean id="multipartResolver"
class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="UTF-8"></property>
<property name="maxUploadSize" value="1024000"></property>
</bean>

</beans>

spring-jpa.xml

  现在我使用的数据源是druid,之后要更换为JNDI的。

<?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:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
xsi:schemaLocation="http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.1.xsd http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.1.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.8.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.1.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd"> 
<!-- 配置自动扫描的包 -->
<context:component-scan base-package="com.laolang.gongda"></context:component-scan>

<!-- 配置 druid数据源 -->
<context:property-placeholder location="classpath:db.properties" />

<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource"
init-method="init" destroy-method="close">
<!-- 基本属性 url、user、password -->
<property name="url" value="${jdbc.jdbcUrl}" />
<property name="username" value="${jdbc.user}" />
<property name="password" value="${jdbc.password}" />

<!-- 配置初始化大小、最小、最大 -->
<property name="initialSize" value="1" />
<property name="minIdle" value="1" />
<property name="maxActive" value="20" />

<!-- 配置获取连接等待超时的时间 -->
<property name="maxWait" value="60000" />

<!-- 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 -->
<property name="timeBetweenEvictionRunsMillis" value="60000" />

<!-- 配置一个连接在池中最小生存的时间,单位是毫秒 -->
<property name="minEvictableIdleTimeMillis" value="300000" />

<property name="validationQuery" value="SELECT 'x'" />
<property name="testWhileIdle" value="true" />
<property name="testOnBorrow" value="false" />
<property name="testOnReturn" value="false" />

<!-- 打开PSCache,并且指定每个连接上PSCache的大小 -->
<property name="poolPreparedStatements" value="true" />
<property name="maxPoolPreparedStatementPerConnectionSize"
value="20" />

<!-- 配置监控统计拦截的filters,去掉后监控界面sql无法统计 -->
<property name="filters" value="stat" />
</bean>

<!-- 配置 JPA 的 EntityManagerFactory -->
<bean id="entityManagerFactory"
class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean>
</property>
<property name="packagesToScan" value="com.laolang.gongda"></property>
<property name="jpaProperties">
<props>
<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>

<prop key="hibernate.cache.use_second_level_cache">true</prop>
<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
</props>
</property>
<property name="sharedCacheMode" value="ENABLE_SELECTIVE"></property>
</bean>

<!-- 配置 JPA 使用的事务管理器 -->
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>

<!-- 配置支持基于注解的事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />

<!-- 配置 SpringData -->
<jpa:repositories base-package="com.laolang.gongda"
entity-manager-factory-ref="entityManagerFactory"></jpa:repositories>
</beans>

代码

数据库操作

实体类 UserStatus

package com.laolang.gongda.bookshop.domain;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Version;

@Entity
@Table(name = "user_status")
public class UserStatus implements Serializable {

private static final long serialVersionUID = 1L;

public UserStatus() {
super();
}

public UserStatus(String statusName, String statusDesc) {
super();
this.statusName = statusName;
this.statusDesc = statusDesc;
}

@Override
public String toString() {
return "UserStatus [id=" + id + ", statusName=" + statusName + ", statusDesc=" + statusDesc + ", version=" + version + "]";
}

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getStatusName() {
return statusName;
}

public void setStatusName(String statusName) {
this.statusName = statusName;
}

public String getStatusDesc() {
return statusDesc;
}

public void setStatusDesc(String statusDesc) {
this.statusDesc = statusDesc;
}

public Integer getVersion() {
return version;
}

public void setVersion(Integer version) {
this.version = version;
}

@Id
@GeneratedValue
private Integer id;

@Column(name = "status_name", unique = true)
private String statusName;

@Column(name = "status_desc")
private String statusDesc;

@Version
private Integer version;

}


UserStatusRepository

package com.laolang.gongda.bookshop.repository;

import java.util.List;

import org.springframework.data.jpa.repository.JpaRepository;

import com.laolang.gongda.bookshop.domain.UserStatus;

public interface UserStatusRepository extends JpaRepository<UserStatus, Integer> {

public List<UserStatus> findByStatusName( String statusName );

}


UserStatusService

package com.laolang.gongda.bookshop.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.laolang.gongda.bookshop.domain.UserStatus;
import com.laolang.gongda.bookshop.repository.UserStatusRepository;

@Service
public class UserStatusService {

@Autowired
private UserStatusRepository userStatusRepository;

@Transactional
public void save( UserStatus userStatus){
userStatusRepository.save(userStatus);
}

@Transactional
public void delete( Integer id ){
userStatusRepository.delete(id);
}

@Transactional(readOnly=true)
public UserStatus find( Integer id ){
return userStatusRepository.findOne(id);
}

@Transactional(readOnly=true)
public List<UserStatus> findByStatusName( String statusName ){
return userStatusRepository.findByStatusName(statusName);
}

}

controller

IndexController

  这个还有问题,稍后会解决。

package com.laolang.gongda.bookshop.web;

import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.laolang.gongda.bookshop.domain.UserStatus;
import com.laolang.gongda.bookshop.service.UserStatusService;

/**
* 首页处理器,在访问首页时,做初始化工作,如初始化显示的类别
*
* @author 小代码
* @version 1.0
*
*/
@Controller
public class IndexController {

Logger log = LoggerFactory.getLogger("infoLog");

@Autowired
private UserStatusService userStatusService;

@RequestMapping(value = { "/" }, method = RequestMethod.HEAD, produces = "text/html")
public String head() {
return "index";
}

/**
*
* @param model
* @return
*/
@RequestMapping(value = { "/", "index" }, method = RequestMethod.GET, produces = "text/html")
public String index(Model model) {
log.info("打开首页");
model.addAttribute("msg", "hello 121项目");
List<UserStatus> statusList = userStatusService.findByStatusName("正常");
if( null != statusList && statusList.size() > 0 ){
model.addAttribute("userStatus", statusList.get(0));
}
return "index";
}

}


BookTypeController

  这个controller主要是为了测试json,稍后会总结一个spring mvc 与json相关的博客。

package com.laolang.gongda.bookshop.web;

import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.view.json.MappingJackson2JsonView;

import com.laolang.gongda.bookshop.pojo.ResultPojo;

@Controller
@RequestMapping("/booktypes")
public class BookTypeController {

Logger log = LoggerFactory.getLogger(BookTypeController.class);

@RequestMapping(value="list",method=RequestMethod.POST)
public ModelAndView bookTypeList( Model model ){
log.info("加载图书类别");
Map<String, Object> map = new HashMap<String, Object>();
ResultPojo result = new ResultPojo(ResultPojo.SUCCESS);
map.put("result", result);
return new ModelAndView(new MappingJackson2JsonView(),map);

}

}

测试相关

  现在只有数据库的测试,还没有controller的测试不过稍后会写配置出来。再有就是数据库的测试使用的是dbunit,我觉得这种方式不太好,稍后应该寻找更好的解决方案。

数据库测试基类

package com.laolang.gongda.bookshop.utils;

import static org.junit.Assert.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.sql.SQLException;

import javax.sql.DataSource;

import org.dbunit.DatabaseUnitException;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.database.QueryDataSet;
import org.dbunit.dataset.DataSetException;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSet;
import org.dbunit.dataset.xml.FlatXmlProducer;
import org.dbunit.operation.DatabaseOperation;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.util.ResourceUtils;
import org.xml.sax.InputSource;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-*.xml")
public class AbstractTestCase {

@Test
public void testToPass(){
assertEquals(1, 1);
}

@Autowired
protected DataSource dataSource;

protected IDatabaseConnection dbunitCon;

protected IDataSet ds;

protected File tempFile;

protected IDataSet createDateSet(String tname) throws DataSetException, FileNotFoundException {
File f = ResourceUtils.getFile("classpath:" + "dbunit_xml/" + tname + ".xml");
InputStream is = new FileInputStream(f);
assertNotNull("dbunit的基本数据文件不存在", is);
return new FlatXmlDataSet(new FlatXmlProducer(new InputSource(is)));
}

protected void backupAllTable() throws SQLException, IOException, DataSetException {
IDataSet ds = dbunitCon.createDataSet();
writeBackupFile(ds);
}

private void writeBackupFile(IDataSet ds) throws IOException, DataSetException {
tempFile = File.createTempFile("back", "xml");
FlatXmlDataSet.write(ds, new FileWriter(tempFile));
}

protected void backupCustomTable(String[] tname) throws DataSetException, IOException {
QueryDataSet ds = new QueryDataSet(dbunitCon);
for (String str : tname) {
ds.addTable(str);
}
writeBackupFile(ds);
}

protected void backupOneTable(String tname) throws DataSetException, IOException {
backupCustomTable(new String[] { tname });
}

protected void resumeTable() throws FileNotFoundException, DatabaseUnitException, SQLException {
IDataSet ds = new FlatXmlDataSet(new FlatXmlProducer(new InputSource(new FileInputStream(tempFile))));
DatabaseOperation.CLEAN_INSERT.execute(dbunitCon, ds);
}

}


一个数据库测试示例

package com.laolang.gongda.bookshop.service;

import static org.junit.Assert.*;

import java.io.FileNotFoundException;
import java.sql.SQLException;
import java.util.List;

import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.operation.DatabaseOperation;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.laolang.gongda.bookshop.domain.UserStatus;
import com.laolang.gongda.bookshop.utils.AbstractTestCase;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:spring-*.xml")
public class UserStatusServiceTest extends AbstractTestCase {

@Autowired
private UserStatusService userStatusService;

@Test
public void saveTest(){
UserStatus userStatus = new UserStatus("禁用", "禁用状态");
userStatusService.save(userStatus);
List<UserStatus> status = userStatusService.findByStatusName("正常");
assertNotNull("未添加数据", status);
assertEquals("添加用户状态数量量不正确", status.size(), 1);
}

@Test
public void findTest(){
UserStatus userStatus = userStatusService.find(1);
assertNotNull("未查询到用户状态", userStatus);
}

@Test
public void deleteTest(){
userStatusService.delete(1);
UserStatus userStatus = userStatusService.find(1);
assertNull("用户状态数据未删除", userStatus);
}

@Before
public void initDbunit() throws Exception {
String tableName = "user_status";
dbunitCon = new DatabaseConnection(DataSourceUtils.getConnection(dataSource));
backupOneTable(tableName);
ds = createDateSet(tableName);
DatabaseOperation.CLEAN_INSERT.execute(dbunitCon, ds);
}

@After
public void testResume() {
try {
resumeTable();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (DatabaseUnitException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}

try {
if (dbunitCon != null)
dbunitCon.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

总结

1 是时候系统的学习一下Maven与Gradle了

2 Eclipse与IDEA的选择是个问题。先安装一个idea写个小项目试试,如果用着还行的话,以后就用idea开发,不过对于我这种喜欢开源免费软件的人来说,用破解版的idea总感觉有点不太舒服。

3 是时候系统的学习Tomcat了
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息