springmvc和多数据源整合框架研究

未分类 发表评论

                这里是最近采用spring+springmvc搭的一个架构,持久层用到两个数据源分别是mysql和mongodb数据库,使用spring-data-jpa和mongoTemplate框架开发持久层,(在看文档前,本人认为读者是熟练jpa框架和mongodb数据库)。

                该项目采用maven管理,以下为项目文件结构:

                

                首先我们看看项目所需的jar包,由于maven中央仓库没有找到相关额外jar包,故需读者手动去下载如下jar包:cglib-nodep-2.2.jar、ehcache-core-2.5.2.jar、ehcache-spring-annotations-1.2.0、ehcache-terracotta-2.5.2.jar、terracotta-toolkit-1.5-runtime-4.2.0.jar和guava-13.0.1.jar

           
其他jar包坐标如下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.mongodb.test</groupId>
	<artifactId>springmvcmongodb</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>springmvcmongodb</name>
	<url>http://maven.apache.org</url>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<spring.version>3.1.3.RELEASE</spring.version>
		<spring.data.mongo.version>1.3.0.M1</spring.data.mongo.version>
		<slf4j.version>1.6.1</slf4j.version>
		<hibernate.version>3.5.6-Final</hibernate.version>
		<org.aspectj-version>1.6.10</org.aspectj-version>
	</properties>
	<repositories>
		<repository>
			<id>spring-maven-release</id>
			<name>Spring Maven Release Repository</name>
			<url>http://maven.springframework.org/release</url>
		</repository>
		<repository>
			<id>spring-maven-milestone</id>
			<name>Spring Maven Milestone Repository</name>
			<url>http://maven.springframework.org/milestone</url>
		</repository>
	</repositories>

	<dependencies>
		<!-- spring data jpa -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-jpa</artifactId>
			<version>1.3.0.RELEASE</version>
		</dependency>
		<!-- spring data mongodb -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-mongodb</artifactId>
			<version>${spring.data.mongo.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-commons</artifactId>
			<version>1.5.0.RELEASE</version>
		</dependency>
		<!-- jpa -->
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2.2</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate.javax.persistence</groupId>
			<artifactId>hibernate-jpa-2.0-api</artifactId>
			<version>1.0.0.Final</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-entitymanager</artifactId>
			<version>${hibernate.version}</version>
		</dependency>
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>3.5.6-Final</version>
		</dependency>
		<dependency>
			<groupId>commons-pool</groupId>
			<artifactId>commons-pool</artifactId>
			<version>1.5.6</version>
		</dependency>
		<dependency>
			<groupId>c3p0</groupId>
			<artifactId>c3p0</artifactId>
			<version>0.9.1.2</version>
		</dependency>
		<!-- jpa -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.8.1</version>
			<scope>test</scope>
		</dependency>
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>1.2.16</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-api</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>jcl-over-slf4j</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>org.slf4j</groupId>
			<artifactId>slf4j-log4j12</artifactId>
			<version>${slf4j.version}</version>
		</dependency>
		<dependency>
			<groupId>commons-fileupload</groupId>
			<artifactId>commons-fileupload</artifactId>
			<version>1.2.2</version>
		</dependency>
		<!-- Spring dependencies -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context-support</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-jdbc</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-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
			<scope>test</scope>
			<exclusions>
				<exclusion>
					<groupId>commons-logging</groupId>
					<artifactId>commons-logging</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-expression</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-asm</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>cglib</groupId>
			<artifactId>cglib</artifactId>
			<version>2.2</version>
		</dependency>
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-mongodb</artifactId>
			<version>${spring.data.mongo.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>
		<!-- @Inject -->
		<dependency>
			<groupId>javax.inject</groupId>
			<artifactId>javax.inject</artifactId>
			<version>1</version>
		</dependency>
		<!-- AspectJ -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjrt</artifactId>
			<version>${org.aspectj-version}</version>
		</dependency>
		<!-- json -->
		<dependency>
			<groupId>net.sf.json-lib</groupId>
			<artifactId>json-lib</artifactId>
			<version>2.4</version>
			<classifier>jdk15</classifier>
		</dependency>
		<!-- 读取属性文件 -->
		<dependency>
			<groupId>commons-configuration</groupId>
			<artifactId>commons-configuration</artifactId>
			<version>1.9</version>
		</dependency>
		<!-- mysql -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.26</version>
		</dependency>
	</dependencies>
	<build>
		<finalName>springmvcmongodb</finalName>
	</build>
</project>

             资源都配置好后,接下来就看看相关配置文件如何整合

             第一步配置springmvc配置文件spring-mvc.xml:            

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context" xsi:schemaLocation="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/mvc 
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">

	<!-- 自动扫描controller包下的所有类,使其认为spring mvc的控制器 -->
	<context:component-scan base-package="com.test.controller" />

    <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->  
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" lazy-init="false" />  
  
    <!-- 另外最好还要加入DefaultAnnotationHandlerMapping,不然会被 XML或其它的映射覆盖! -->  
    <bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />  

	<!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 -->
	<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"
	 p:prefix="WEB-INF/jsp/" 
	 p:suffix=".jsp" />

	<!-- 支持上传文件 -->  
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <description>文件上传大小限制</description>
    <property name="maxUploadSize" value="1024000000"></property>
    </bean>  
</beans>

            第二步配置数据源文件(mysql数据源中配置spring与spring-data-jpa整合文件,mongodb数据源中配置spring与mongodb整合文件)
            1. spring与spring-data-jpa整合配置文件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:context="http://www.springframework.org/schema/context"
	xmlns:tx="http://www.springframework.org/schema/tx" xmlns:jpa="http://www.springframework.org/schema/data/jpa"
	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.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.5.xsd http://www.springframework.org/schema/data/jpa http://www.springframework.org/schema/data/jpa/spring-jpa-1.0.xsd">
 	<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
		<property name="driverClass" value="${app.jdbc.driverClassName}" />
		<property name="jdbcUrl" value="${app.jdbc.url}" />
		<property name="user" value="${app.jdbc.username}" />
		<property name="password" value="${app.jdbc.password}" />
		<property name="initialPoolSize" value="${app.jdbc.initialPoolSize}" />
		<property name="minPoolSize" value="${app.jdbc.minPoolSize}" />
		<property name="maxPoolSize" value="${app.jdbc.maxPoolSize}" />
		<property name="maxIdleTime" value="${app.jdbc.maxIdleTime}" />
		<property name="acquireIncrement" value="${app.jdbc.acquireIncrement}" />
		<property name="idleConnectionTestPeriod" value="${app.jdbc.idleConnectionTestPeriod}" />
		<property name="testConnectionOnCheckout" value="${app.jdbc.testConnectionOnCheckout}" />
		<property name="testConnectionOnCheckin" value="${app.jdbc.testConnectionOnCheckin}" />
		<property name="checkoutTimeout" value="${app.jdbc.checkoutTimeout}" />
	</bean>
	<bean id="entityManagerFactory2"
		class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
		<property name="dataSource" ref="dataSource" />
        <!--<property name="packagesToScan" value="cn.damai.terminal.core.domain" />-->
		<property name="persistenceUnitName" value="app_service" />
		<property name="persistenceXmlLocation" value="classpath*:META-INF/persistence.xml" />
		<property name="jpaVendorAdapter">
			<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		 		<property name="generateDdl" value="true" />
 				<property name="showSql" value="true" />
			</bean>
		</property>
     </bean>

	<bean id="apptransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
		<property name="entityManagerFactory" ref="entityManagerFactory2" />
	</bean>
    <tx:annotation-driven transaction-manager="apptransactionManager" />

	<jpa:repositories base-package="com.test.jpa.dao"
		query-lookup-strategy="create-if-not-found" repository-impl-postfix="CustomImpl"
		entity-manager-factory-ref="entityManagerFactory2" transaction-manager-ref="apptransactionManager">
	</jpa:repositories>
</beans>

               2. spring与mongodb整合配置文件spring-mongodb.xml如下:

<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:mongo="http://www.springframework.org/schema/data/mongo"
    xsi:schemaLocation="http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-3.0.xsd
          http://www.springframework.org/schema/data/mongo
          http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
  
     <mongo:db-factory id="mongoDbFactory"  
                  host="localhost"  
                  port="27017"  
                  dbname="test"  
                  username=""  
                  password=""/>    
     <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">    
    <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>    
    </bean>  
</beans>

注意:这里面配置是我本地测试mongodb服务器地址,读者项目需修改host、port和dbname信息。

            第三步配置ehcache缓存配置文件ehcache.xml如下:

<?xml version="1.0" encoding="UTF-8"?>
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:noNamespaceSchemaLocation="http://ehcache.org/ehcache.xsd">
    <!-- Cache configuration.
    The following attributes are required.
    name:
    Sets the name of the cache. This is used to identify the cache. It must be unique.
    maxElementsInMemory:
    Sets the maximum number of objects that will be created in memory (0 == no limit)
    maxElementsOnDisk:
    Sets the maximum number of objects that will be maintained in the DiskStore
    The default value is zero, meaning unlimited.
    eternal:
    Sets whether elements are eternal. If eternal,  timeouts are ignored and the
    element is never expired.
    overflowToDisk:
    Sets whether elements can overflow to disk when the in-memory cache
    has reached the maxInMemory limit.
    The following attributes are optional.
    timeToIdleSeconds:
    Sets the time to idle for an element before it expires.
    i.e. The maximum amount of time between accesses before an element expires
    Is only used if the element is not eternal.
    Optional attribute. A value of 0 means that an Element can idle for infinity.
    The default value is 0.
    timeToLiveSeconds:
    Sets the time to live for an element before it expires.
    i.e. The maximum time between creation time and when an element expires.
    Is only used if the element is not eternal.
    Optional attribute. A value of 0 means that and Element can live for infinity.
    The default value is 0.
    diskPersistent:
    Whether the disk store persists between restarts of the Virtual Machine.
    The default value is false.
    diskExpiryThreadIntervalSeconds:
    The number of seconds between runs of the disk expiry thread. The default value
    is 120 seconds.
    diskSpoolBufferSizeMB:
    This is the size to allocate the DiskStore for a spool buffer. Writes are made
    to this area and then asynchronously written to disk. The default size is 30MB.
    Each spool buffer is used only by its cache. If you get OutOfMemory errors consider
    lowering this value. To improve DiskStore performance consider increasing it. Trace level
    logging in the DiskStore will show if put back ups are occurring.
    memoryStoreEvictionPolicy:
    Policy would be enforced upon reaching the maxElementsInMemory limit. Default
    policy is Least Recently Used (specified as LRU). Other policies available -
    First In First Out (specified as FIFO) and Less Frequently Used
    (specified as LFU)
    Cache elements can also contain sub elements which take the same format of a factory class
    and properties. Defined sub-elements are:
    * cacheEventListenerFactory - Enables registration of listeners for cache events, such as
      put, remove, update, and expire.
    * bootstrapCacheLoaderFactory - Specifies a BootstrapCacheLoader, which is called by a
      cache on initialisation to prepopulate itself.
    Each cache that will be distributed needs to set a cache event listener which replicates
    messages to the other CacheManager peers. For the built-in RMI implementation this is done
    by adding a cacheEventListenerFactory element of type RMICacheReplicatorFactory to each
    distributed cache's configuration as per the following example:
    <cacheEventListenerFactory class="net.sf.ehcache.distribution.RMICacheReplicatorFactory"
         properties="replicateAsynchronously=true,
         replicatePuts=true,
         replicateUpdates=true,
         replicateUpdatesViaCopy=true,
         replicateRemovals=true "/>
    The RMICacheReplicatorFactory recognises the following properties:
    * replicatePuts=true|false - whether new elements placed in a cache are
      replicated to others. Defaults to true.
    * replicateUpdates=true|false - whether new elements which override an
      element already existing with the same key are replicated. Defaults to true.
    * replicateRemovals=true - whether element removals are replicated. Defaults to true.
    * replicateAsynchronously=true | false - whether replications are
      asynchronous (true) or synchronous (false). Defaults to true.
    * replicateUpdatesViaCopy=true | false - whether the new elements are
      copied to other caches (true), or whether a remove message is sent. Defaults to true.
    * asynchronousReplicationIntervalMillis=<number of milliseconds> - The asynchronous
      replicator runs at a set interval of milliseconds. The default is 1000. The minimum
      is 10. This property is only applicable if replicateAsynchronously=true
    * asynchronousReplicationMaximumBatchSize=<number of operations> - The maximum
      number of operations that will be batch within a single RMI message.  The default
      is 1000. This property is only applicable if replicateAsynchronously=true
    The RMIBootstrapCacheLoader bootstraps caches in clusters where RMICacheReplicators are
    used. It is configured as per the following example:

    <bootstrapCacheLoaderFactory
        class="net.sf.ehcache.distribution.RMIBootstrapCacheLoaderFactory"
        properties="bootstrapAsynchronously=true, maximumChunkSizeBytes=5000000"/>

    The RMIBootstrapCacheLoaderFactory recognises the following optional properties:

    * bootstrapAsynchronously=true|false - whether the bootstrap happens in the background
      after the cache has started. If false, bootstrapping must complete before the cache is
      made available. The default value is true.
    * maximumChunkSizeBytes=<integer> - Caches can potentially be very large, larger than the
      memory limits of the VM. This property allows the bootstraper to fetched elements in
      chunks. The default chunk size is 5000000 (5MB).
    -->
    <diskStore path="java.io.tmpdir"/>
    <!--
    Mandatory Default Cache configuration. These settings will be applied to caches
    created programmtically using CacheManager.add(String cacheName)
    -->
    <defaultCache
            maxElementsInMemory="10000"
            eternal="false"
            timeToIdleSeconds="120"
            timeToLiveSeconds="120"
            maxElementsOnDisk="10000000"
            diskExpiryThreadIntervalSeconds="120"
            memoryStoreEvictionPolicy="LRU">
        <!-- <persistence strategy="localTempSwap"/> -->
    </defaultCache>
    
    <!-- 给Admin类设置缓存 -->
    <cache name="com.test.domain.Admin"
            maxElementsInMemory="1000"
            maxElementsOnDisk="1000"
            overflowToDisk="true"
            eternal="true">            
    </cache>    
</ehcache>

注意:这里是配置需要缓存的实体类对应的缓存,也可采用默认缓存,笔者建议读者在网上搜索ehcache的配置文件,自己配置ehcache.xml文件,有可能配置不当导致系统性能降低。

             第四步将上述配置xml文件整合至一个xml文件中方便读取(可根据个人喜好配置),spring.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:context="http://www.springframework.org/schema/context" xsi:schemaLocation="
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
">
<!-- 引入属性文件 -->
	<context:property-placeholder location="classpath:config.properties" />
	<!-- 自动扫描(自动注入) -->
	<context:component-scan base-package="com.test.dao" />
    <import resource="spring_mongodb.xml"/>
    <import resource="applicationContext.xml"/>
</beans>

           spring的相关文件都配置好了后,最后问题就是要启动它,加载它。

           第五步配置web.xml文件如下:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" 
	xmlns="http://java.sun.com/xml/ns/javaee" 
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee 
	http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
  <display-name></display-name>
  <context-param>
  	<param-name>contextConfigLocation</param-name>
  	<param-value>classpath:spring.xml;</param-value>
  </context-param>
  
  <filter>
    <description>字符集过滤器</description>
    <filter-name>encodingFilter</filter-name>
    <filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
    <init-param>
      <description>字符集编码</description>
      <param-name>encoding</param-name>
      <param-value>UTF-8</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>encodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  <filter>
       <filter-name>OpenEntityManagerInViewFilter</filter-name>
       <filter-class>org.springframework.orm.jpa.support.OpenEntityManagerInViewFilter</filter-class>
   </filter>
   <filter-mapping>
       <filter-name>OpenEntityManagerInViewFilter</filter-name>
       <url-pattern>*.do</url-pattern>
   </filter-mapping>
  <listener>
    <description>spring监听器</description>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
  </listener>
  <servlet>
    <description>spring mvc servlet</description>
    <servlet-name>springMvc</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <description>spring mvc 配置文件</description>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring-mvc.xml</param-value>            //注意springmvc的配置文件在web.xml下添加,不在spring.xml中加载
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springMvc</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>
  <description>会话超时时间间隔(单位:分钟)</description>
  <session-config>
    <session-timeout>30</session-timeout>
  </session-config>
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
      第六步建mysql表结构如下:
<pre name="code" class="sql">   <pre name="code" class="sql">CREATE TABLE `app_tentinet_system_admin` (  
  `admin_id` int(11) NOT NULL AUTO_INCREMENT,  
  `admin_name` varchar(64) NOT NULL,  
  `admin_password` varchar(32) NOT NULL,  
  `admin_email` varchar(64) NOT NULL,  
  `admin_phone` varchar(11) NOT NULL,  
  `create_date` varchar(50) NOT NULL,  
  `admin_range` int(11) NOT NULL DEFAULT '0',  
  `is_del` int(11) NOT NULL DEFAULT '0',  
  PRIMARY KEY (`admin_id`)  
) ENGINE=MyISAM AUTO_INCREMENT=10 DEFAULT CHARSET=utf8;  
     第七步配置映射实体类如下:
     1. jpa实体类映射如下:
      <pre name="code" class="java">package com.test.domain;
import java.io.Serializable;
import javax.persistence.Cacheable;
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 org.hibernate.annotations.Cache;
import org.hibernate.annotations.CacheConcurrencyStrategy;
@Cache(usage=CacheConcurrencyStrategy.READ_ONLY)
@Cacheable(true)
@Entity
@Table(name="app_tentinet_system_admin")
public class Admin implements Serializable{
	private static final long serialVersionUID = 1L;	
	/* 管理员ID */
	private int adminId;
	/* 管理员姓名 */
	private String adminName;
	/* 管理员密码 */
	private String adminPassword;
	/* 管理员e-mail */
	private String adminEmail;
	/* 管理员电话 */
	private String adminPhone;
	/* 创建日期 */
	private String createDate;
	/* 管理员等级 */
	private int adminRange;
	/* 删除标记 */
	private int isDel;
	
	public Admin() {
		super();
		// TODO Auto-generated constructor stub
	}
	
	public Admin(int adminId, String adminName, String adminPassword,
			String adminEmail, String adminPhone, String createDate,
			int adminRange, int isDel) {
		super();
		this.adminId = adminId;
		this.adminName = adminName;
		this.adminPassword = adminPassword;
		this.adminEmail = adminEmail;
		this.adminPhone = adminPhone;
		this.createDate = createDate;
		this.adminRange = adminRange;
		this.isDel = isDel;
	}

	@Id
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	@Column(name="admin_id",unique=true)
	public int getAdminId() {
		return adminId;
	}
	public void setAdminId(int adminId) {
		this.adminId = adminId;
	}
	
	@Column(name="admin_name")
	public String getAdminName() {
		return adminName;
	}
	public void setAdminName(String adminName) {
		this.adminName = adminName;
	}
	
	@Column(name="admin_password")
	public String getAdminPassword() {
		return adminPassword;
	}
	public void setAdminPassword(String adminPassword) {
		this.adminPassword = adminPassword;
	}
	
	@Column(name="admin_email")
	public String getAdminEmail() {
		return adminEmail;
	}
	public void setAdminEmail(String adminEmail) {
		this.adminEmail = adminEmail;
	}
	
	@Column(name="admin_phone")
	public String getAdminPhone() {
		return adminPhone;
	}
	public void setAdminPhone(String adminPhone) {
		this.adminPhone = adminPhone;
	}
	
	@Column(name="create_date")
	public String getCreateDate() {
		return createDate;
	}
	public void setCreateDate(String createDate) {
		this.createDate = createDate;
	}
	
	@Column(name="admin_range")
	public int getAdminRange() {
		return adminRange;
	}
	public void setAdminRange(int adminRange) {
		this.adminRange = adminRange;
	}
	
	@Column(name="is_del")
	public int getIsDel() {
		return isDel;
	}
	public void setIsDel(int isDel) {
		this.isDel = isDel;
	}
	@Override
	public String toString() {
		return "Admin [adminId=" + adminId + ", adminName=" + adminName
				+ ", adminPassword=" + adminPassword + ", adminEmail="
				+ adminEmail + ", adminPhone=" + adminPhone + ", createDate="
				+ createDate + ", adminRange=" + adminRange + "]";
	}
}

     <span style="color:#ff0000;"> 2. mongodb实体类映射如下:</span>
<pre name="code" class="java">package com.test.domain;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection="userinfo")
public class UserInfo {
	@Id
	private String id;
	private String name;
	private int age;
	private String birthday;
	
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getBirthday() {
		return birthday;
	}
	public void setBirthday(String birthday) {
		this.birthday = birthday;
	}
	public String getId() {
		return id;
	}
	public void setId(String id) {
		this.id = id;
	}
	@Override
	public String toString() {
		return "UserInfo [id=" + id + ", name=" + name + ", age=" + age
				+ ", birthday=" + birthday + "]";
	}	
}

           到现在,准备工作都已经做好了,接下来看看接口源码

          jpa的Dao层UserInfoJpaDao接口如下:

package com.test.jpa.dao;
import java.io.Serializable;
import java.util.List;
import javax.persistence.QueryHint;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.QueryHints;
import org.springframework.data.repository.query.Param;
import org.springframework.transaction.annotation.Transactional;
import com.test.domain.Admin;

public interface UserInfoJpaDao extends JpaRepository<Admin,Serializable>{
	
	@Query("from Admin")
	@QueryHints({@QueryHint(name="org.hibernate.cacheable",value="true")})
	public List<Admin> findAdmins();
	
	@Transactional(value="apptransactionManager")
	@Modifying
	@Query("update Admin set adminName =:an where adminId =:id")
	public void updateAdmin(@Param("an") String adminName,@Param("id") int adminId);
}

注意:在使用二级缓存时需在方法上加上QueryHints申明使用二级缓存其中queryHint的name=‘org.hibernate.cacheable’ , value=’true’ 其中value=true意思是开启二级缓存。

           mongodb与spring整合有两种方式可实现:其一、SpringData方式,采用mongoTemplate接口实现;其二、MongoRepository方式,这种方式很像spring-data-jpa
,但是对于个人而言,在使用的时候这种方式不是很灵活,个人建议使用mongoTemplate编程。

           mongodb中Dao层UserDao接口如下:

package com.test.dao;
import java.util.List;
import com.test.domain.UserInfo;
public interface UserDao {
	public List<UserInfo> findUser();
}

            其实现层UserDaoImpl接口如下:

package com.test.dao.impl;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.stereotype.Repository;
import com.test.dao.UserDao;
import com.test.domain.UserInfo;

@Repository
public class UserDaoImpl implements UserDao {
	@Resource
	private MongoTemplate mongoTemplate;	
	public List<UserInfo> findUser() {		
		return mongoTemplate.findAll(UserInfo.class);
	}

	public MongoTemplate getMongoTemplate() {
		return mongoTemplate;
	}

	public void setMongoTemplate(MongoTemplate mongoTemplate) {
		this.mongoTemplate = mongoTemplate;
	}

}

           接下来写个测试类看看接口数据:

package test;
import java.util.List;
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 com.test.dao.UserDao;
import com.test.domain.Admin;
import com.test.domain.UserInfo;
import com.test.jpa.dao.UserInfoJpaDao;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations={"classpath:spring.xml"})
public class UserInfoTest {
	@Autowired
	private UserDao userDao;	
	@Autowired
	private UserInfoJpaDao userInfoJpaDao;
	
