基于RestEasy开发环境搭建

RESTEasy是JBoss的开源项目之一,是一个RESTful Web Services框架,RESTEasy的开发者Bill Burke同时也是JAX-RS的J2EE标准制定者之一。JAX-RS是一个JCP制订的新标准,用于规范基于HTTP的RESTful Web Services的API。

RESTEasy相对SOAP来说,REST比SOAP更具优势,架构比SOA更简单轻便。下面基于RestEasy+SpringMVC+Myibates搭建作简单的介绍:

一、新建个Maven-Web项目,在POM文件中,作如下Maven依赖:

<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.sumcope.cdh.api</groupId>
  <artifactId>CDHAPI</artifactId>
  <packaging>war</packaging>
  <version>1.0-SNAPSHOT</version>
  <name>CDHAPI Maven Webapp</name>
  <properties>
  	<spring.version>4.2.0.RELEASE</spring.version>
  	<json.version>1.9.13</json.version>
  	<resteasy.version>3.0.11.Final</resteasy.version>
  	<aspectj.version>1.8.6</aspectj.version>
  	<slf4j.version>1.7.12</slf4j.version>
  	<log4j.version>1.2.17</log4j.version>
  	<mybatis.version>3.3.0</mybatis.version>
  </properties>
 
	<repositories>
		<repository>
			<id>JBoss repository</id>
			 <url>http://repository.jboss.org/maven2</url>
		</repository>
	</repositories>
  
  <dependencies>
  	<!-- Spring依赖 -->
    <dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-core</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-beans</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-context</artifactId>
	    <version>${spring.version}</version>
	    <exclusions>  
            <!-- Exclude Commons Logging in favor of SLF4j -->  
            <exclusion>  
                <groupId>commons-logging</groupId>  
                <artifactId>commons-logging</artifactId>  
             </exclusion>  
        </exclusions>  
	</dependency>
	<dependency>
	    <groupId>org.springframework</groupId>
	    <artifactId>spring-context-support</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-oxm</artifactId>
	    <version>${spring.version}</version>
	</dependency>
	<dependency>  
        <groupId>org.springframework</groupId>  
        <artifactId>spring-jdbc</artifactId>  
        <version>${spring.version}</version>  
    </dependency>
	<!-- JSON依赖 -->
	<dependency>
	    <groupId>org.codehaus.jackson</groupId>
	    <artifactId>jackson-mapper-asl</artifactId>
	    <version>${json.version}</version>
	</dependency>
	<dependency>
	    <groupId>org.codehaus.jackson</groupId>
	    <artifactId>jackson-jaxrs</artifactId>
	    <version>${json.version}</version>
	</dependency>
	<!-- logger -->
	<dependency>
	    <groupId>org.slf4j</groupId>
	    <artifactId>slf4j-log4j12</artifactId>
	    <version>${slf4j.version}</version>
	</dependency>
	<dependency>
      <groupId>org.slf4j</groupId>
      <artifactId>slf4j-api</artifactId>
      <version>${slf4j.version}</version>
	</dependency>
	<dependency>  
       <groupId>log4j</groupId>  
       <artifactId>log4j</artifactId>  
       <version>${log4j.version}</version>  
       <exclusions>  
           <exclusion>  
               <groupId>javax.mail</groupId>  
               <artifactId>mail</artifactId>  
           </exclusion>  
           <exclusion>  
               <groupId>javax.jms</groupId>  
               <artifactId>jms</artifactId>  
           </exclusion>  
           <exclusion>  
               <groupId>com.sun.jdmk</groupId>  
               <artifactId>jmxtools</artifactId>  
           </exclusion>  
           <exclusion>  
               <groupId>com.sun.jmx</groupId>  
               <artifactId>jmxri</artifactId>  
           </exclusion>  
       </exclusions>  
       <scope>runtime</scope>  
   </dependency>  
	<!-- Servlet -->
	<dependency>
	    <groupId>javax.servlet</groupId>
	    <artifactId>servlet-api</artifactId>
	    <version>3.0-alpha-1</version>
	    <scope>provided</scope>
	</dependency>
	<!-- resteasy -->
	<dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-spring</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-client</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
    <dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-jaxb-provider</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
     <dependency>
		<groupId>org.jboss.resteasy</groupId>
		<artifactId>resteasy-jackson2-provider</artifactId>
		<version>${resteasy.version}</version>
	</dependency>
	<dependency>
        <groupId>org.jboss.resteasy</groupId>
        <artifactId>resteasy-servlet-initializer</artifactId>
        <version>${resteasy.version}</version>
    </dependency>
    <dependency>
		<groupId>org.jboss.resteasy</groupId>
		<artifactId>resteasy-jaxrs</artifactId>
		<version>${resteasy.version}</version>
		<exclusions>
			<exclusion>
				<groupId>org.slf4j</groupId>
				<artifactId>slf4j-simple</artifactId>
			</exclusion>
			<exclusion>
				<groupId>javassist</groupId>
				<artifactId>javassist</artifactId>
			</exclusion>
		</exclusions>
	</dependency>
    <!-- JUnit -->
     <dependency>
        <groupId>junit</groupId>
        <artifactId>junit</artifactId>
        <version>4.4</version>
        <scope>test</scope>
      </dependency>
      
      <dependency>
	    <groupId>cglib</groupId>
	    <artifactId>cglib</artifactId>
	    <version>2.2.2</version>
	 </dependency>
	 
	<dependency>
	    <groupId>mysql</groupId>
	    <artifactId>mysql-connector-java</artifactId>
	    <version>5.1.36</version>
	</dependency>
	 <!-- start spring 集成Ibatis -->  
	<dependency>  
        <groupId>org.mybatis</groupId>  
        <artifactId>mybatis</artifactId>  
        <version>${mybatis.version}</version>  
    </dependency>  
    <dependency>  
        <groupId>org.mybatis</groupId>  
        <artifactId>mybatis-spring</artifactId>  
        <version>1.2.3</version>  
    </dependency>  
	<!-- AspectJ -->  
     <dependency>  
            <groupId>org.aspectj</groupId>  
            <artifactId>aspectjrt</artifactId>  
            <version>${aspectj.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>org.aspectj</groupId>  
            <artifactId>aspectjweaver</artifactId>  
            <version>${aspectj.version}</version>  
        </dependency>  
        <dependency>  
            <groupId>commons-dbcp</groupId>  
            <artifactId>commons-dbcp</artifactId>  
            <version>1.4</version>  
        </dependency>
        <!-- @Inject -->  
        <dependency>  
            <groupId>javax.inject</groupId>  
            <artifactId>javax.inject</artifactId>  
            <version>1</version>  
        </dependency>           
        <!-- end spring 集成Ibatis -->  
        <!-- start web工程依赖包 -->  
        <dependency>  
            <groupId>javax.servlet</groupId>  
            <artifactId>servlet-api</artifactId>  
            <version>2.5</version>  
            <scope>provided</scope>  
        </dependency>  
        <dependency>  
            <groupId>javax.servlet.jsp</groupId>  
            <artifactId>jsp-api</artifactId>  
            <version>2.1</version>  
            <scope>provided</scope>  
        </dependency>  
        <!-- end web工程依赖包 -->    
  </dependencies>
  
  <profiles>
  	<!-- 本地环境 -->
  	<profile>
  		<id>local</id>
  		<properties>
  		</properties>
  	</profile>
  	<!-- 开发环境 -->
  	<profile>
  		<id>dev</id>
  		<properties>
  		</properties>
  		<!-- 默认激活本环境 -->
  		<activation>
  			<activeByDefault>true</activeByDefault>
  		</activation>
  	</profile>
  	 <!-- 测试环境 -->
  	<profile>
  		<id>test</id>
  		<properties>
  		</properties>
  	</profile>
  	 <!-- 预发布环境 -->
  	<profile>
  		<id>pre</id>
  		<properties>
  		</properties>
  	</profile>
  	 <!-- 生产环境 -->
  	<profile>
  		<id>prod</id>
  		<properties>
  		</properties>
  	</profile>
  </profiles>
  <build>
    <finalName>CDHAPI</finalName>
    <resources>
    	<resource>
    		<directory>src/main/resources</directory>
    		<filtering>true</filtering>
    	</resource>
    </resources>
    <plugins>
    	<plugin>
    		<groupId>org.apache.maven.plugins</groupId>
    		<artifactId>maven-compiler-plugin</artifactId>
    		<configuration>
    			 <source>1.8</source>
    			 <target>1.8</target>
    			 <encoding>utf-8</encoding>
    		</configuration>
    	</plugin>
    </plugins>
  </build>
  
  <organization>
  	<name>roskin</name>
  	<url>www.sumscope.com</url>
  </organization>
</project>

、配置日志文件及Web.xml文件:

log4j.debug=true   
log4j.rootLogger=INFO,D,E,stdout

log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File = ../logs/logs.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = DEBUG
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n
#log4j.appender.E.layout.

log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ../logs/error.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = ERROR
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss}  [ %t:%r ] - [ %p ]  %m%n