	@Test
	public void testUser(){
		List<UserInfo> list = userDao.findUser();
		for (UserInfo userInfo : list) {
			System.out.println(userInfo);
		}
		System.out.println(123);
	}
	
	@Test
	public void testUsers(){
		List<Admin> list = userInfoJpaDao.findAdmins();
		for (Admin admin : list) {
			System.out.println(admin.getAdminName()+":"+admin.getAdminId());
		}
		userInfoJpaDao.updateAdmin("test4", 8);
		list = userInfoJpaDao.findAdmins();
		for (Admin admin : list) {
			System.out.println(admin.getAdminName());
		}
	}
	
	@Test
	public void testUpdateAdmin(){
		userInfoJpaDao.updateAdmin("test2", 8);
	}
}

            笔者已亲自调试,数据可获得,到这里,持久层和业务处均已ok,现在来看看控制层,代码如下:

package com.test.controller;
import java.util.List;
import javax.annotation.Resource;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.test.dao.UserDao;
import com.test.domain.Admin;
import com.test.domain.UserInfo;
import com.test.jpa.dao.UserInfoJpaDao;

@Controller
public class UserTest {
	@Resource
	private UserDao userDao;	
	@Resource
	private UserInfoJpaDao userInfoJpaDao;
	
	@RequestMapping(value="a",method=RequestMethod.GET)
	public String skipIndex(){
		List<UserInfo> list = userDao.findUser();
		for (UserInfo userInfo : list) {
			System.out.println(userInfo);
		}
		
		List<Admin> list2 = userInfoJpaDao.findAll();
		for (Admin admin : list2) {
			System.out.println(admin.getAdminName());
		}		
		return "index";
	}	
}

   注意:访问路径http://localhost:8080/springmvcmongodb/a.do

              到此框架已完整搭建完毕,希望本篇文章能让你学到东西,另外如有不明白地方可私下邮件笔者一同研究大笑










发表评论

电子邮件地址不会被公开。 必填项已用*标注

昵称 *