log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy/MM/dd HH:mm:ss} [%c{1}] - %m%n
配置src/main/webapp/WEB-INF/web.xml下的web.xml文件

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0"
	xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	metadata-complete="true"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee/ http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
	<display-name>CDH API</display-name>
	
	<!-- 应用程序描述说明性文字 -->  
  	<description>Spring,SpringMvc,myBatis,cdh</description> 
  	<!-- Spring和mybatis的配置文件 -->   
	<context-param>  
        <param-name>contextConfigLocation</param-name>  
        <param-value>classpath:springmvc-mybatis.xml</param-value>  
    </context-param>  
	<listener>  
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
       <context-param>
	        <param-name>contextConfigLocation</param-name> 
	        <param-value>/WEB-INF/springmvc-servlet.xml</param-value> 
	    </context-param>
    </listener> 
     <!-- 防止Spring内存溢出监听器 -->  
    <listener>  
        <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>  
    </listener>  
    
	<servlet>  
      <servlet-name>springmvc</servlet-name>  
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <init-param>
      	<param-name>contextConfigLocation</param-name>
      	<param-value>classpath:springmvc-servlet.xml</param-value>
      </init-param>
      <load-on-startup>1</load-on-startup>
      <async-supported>true</async-supported>    
   </servlet>  
 
   <servlet-mapping>  
      <servlet-name>springmvc</servlet-name>  
      <url-pattern>/</url-pattern>  	<!-- 过滤所有路径(spring 3.0 REST 风格支持) -->  
   </servlet-mapping>  
   
   <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>
  	<init-param>  
      <param-name>forceEncoding</param-name>  
      <param-value>true</param-value>  
  	</init-param>  
  </filter>
  <filter-mapping>
  	<filter-name>CharacterEncodingFilter</filter-name>
  	<url-pattern>/*</url-pattern>
  </filter-mapping>
  
   <filter>  
        <filter-name>HiddenHttpMethodFilter</filter-name>  
        <filter-class>org.springframework.web.filter.HiddenHttpMethodFilter</filter-class>  
    </filter>  
    <filter-mapping>  
        <filter-name>HiddenHttpMethodFilter</filter-name>  
        <servlet-name>Spring MVC Dispatcher Servlet</servlet-name>  
    </filter-mapping>  
</web-app>

三、新建Springmvc-resteasy.xml文件,配置resteasy所注入Spring中的管理

<?xml version="1.0" encoding="UTF-8"?>
<!-- 
 @author <a href="mailto:[email protected]">Solomn Duskis</a>
 @version $Revision: 1 $
 -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:p="http://www.springframework.org/schema/p"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">

    <description>
        Import this file in a Spring MVC dispatcher XML
        environment to get the default implementation of the Spring
        MVC/RestEasy integration. You can also use this as a template for more
        advanced functionality, such as configuring multiple RestEasy
        factories/dispatchers/registries for different scenarios.
    </description>

    <!-- ========== Resteasy setup ================ -->

    <bean id="resteasy.deployment" class="org.jboss.resteasy.spi.ResteasyDeployment" init-method="start" destroy-method="stop">
        <description>
            This bean manages configuring your resteasy runtime.
        </description>
    </bean>

    <bean id="resteasy.registry" factory-bean="resteasy.deployment"
          factory-method="getRegistry">
        <description>
            Expose the dispatcher's registry as a full-blown Spring
            bean, so that it can be passed in as a reference.
        </description>
    </bean>

    <bean id="resteasy.dispatcher" factory-bean="resteasy.deployment"
          factory-method="getDispatcher">
        <description>
            Expose the dispatcher's registry as a full-blown Spring
            bean, so that it can be passed in as a reference.
        </description>
    </bean>

    <bean id="resteasy.providerFactory" factory-bean="resteasy.deployment"
          factory-method="getProviderFactory">
        <description>
            This bean manages all of the JAX-RS @Providers.
            @Providers convert from the inputStream to a java object and from a
            Java object to an output stream. The SpringBeanPreprocessor scans
            through the context for all @Provider, and adds them to this
            instance.
        </description>
    </bean>




    <bean id="resteasy.spring.bean.processor" class="org.jboss.resteasy.plugins.spring.SpringBeanProcessor"
          depends-on="resteasy.deployment">
        <description>
            Add Resources and @Providers to the appropriate places
            in Resteasy's infrastructure
        </description>
        <constructor-arg ref="resteasy.deployment"/>
    </bean>

    <!-- ========== Resteasy Spring MVC setup ================ -->

    <bean abstract="true" class="org.jboss.resteasy.springmvc.ResteasyHandlerMapping"
          id="abstract.resteasy.handlerMapping" depends-on="resteasy.deployment">
        <description>
            Tap into the RestEasy registry to find out if any of it's
            Resources handle a specific URL.

            This abstract bean has default settings. You can optimize settings for
            this handler mappings by overriding the "resteasy.handlerMapping" bean
            and customizing the following:

            1) setting a list of interceptors into the "interceptors" property.
            This is useful when you want to do things like use the OpenSessionInViewInterceptor

            2) set order and/or throwNotFound=true which will return the HTTP status
            codes that core RESTEasy recommends back to the client. It works in conjunction
            with the "resteasy.exception.handler"

        </description>
        <constructor-arg ref="resteasy.deployment"/>
        <property name="interceptors">
            <description>
                Look for a list/array bean named "resteasy.dispatcher.interceptors"
                which is composed of HandlerInterceptors to apply to this handler adapter.
            </description>
            <bean class="org.jboss.resteasy.plugins.spring.OptionalValueBeanFactory"
                  p:beanName="resteasy.dispatcher.interceptors"/>
        </property>
    </bean>

    <bean id="resteasy.handlerMapping" parent="abstract.resteasy.handlerMapping"/>

    <bean id="resteasy.handlerAdapter" class="org.jboss.resteasy.springmvc.ResteasyHandlerAdapter" depends-on="resteasy.deployment">
        <description>
            This HandlerAdapter knows how to forward requests to
            Resteasy for the handling of the service functionality, but not the
            rendering, which is handled by a ResteasyView.
        </description>

        <constructor-arg ref="resteasy.deployment"/>
    </bean>

    <bean id="resteasy.exception.handler"
          class="org.springframework.web.servlet.handler.SimpleMappingExceptionResolver"
          p:exceptionMappings="org.jboss.resteasy.spi.NoResourceFoundFailure=resteasy.no.resource.found.view"
          p:exceptionAttribute="exception">
        <description>
            This will be invoked if an end user overrides resteasy.handlerMapping with throwNotFound=true
        </description>
    </bean>

    <bean id="resteasy.no.resource.found.view"
          class="org.jboss.resteasy.springmvc.ResteasyNoResourceFoundView"
          p:deployment-ref="resteasy.deployment"/>

    <bean id="reateasy.error.view.resolver"
          class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
    
</beans>

四、新建Springmvc-servlet.xml文件,定义跳转的文件的前后缀 ,视图模式配置和Spring注解注入层:

<?xml version="1.0" encoding="GBK"?>  
<beans xmlns="http://www.springframework.org/schema/beans"   
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
xmlns:aop="http://www.springframework.org/schema/aop"   
xmlns:mvc="http://www.springframework.org/schema/mvc"   
xmlns:tx="http://www.springframework.org/schema/tx"   
xmlns:util="http://www.springframework.org/schema/util"   
xmlns:context="http://www.springframework.org/schema/context"   
xmlns:cache="http://www.springframework.org/schema/cache"   
xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
    xsi:schemaLocation="http://www.springframework.org/schema/beans   
    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
    http://www.springframework.org/schema/aop   
    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
    http://www.springframework.org/schema/mvc  
    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd  
    http://www.springframework.org/schema/tx   
    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
    http://www.springframework.org/schema/util   
    http://www.springframework.org/schema/util/spring-util-3.2.xsd  
    http://www.springframework.org/schema/context   
    http://www.springframework.org/schema/context/spring-context-3.2.xsd  
    http://www.springframework.org/schema/jdbc  
    http://www.springframework.org/schema/context/spring-jdbc-3.2.xsd  
    http://www.springframework.org/schema/cache   
    http://www.springframework.org/schema/context/spring-cache-3.2.xsd"
    default-autowire="byName"
    >  
    <!-- 指定spring注解注入层 -->
	<context:component-scan base-package="com.sumscope.cdh.api.controller" />
	<context:annotation-config />
	<import resource="classpath:springmvc-resteasy.xml" />
	<!-- 定义跳转的文件的前后缀 ,视图模式配置-->
	<bean id="viewResolver"
		class="org.springframework.web.servlet.view.InternalResourceViewResolver">
		<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
		<property name="prefix" value="/WEB-INF/" />
		<property name="suffix" value=".jsp" />
	</bean>
	<pre name="code" class="html" style="font-size: 14px; line-height: 25.1875px;"><span style="white-space:pre">	</span><!-- 静态资源不拦截-->
<mvc:resources mapping="/images/**" location="/images/*" cache-period="31556926"/> <mvc:resources mapping="/js/**" location="/js/*" cache-period="31556926"/> <mvc:resources mapping="/css/**" location="/css/*" cache-period="31556926"/> </beans>

 五、配置Mybatis相关的Sping注入及对数据源的配置,本实例采用的是Memsql数据库,是一种基于内存的数据库。 
 1、首先配置数据源配置,新建个jdbc.properties属性文件: 
 

mmsql.driverClassName=com.mysql.jdbc.Driver
mmsql.url=jdbc:mysql://localhost:3307/ticker?autoReconnect=true&characterEncoding=utf8&useUnicode=true
mmsql.username=root
mmsql.password=XXXXXX
#初始化连接大小 
mmsql.initialSize=0
#连接池最大数量
mmsql.maxActive=20
#连接池最大空闲
mmsql.maxIdle=20
#连接池最小空闲
mmsql.minIdle=1
#获取连接最大等待时间
mmsql.maxWait=60000
2、Spring与Ibaties的集成

<?xml version="1.0" encoding="GBK"?>  
<beans xmlns="http://www.springframework.org/schema/beans"   
		xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"   
		xmlns:aop="http://www.springframework.org/schema/aop"   
		xmlns:mvc="http://www.springframework.org/schema/mvc"   
		xmlns:tx="http://www.springframework.org/schema/tx"   
		xmlns:util="http://www.springframework.org/schema/util"   
		xmlns:context="http://www.springframework.org/schema/context"   
		xmlns:cache="http://www.springframework.org/schema/cache"   
		xmlns:jdbc="http://www.springframework.org/schema/jdbc"  
		    xsi:schemaLocation="http://www.springframework.org/schema/beans   
		    http://www.springframework.org/schema/beans/spring-beans-3.2.xsd  
		    http://www.springframework.org/schema/aop   
		    http://www.springframework.org/schema/aop/spring-aop-3.2.xsd  
		    http://www.springframework.org/schema/mvc  
		    http://www.springframework.org/schema/mvc/spring-mvc-3.2.xsd  
		    http://www.springframework.org/schema/tx   
		    http://www.springframework.org/schema/tx/spring-tx-3.2.xsd  
		    http://www.springframework.org/schema/util   
		    http://www.springframework.org/schema/util/spring-util-3.2.xsd  
		    http://www.springframework.org/schema/context   
		    http://www.springframework.org/schema/context/spring-context-3.2.xsd  
		    http://www.springframework.org/schema/jdbc  
		    http://www.springframework.org/schema/context/spring-jdbc-3.2.xsd  
		    http://www.springframework.org/schema/cache   
		    http://www.springframework.org/schema/context/spring-cache-3.2.xsd"> 
	<context:component-scan base-package="com.sumscope.cdh.api"/>	    
	<!-- 加载配置文件 --> 
	<bean id="propertyConfigurer"
		class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
		<property name="location" value="classpath:jdbc.properties" />
	</bean>
	<!-- 数据库连接池管理 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
        <property name="driverClassName" value="${mmsql.driverClassName}"/>  
        <property name="url" value="${mmsql.url}"/>  
        <property name="username" value="${mmsql.username}"/>  
        <property name="password" value="${mmsql.password}"/>
    	<!-- 初始化连接大小 -->
		<property name="initialSize" value="${mmsql.initialSize}"/>
		<!-- 连接池最大数量 -->
		<property name="maxActive" value="${mmsql.maxActive}"/>
		<!-- 连接池最大空闲 -->
		<property name="maxIdle" value="${mmsql.maxIdle}"/>
		<!-- 连接池最小空闲 -->
		<property name="minIdle" value="${mmsql.minIdle}"/>
		<!-- 获取连接最大等待时间 -->
		<property name="maxWait" value="${mmsql.maxWait}"/>
    </bean>
     <!-- pring和MyBatis完美整合,不需要mybatis的配置映射文件 -->  
     <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">  
        <property name="dataSource" ref="dataSource" />  
        <property name="configLocation" value="classpath:conf/mybatis-config.xml"/>
        <!-- 自动扫描mapping.xml文件 -->
        <property name="mapperLocations" value="classpath:com/sumscope/cdh/api/mapping/*Mapper.xml" />  
    </bean>
    <!-- DAO接口所在包名,Spring会自动查找其下的类 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">  
        <property name="basePackage" value="com.sumscope.cdh.api.dao" />  
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />  
    </bean>
     <!-- 配置事务管理器 -->  
    <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
        <property name="dataSource" ref="dataSource" />  
    </bean> 
    <!-- 拦截器方式配置事物 -->  
    <tx:advice id="transactionAdvice" transaction-manager="transactionManager">  
        <tx:attributes>  
            <tx:method name="add*" propagation="REQUIRED" />  
            <tx:method name="modify*" propagation="REQUIRED" />  
            <tx:method name="delete*" propagation="REQUIRED" />  
            <tx:method name="find*" propagation="SUPPORTS" />  
            <tx:method name="query*" propagation="SUPPORTS" />  
            <tx:method name="search*" propagation="SUPPORTS" />  
            <tx:method name="*" propagation="SUPPORTS" />  
        </tx:attributes>  
    </tx:advice>
     <aop:config>  
        <aop:pointcut id="transactionPointcut" expression="execution(* com.sumscope.cdh.api.service.*.*(..))" />  
        <aop:advisor pointcut-ref="transactionPointcut" advice-ref="transactionAdvice" />  
    </aop:config>           
</beans>
到此,配置文件已经配置完成,下面主要说下开发流程:

由于MyBatis属于一种半自动的ORM框架,所以主要的工作就是配置Mapping映射文件,但是由于手写映射文件很容易出错,因此可借助Mybatis自动代码工具生成相应的VO类、DAO类、和Mapper配置文件,下载地址 :点击打开链接

把工具解压后,会有如下文件:

修改generatorConfig.xml文件,设置生成类的包名及类名:

<?xml version="1.0" encoding="UTF-8"?>  
<!DOCTYPE generatorConfiguration  
  PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"  
  "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">  
<generatorConfiguration>  
<!-- 数据库驱动-->  
    <classPathEntry  location="mysql-connector-java-5.1.25-bin.jar"/>  
    <context id="DB2Tables"  targetRuntime="MyBatis3">  
        <commentGenerator>  
            <property name="suppressDate" value="true"/>  
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->  
            <property name="suppressAllComments" value="true"/>  
        </commentGenerator>  
        <!--数据库链接URL,用户名、密码 -->  
        <jdbcConnection driverClass="com.mysql.jdbc.Driver" connectionURL="jdbc:mysql://172.16.8.84:3307/ticker" userId="root" password="111111">  
        </jdbcConnection>  
        <javaTypeResolver>  
            <property name="forceBigDecimals" value="false"/>  
        </javaTypeResolver>  
        <!-- 生成模型的包名和位置-->  
        <javaModelGenerator targetPackage="com.sumscope.cdh.api.vo" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
            <property name="trimStrings" value="true"/>  
        </javaModelGenerator>  
         <!-- 生成映射文件的包名和位置-->   
        <sqlMapGenerator targetPackage="com.sumscope.cdh.api.mapping" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
        </sqlMapGenerator>  
         <!-- 生成DAO的包名和位置-->  
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.sumscope.cdh.api.IDao" targetProject="src">  
            <property name="enableSubPackages" value="true"/>  
        </javaClientGenerator>  
        <!-- 要生成的表 tableName是数据库中的表名或视图名 domainObjectName是实体类名-->
        <table tableName="bond_deal_minite_1" domainObjectName="BondDealForOneMinuteVO" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false" selectByExampleQueryId="false"></table>
    </context>  
</generatorConfiguration>  

在CMD命令行中把目录切换到生成工具的lib目录,执行如下命令生成相应的类:java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite。这样在生成之后,就在src目录下找到相应的文件夹,每个表格都会对应三个文件(实体类,DAO接口、mapper配置文件).生成的接口如不能满足的需求,可在DAO接口类中添加相应的接口,然后在Maaper.xml文件中配置相应sql语句

DAO接口

package com.sumscope.cdh.api.dao;

import java.util.List;

import org.springframework.stereotype.Repository;

import com.sumscope.cdh.api.vo.BondDealForOneMinuteVO;
@Repository
public interface BondDealForOneMinuteMapper {
	
	int deleteByPrimaryKey(Long id);

    int insert(BondDealForOneMinuteVO record);

    int insertSelective(BondDealForOneMinuteVO record);

    BondDealForOneMinuteVO selectByPrimaryKey(Long id);

    int updateByPrimaryKeySelective(BondDealForOneMinuteVO record);

    int updateByPrimaryKey(BondDealForOneMinuteVO record);
    /**
     * 查询一分钟所有的成交量的K线图
     * @return
     */
	public List<BondDealForOneMinuteVO> queryAllBondDealsForOneMinute();
	/**
	 * 查询某个债券的K线图
	 * @param bondCode
	 * @return
	 */
	public List<BondDealForOneMinuteVO> queryBondDealsForOneMinuteByBondCode(String bondCode);
	/**
	 * 查询某个债券的K线图
	 * @param bondCode
	 * @return
	 */
	public List<BondDealForOneMinuteVO> queryBondDealsForOneMinuteByBondCodeAndMarket(String bondCode,String market);
}

BondDealForOneMinuteMapper.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.sumscope.cdh.api.dao.BondDealForOneMinuteMapper" >
  <resultMap id="BaseResultMap" type="com.sumscope.cdh.api.vo.BondDealForOneMinuteVO" >
    <id column="id" property="id" jdbcType="BIGINT" />
    <result column="method" property="method" jdbcType="VARCHAR" />
    <result column="deal_id" property="dealId" jdbcType="VARCHAR" />
    <result column="trade_time" property="tradeTime" jdbcType="TIMESTAMP" />
    <result column="collect_time" property="collectTime" jdbcType="TIMESTAMP" />
    <result column="insert_time" property="insertTime" jdbcType="TIMESTAMP" />
    <result column="bond_key" property="bondKey" jdbcType="VARCHAR" />
    <result column="bond_key_listed_market" property="bondKeyListedMarket" jdbcType="VARCHAR" />
    <result column="bond_code" property="bondCode" jdbcType="VARCHAR" />
    <result column="bond_short_name" property="bondShortName" jdbcType="VARCHAR" />
    <result column="volume" property="volume" jdbcType="DECIMAL" />
    <result column="open_ytm" property="openYtm" jdbcType="DECIMAL" />
    <result column="high_ytm" property="highYtm" jdbcType="DECIMAL" />
    <result column="low_ytm" property="lowYtm" jdbcType="DECIMAL" />
    <result column="close_ytm" property="closeYtm" jdbcType="DECIMAL" />
    <result column="open_clean_price" property="openCleanPrice" jdbcType="DECIMAL" />
    <result column="high_clean_price" property="highCleanPrice" jdbcType="DECIMAL" />
    <result column="low_clean_price" property="lowCleanPrice" jdbcType="DECIMAL" />
    <result column="close_clean_price" property="closeCleanPrice" jdbcType="DECIMAL" />
    <result column="weighted_ave_clean_price" property="weightedAveCleanPrice" jdbcType="DECIMAL" />
    <result column="weighted_ave_ytm" property="weightedAveYtm" jdbcType="DECIMAL" />
    <result column="turnover_rate" property="turnoverRate" jdbcType="DECIMAL" />
    <result column="listed_market" property="listedMarket" jdbcType="VARCHAR" />
  </resultMap>
  <sql id="Base_Column_List" >
    id, method, deal_id, trade_time, collect_time, insert_time, bond_key, bond_key_listed_market, 
    bond_code, bond_short_name, volume, open_ytm, high_ytm, low_ytm, close_ytm, open_clean_price, 
    high_clean_price, low_clean_price, close_clean_price, weighted_ave_clean_price, weighted_ave_ytm, 
    turnover_rate, listed_market
  </sql>
   <!-- 查询所有的K线 -->
  <select id="queryAllBondDealsForOneMinute" resultMap="BaseResultMap">
  	select
  	<include refid="Base_Column_List"/>
  	from bond_deal_minite_1
  </select>
  <!-- 根据BondCode查询 -->
  <select id="queryBondDealsForOneMinuteByBondCode" resultMap="BaseResultMap" parameterType="java.lang.String" >
  	select
  	<include refid="Base_Column_List"/>
  	from bond_deal_minite_1
  	where bond_code = #{bondCode,jdbcType=VARCHAR}
  </select>
   <!-- 根据BondCode And Market查询 -->
  <select id="queryBondDealsForOneMinuteByBondCodeAndMarket" resultMap="BaseResultMap">
  	select
  	<include refid="Base_Column_List"/>
  	from bond_deal_minite_1
  	where bond_code = #{0} and listed_market = #{1}
  </select>
  <select id="selectByPrimaryKey" resultMap="BaseResultMap" parameterType="java.lang.Long" >
    select 
    <include refid="Base_Column_List" />
    from bond_deal_minite_1
    where id = #{id,jdbcType=BIGINT}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.Long" >
    delete from bond_deal_minite_1
    where id = #{id,jdbcType=BIGINT}
  </delete>
  <insert id="insert" parameterType="com.sumscope.cdh.api.vo.BondDealForOneMinuteVO" >
    insert into bond_deal_minite_1 (id, method, deal_id, 
      trade_time, collect_time, insert_time, 
      bond_key, bond_key_listed_market, bond_code, 
      bond_short_name, volume, open_ytm, 
      high_ytm, low_ytm, close_ytm, 
      open_clean_price, high_clean_price, low_clean_price, 
      close_clean_price, weighted_ave_clean_price, 
      weighted_ave_ytm, turnover_rate, listed_market
      )
    values (#{id,jdbcType=BIGINT}, #{method,jdbcType=VARCHAR}, #{dealId,jdbcType=VARCHAR}, 
      #{tradeTime,jdbcType=TIMESTAMP}, #{collectTime,jdbcType=TIMESTAMP}, #{insertTime,jdbcType=TIMESTAMP}, 
      #{bondKey,jdbcType=VARCHAR}, #{bondKeyListedMarket,jdbcType=VARCHAR}, #{bondCode,jdbcType=VARCHAR}, 
      #{bondShortName,jdbcType=VARCHAR}, #{volume,jdbcType=DECIMAL}, #{openYtm,jdbcType=DECIMAL}, 
      #{highYtm,jdbcType=DECIMAL}, #{lowYtm,jdbcType=DECIMAL}, #{closeYtm,jdbcType=DECIMAL}, 
      #{openCleanPrice,jdbcType=DECIMAL}, #{highCleanPrice,jdbcType=DECIMAL}, #{lowCleanPrice,jdbcType=DECIMAL}, 
      #{closeCleanPrice,jdbcType=DECIMAL}, #{weightedAveCleanPrice,jdbcType=DECIMAL}, 
      #{weightedAveYtm,jdbcType=DECIMAL}, #{turnoverRate,jdbcType=DECIMAL}, #{listedMarket,jdbcType=VARCHAR}
      )
  </insert>
  <insert id="insertSelective" parameterType="com.sumscope.cdh.api.vo.BondDealForOneMinuteVO" >
    insert into bond_deal_minite_1
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="method != null" >
        method,
      </if>
      <if test="dealId != null" >
        deal_id,
      </if>
      <if test="tradeTime != null" >
        trade_time,
      </if>
      <if test="collectTime != null" >
        collect_time,
      </if>
      <if test="insertTime != null" >
        insert_time,
      </if>
      <if test="bondKey != null" >
        bond_key,
      </if>
      <if test="bondKeyListedMarket != null" >
        bond_key_listed_market,
      </if>
      <if test="bondCode != null" >
        bond_code,
      </if>
      <if test="bondShortName != null" >
        bond_short_name,
      </if>
      <if test="volume != null" >
        volume,
      </if>
      <if test="openYtm != null" >
        open_ytm,
      </if>
      <if test="highYtm != null" >
        high_ytm,
      </if>
      <if test="lowYtm != null" >
        low_ytm,
      </if>
      <if test="closeYtm != null" >
        close_ytm,
      </if>
      <if test="openCleanPrice != null" >
        open_clean_price,
      </if>
      <if test="highCleanPrice != null" >
        high_clean_price,
      </if>
      <if test="lowCleanPrice != null" >
        low_clean_price,
      </if>
      <if test="closeCleanPrice != null" >
        close_clean_price,
      </if>
      <if test="weightedAveCleanPrice != null" >
        weighted_ave_clean_price,
      </if>
      <if test="weightedAveYtm != null" >
        weighted_ave_ytm,
      </if>
      <if test="turnoverRate != null" >
        turnover_rate,
      </if>
      <if test="listedMarket != null" >
        listed_market,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=BIGINT},
      </if>
      <if test="method != null" >
        #{method,jdbcType=VARCHAR},
      </if>
      <if test="dealId != null" >
        #{dealId,jdbcType=VARCHAR},
      </if>
      <if test="tradeTime != null" >
        #{tradeTime,jdbcType=TIMESTAMP},
      </if>
      <if test="collectTime != null" >
        #{collectTime,jdbcType=TIMESTAMP},
      </if>
      <if test="insertTime != null" >
        #{insertTime,jdbcType=TIMESTAMP},
      </if>
      <if test="bondKey != null" >
        #{bondKey,jdbcType=VARCHAR},
      </if>
      <if test="bondKeyListedMarket != null" >
        #{bondKeyListedMarket,jdbcType=VARCHAR},
      </if>
      <if test="bondCode != null" >
        #{bondCode,jdbcType=VARCHAR},
      </if>
      <if test="bondShortName != null" >
        #{bondShortName,jdbcType=VARCHAR},
      </if>
      <if test="volume != null" >
        #{volume,jdbcType=DECIMAL},
      </if>
      <if test="openYtm != null" >
        #{openYtm,jdbcType=DECIMAL},
      </if>
      <if test="highYtm != null" >
        #{highYtm,jdbcType=DECIMAL},
      </if>
      <if test="lowYtm != null" >
        #{lowYtm,jdbcType=DECIMAL},
      </if>
      <if test="closeYtm != null" >
        #{closeYtm,jdbcType=DECIMAL},
      </if>
      <if test="openCleanPrice != null" >
        #{openCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="highCleanPrice != null" >
        #{highCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="lowCleanPrice != null" >
        #{lowCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="closeCleanPrice != null" >
        #{closeCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="weightedAveCleanPrice != null" >
        #{weightedAveCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="weightedAveYtm != null" >
        #{weightedAveYtm,jdbcType=DECIMAL},
      </if>
      <if test="turnoverRate != null" >
        #{turnoverRate,jdbcType=DECIMAL},
      </if>
      <if test="listedMarket != null" >
        #{listedMarket,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.sumscope.cdh.api.vo.BondDealForOneMinuteVO" >
    update bond_deal_minite_1
    <set >
      <if test="method != null" >
        method = #{method,jdbcType=VARCHAR},
      </if>
      <if test="dealId != null" >
        deal_id = #{dealId,jdbcType=VARCHAR},
      </if>
      <if test="tradeTime != null" >
        trade_time = #{tradeTime,jdbcType=TIMESTAMP},
      </if>
      <if test="collectTime != null" >
        collect_time = #{collectTime,jdbcType=TIMESTAMP},
      </if>
      <if test="insertTime != null" >
        insert_time = #{insertTime,jdbcType=TIMESTAMP},
      </if>
      <if test="bondKey != null" >
        bond_key = #{bondKey,jdbcType=VARCHAR},
      </if>
      <if test="bondKeyListedMarket != null" >
        bond_key_listed_market = #{bondKeyListedMarket,jdbcType=VARCHAR},
      </if>
      <if test="bondCode != null" >
        bond_code = #{bondCode,jdbcType=VARCHAR},
      </if>
      <if test="bondShortName != null" >
        bond_short_name = #{bondShortName,jdbcType=VARCHAR},
      </if>
      <if test="volume != null" >
        volume = #{volume,jdbcType=DECIMAL},
      </if>
      <if test="openYtm != null" >
        open_ytm = #{openYtm,jdbcType=DECIMAL},
      </if>
      <if test="highYtm != null" >
        high_ytm = #{highYtm,jdbcType=DECIMAL},
      </if>
      <if test="lowYtm != null" >
        low_ytm = #{lowYtm,jdbcType=DECIMAL},
      </if>
      <if test="closeYtm != null" >
        close_ytm = #{closeYtm,jdbcType=DECIMAL},
      </if>
      <if test="openCleanPrice != null" >
        open_clean_price = #{openCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="highCleanPrice != null" >
        high_clean_price = #{highCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="lowCleanPrice != null" >
        low_clean_price = #{lowCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="closeCleanPrice != null" >
        close_clean_price = #{closeCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="weightedAveCleanPrice != null" >
        weighted_ave_clean_price = #{weightedAveCleanPrice,jdbcType=DECIMAL},
      </if>
      <if test="weightedAveYtm != null" >
        weighted_ave_ytm = #{weightedAveYtm,jdbcType=DECIMAL},
      </if>
      <if test="turnoverRate != null" >
        turnover_rate = #{turnoverRate,jdbcType=DECIMAL},
      </if>
      <if test="listedMarket != null" >
        listed_market = #{listedMarket,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=BIGINT}
  </update>
  <update id="updateByPrimaryKey" parameterType="com.sumscope.cdh.api.vo.BondDealForOneMinuteVO" >
    update bond_deal_minite_1
    set method = #{method,jdbcType=VARCHAR},
      deal_id = #{dealId,jdbcType=VARCHAR},
      trade_time = #{tradeTime,jdbcType=TIMESTAMP},
      collect_time = #{collectTime,jdbcType=TIMESTAMP},
      insert_time = #{insertTime,jdbcType=TIMESTAMP},
      bond_key = #{bondKey,jdbcType=VARCHAR},
      bond_key_listed_market = #{bondKeyListedMarket,jdbcType=VARCHAR},
      bond_code = #{bondCode,jdbcType=VARCHAR},
      bond_short_name = #{bondShortName,jdbcType=VARCHAR},
      volume = #{volume,jdbcType=DECIMAL},
      open_ytm = #{openYtm,jdbcType=DECIMAL},
      high_ytm = #{highYtm,jdbcType=DECIMAL},
      low_ytm = #{lowYtm,jdbcType=DECIMAL},
      close_ytm = #{closeYtm,jdbcType=DECIMAL},
      open_clean_price = #{openCleanPrice,jdbcType=DECIMAL},
      high_clean_price = #{highCleanPrice,jdbcType=DECIMAL},
      low_clean_price = #{lowCleanPrice,jdbcType=DECIMAL},
      close_clean_price = #{closeCleanPrice,jdbcType=DECIMAL},
      weighted_ave_clean_price = #{weightedAveCleanPrice,jdbcType=DECIMAL},
      weighted_ave_ytm = #{weightedAveYtm,jdbcType=DECIMAL},
      turnover_rate = #{turnoverRate,jdbcType=DECIMAL},
      listed_market = #{listedMarket,jdbcType=VARCHAR}
    where id = #{id,jdbcType=BIGINT}
  </update>
</mapper>
Mybatis像Hibernate一样也支持一级缓存和二级缓存:

MyBatis的一级缓存指的是在一个Session域内,session为关闭的时候执行的查询会根据SQL为key被缓存(跟mysql缓存一样,修改任何参数的值都会导致缓存失效)

1)单独使用MyBatis而不继承Spring,使用原生的MyBatis的SqlSessionFactory来构造sqlSession查询,是可以使用以及缓存的,示例代码如下:

public class Test {
    public static void main(String[] args) throws IOException {
        String config = "mybatis-config.xml";
        InputStream is = Resources.getResourceAsStream(config);
        SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
        SqlSession session = factory.openSession();
        System.out.println(session.selectOne("selectUserByID", 1));
        // 同一个session的相同sql查询,将会使用一级缓存 
        System.out.println(session.selectOne("selectUserByID", 1));
        // 参数改变,需要重新查询
        System.out.println(session.selectOne("selectUserByID", 2));
        // 清空缓存后需要重新查询
        session.clearCache();
        System.out.println(session.selectOne("selectUserByID", 1));
        // session close以后,仍然使用同一个db connection
        session.close();
        session = factory.openSession();
        System.out.println(session.selectOne("selectUserByID", 1));
    }
}

    看以看出来,当参数不变的时候只进行了一次查询,参数变更以后,则需要重新进行查询,而清空缓存以后,参数相同的查询过的SQL也需要重新查询,而且使用的数据库连接是同一个数据库连接,这里要得益于我们在mybatis-config.xml里面的datasource设置:

<environments default="development">
        <environment id="development">
            <transactionManager type="JDBC">
            </transactionManager>
            <dataSource type="POOLED">
                <property name="driver" value="com.mysql.jdbc.Driver" />
                <property name="url" value="jdbc:mysql://127.0.0.1:3306/mybatistest?characterEncoding=utf8" />
                <property name="username" value="root" />
                <property name="password" value="root" />
            </dataSource>
        </environment>
    </environments>

注意datasource使用的是POOLED,也就是使用了连接池,所以数据库连接可回收利用,当然这个environment属性在集成spring的时候是不需要的,因为我们需要另外配置datasource的bean.

2) 跟Spring集成的时候(使用mybatis-spring)

@Repository
public class UserDao extends SqlSessionDaoSupport {
    public User selectUserById(int id) {
        SqlSession session = getSqlSession();
        session.selectOne("dao.userdao.selectUserByID", id);
        // 由于session的实现是SqlSessionTemplate的动态代理实现
        // 它已经在代理类内执行了session.close(),所以无需手动关闭session
        return session.selectOne("dao.userdao.selectUserByID", id);
    }
}

这里执行了2次sql查询,看似我们使用了同一个sqlSession,但是实际上因为我们的dao继承了SqlSessionDaoSupport,而SqlSessionDaoSupport内部sqlSession的实现是使用用动态代理实现的,这个动态代理sqlSessionProxy使用一个模板方法封装了select()等操作,每一次select()查询都会自动先执行openSession(),执行完close()以后调用close()方法,相当于生成了一个新的session实例,所以我们无需手动的去关闭这个session()(关于这一点见下面mybatis的官方文档),当然也无法使用mybatis的一级缓存,也就是说mybatis的一级缓存在spring中是没有作用的.

二级缓存就是global caching,它超出session范围之外,可以被所有sqlSession共享,它的实现机制和mysql的缓存一样,开启它只需要在mybatis的配置文件开启settings里的

<setting name="cacheEnabled" value="true"/>

以及在相应的Mapper文件(例如userMapper.xml)里开启

<mapper namespace="dao.userdao">
   ...  select statement ...
       <!-- Cache 配置 -->
    <cache
        eviction="FIFO"
        flushInterval="60000"
        size="512"
        readOnly="true" />
</mapper>

需要注意的是global caching的作用域是针对Mapper的Namespace而言的,也就是说只在有在这个Namespace内的查询才能共享这个cache。

Service层的编写:

定义Service接口:

/**
 * 
 */
package com.sumscope.cdh.api.service;

import java.util.List;

import com.sumscope.cdh.api.vo.BondDealForOneMinuteVO;

/**
 * @author sijin.luo
 *
 */
public interface IBondDealForKLineService {
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinute();
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinuteByBondCode(String bondCode);
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinuteByBondCodeAndMarket(String bondCode,String market);
}
定义Service实现:

/**
 * 
 */
package com.sumscope.cdh.api.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sumscope.cdh.api.dao.BondDealForOneMinuteMapper;
import com.sumscope.cdh.api.vo.BondDealForOneMinuteVO;

/**
 * @author sijin.luo
 *
 */
@Service
public class BondDealForKLineServiceImpl implements IBondDealForKLineService {
	@Autowired
	private BondDealForOneMinuteMapper bondDealForOneMinuteDao;

	/* (non-Javadoc)
	 * @see com.sumscope.cdh.api.service.IBondDealForKLineService#queryForOneMiniuteBondDeal()
	 */
	@Override
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinute() {
		return bondDealForOneMinuteDao.queryAllBondDealsForOneMinute();
	}

	@Override
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinuteByBondCode(
			String bondCode) {
		return bondDealForOneMinuteDao.queryBondDealsForOneMinuteByBondCode(bondCode);
	}

	@Override
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinuteByBondCodeAndMarket(
			String bondCode, String market) {
		return bondDealForOneMinuteDao.queryBondDealsForOneMinuteByBondCodeAndMarket(bondCode, market);
	}

}
编写Controller层代码:

/**
 * 
 */
package com.sumscope.cdh.api.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.sumscope.cdh.api.dao.BondDealForOneMinuteMapper;
import com.sumscope.cdh.api.vo.BondDealForOneMinuteVO;

/**
 * @author sijin.luo
 *
 */
@Service
public class BondDealForKLineServiceImpl implements IBondDealForKLineService {
	@Autowired
	private BondDealForOneMinuteMapper bondDealForOneMinuteDao;

	/* (non-Javadoc)
	 * @see com.sumscope.cdh.api.service.IBondDealForKLineService#queryForOneMiniuteBondDeal()
	 */
	@Override
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinute() {
		return bondDealForOneMinuteDao.queryAllBondDealsForOneMinute();
	}

	@Override
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinuteByBondCode(
			String bondCode) {
		return bondDealForOneMinuteDao.queryBondDealsForOneMinuteByBondCode(bondCode);
	}

	@Override
	public List<BondDealForOneMinuteVO> getBondDealsForOneMinuteByBondCodeAndMarket(
			String bondCode, String market) {
		return bondDealForOneMinuteDao.queryBondDealsForOneMinuteByBondCodeAndMarket(bondCode, market);
	}

}
最后编写一个测试用例:

package com.sumscope.cdh.api.controller;


import javax.ws.rs.core.Response;

import org.jboss.resteasy.client.jaxrs.ResteasyClient;
import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.jboss.resteasy.client.jaxrs.ResteasyWebTarget;
import org.junit.Test;

import junit.framework.TestCase;

public class BondDealForKLineControllerTest extends TestCase {
	
	@Test
	public void testGetBondDealForMinute(){
		ResteasyClient client = new ResteasyClientBuilder().build();
		String url = "http://localhost:8080/CDHAPI/bond/quote/minutely/1m/120527.sz";
		ResteasyWebTarget target = client.target(url);
		Response response = target.request().get();
		if(response.getStatus()!=200)
		{
			throw new RuntimeException("Failed : HTTP error code : "+response.getStatus());
		}
		 System.out.println("Server response : \n");
		 System.out.println(response.readEntity(String.class));
		 response.close();
	}
}
调用2:

URL restServiceURL = new URL("http://localhost:8080/CDHAPI/bond/quote/minutely/1m/112073");
	     HttpURLConnection httpConnection = (HttpURLConnection) restServiceURL.openConnection();
	     httpConnection.setRequestMethod("GET");
         httpConnection.setRequestProperty("Accept", "application/json");
         if (httpConnection.getResponseCode() != 200) {
             throw new RuntimeException("HTTP GET Request Failed with Error code : "
                           + httpConnection.getResponseCode());
         }
         BufferedReader responseBuffer = new BufferedReader(new InputStreamReader(
                 (httpConnection.getInputStream())));

          String output;
          System.out.println("Output from Server:  \n");
          String jsonStr="";
          while ((output = responseBuffer.readLine()) != null) {
        	  	jsonStr = output;
                System.out.println(jsonStr);
          }
          httpConnection.disconnect();
          List<BondDeal> deals = null;
          if(jsonStr!=null&&!jsonStr.isEmpty()){
        	  deals = JSONUtils.readJson(jsonStr, List.class, BondDeal.class);
          }
          System.out.println("deals's Size:"+deals.size());

在CMD命令行中把目录切换到生成工具的lib目录,执行如下命令生成相应的类:java -jar mybatis-generator-core-1.3.2.jar -configfile generatorConfig.xml -overwrite。这样在生成之后,就在src目录下找到相应的文件夹,每个表格都会对应三个文件(实体类,DAO接口、mapper配置文件).生成的接口如不能满足的需求,可在DAO接口类中添加相应的接口,然后在Maaper.xml文件中配置相应sql语句

DAO接口

你可能感兴趣的:(基于RestEasy开发环境搭建)