springmvc+mybatis集成redis

前期準備

(1)開發環境 : idea,tomcat8,jdk1.8,redis,mybatis,maven,spring4.2.0,log4j
(2)逆向工程配置
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>
    <!--導入屬性配置 -->
    <properties resource="generator.properties"></properties>

    <!--指定特定數據庫的jdbc驅動jar包的位置 -->
    <classPathEntry location="${jdbc.driverLocation}"/>

    <context id="default" targetRuntime="MyBatis3">


        <!-- optional,旨在創建class時,對註釋進行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true" />
        </commentGenerator>


        <!--jdbc的數據庫連接 -->
        <jdbcConnection driverClass="${jdbc.driverClass}" connectionURL="${jdbc.connectionURL}" userId="${jdbc.userId}" password="${jdbc.password}">
        </jdbcConnection>



        <!-- 非必需,類型處理器,在數據庫類型和java類型之間的轉換控制-->
        <javaTypeResolver >
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- Model模型生成器,用來生成含有主鍵key的類,記錄類 以及查詢Example類
            targetPackage     指定生成的model生成所在的包名
            targetProject     指定在該項目下所在的路徑
        -->
        <javaModelGenerator targetPackage="com.wyn.app.entity" targetProject="src/main/java">
            <!-- 是否對model添加 構造函數 -->
            <!-- <property name="constructorBased" value="true"/>-->

            <!-- 是否允許子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="false"/>

            <!-- 建立的Model對象是否 不可改變  即生成的Model對象不會有 setter方法,只有構造方法 -->
            <!--<property name="immutable" value="true"/>-->

            <!-- 給Model添加一個父類 -->
            <!--<property name="rootClass" value="com.foo.louis.Hello"/>-->

            <!-- 是否對類CHAR類型的列的數據進行trim操作 -->
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>

        <!--Mapper映射文件生成所在的目錄 爲每一個數據庫的表生成對應的SqlMap文件 -->
        <sqlMapGenerator targetPackage="com.wyn.app.sqlmap" targetProject="src/main/java">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>


        <!-- 客戶端代碼,生成易於使用的針對Model對象和XML配置文件 的代碼
                type="ANNOTATEDMAPPER",生成Java Model 和基於註解的Mapper對象
                type="MIXEDMAPPER",生成基於註解的Java Model 和相應的Mapper對象
                type="XMLMAPPER",生成SQLMap XML文件和獨立的Mapper接口
        -->
        <javaClientGenerator targetPackage="com.wyn.app.dao" targetProject="src/main/java" type="MIXEDMAPPER">
            <property name="enableSubPackages" value=""/>
            <!--
                    定義Maper.java 源代碼中的ByExample() 方法的可視性,可選的值有:
                    public;
                    private;
                    protected;
                    default
                    注意:如果 targetRuntime="MyBatis3",此參數被忽略
             -->
            <property name="exampleMethodVisibility" value=""/>
            <!--
                                           方法名計數器
              Important note: this property is ignored if the target runtime is MyBatis3.
             -->
            <property name="methodNameCalculator" value=""/>

            <!--
                                                爲生成的接口添加父接口
             -->
            <property name="rootInterface" value=""/>

        </javaClientGenerator>



        <table tableName="user" schema="" enableCountByExample="false" enableUpdateByExample="false" enableDeleteByExample="false"
               enableSelectByExample="false" selectByExampleQueryId="false">

            <!-- optional   , only for mybatis3 runtime
                 自動生成的鍵值(identity,或者序列值)
               如果指定此元素,MBG將會生成<selectKey>元素,然後將此元素插入到SQL Map的<insert> 元素之中
               sqlStatement 的語句將會返回新的值
               如果是一個自增主鍵的話,你可以使用預定義的語句,或者添加自定義的SQL語句. 預定義的值如下:
                  Cloudscape    This will translate to: VALUES IDENTITY_VAL_LOCAL()
                  DB2:      VALUES IDENTITY_VAL_LOCAL()
                  DB2_MF:       SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
                  Derby:        VALUES IDENTITY_VAL_LOCAL()
                  HSQLDB:   CALL IDENTITY()
                  Informix:     select dbinfo('sqlca.sqlerrd1') from systables where tabid=1
                  MySql:        SELECT LAST_INSERT_ID()
                  SqlServer:    SELECT SCOPE_IDENTITY()
                  SYBASE:   SELECT @@IDENTITY
                  JDBC:     This will configure MBG to generate code for MyBatis3 suport of JDBC standard generated keys. This is a database independent method of obtaining the value from identity columns.
                  identity: 自增主鍵  If true, then the column is flagged as an identity column and the generated <selectKey> element will be placed after the insert (for an identity column). If false, then the generated <selectKey> will be placed before the insert (typically for a sequence).

            -->
            <!--<generatedKey column="" sqlStatement="" identity="" type=""/>-->


            <!-- optional.
                    列的命名規則:
                    MBG使用 <columnRenamingRule> 元素在計算列名的對應 名稱之前,先對列名進行重命名,
                    作用:一般需要對BUSI_CLIENT_NO 前的BUSI_進行過濾
                    支持正在表達式
                     searchString 表示要被換掉的字符串
                     replaceString 則是要換成的字符串,默認情況下爲空字符串,可選
            -->
           <!-- <columnRenamingRule searchString="" replaceString=""/>-->



            <!-- optional.告訴 MBG 忽略某一列
                    column,需要忽略的列
                    delimitedColumnName:true ,匹配column的值和數據庫列的名稱 大小寫完全匹配,false 忽略大小寫匹配
                    是否限定表的列名,即固定表列在Model中的名稱
            -->
           <!-- <ignoreColumn column="PLAN_ID"  delimitedColumnName="true" />-->


            <!--optional.覆蓋MBG對Model 的生成規則
                 column: 數據庫的列名
                 javaType: 對應的Java數據類型的完全限定名
                 在必要的時候可以覆蓋由JavaTypeResolver計算得到的java數據類型. For some databases, this is necessary to handle "odd" database types (e.g. MySql's unsigned bigint type should be mapped to java.lang.Object).
                 jdbcType:該列的JDBC數據類型(INTEGER, DECIMAL, NUMERIC, VARCHAR, etc.),該列可以覆蓋由JavaTypeResolver計算得到的Jdbc類型,對某些數據庫而言,對於處理特定的JDBC 驅動癖好 很有必要(e.g. DB2's LONGVARCHAR type should be mapped to VARCHAR for iBATIS).
                 typeHandler:

            -->
            <!--<columnOverride column="" javaType=""    jdbcType="" typeHandler=""  delimitedColumnName="" />-->

        </table>
    </context>
</generatorConfiguration>

generator.properties:

#mysql配置
jdbc.driverLocation=C:\\Users\\wangyanan\\.m2\\repository\\mysql\\mysql-connector-java\\5.1.36\\mysql-connector-java-5.1.36.jar
jdbc.driverClass=com.mysql.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://localhost:3306/webredis
jdbc.userId=root
jdbc.password=123456

項目結構

1整體結構
這裏寫圖片描述
2 詳情結構
這裏寫圖片描述

配置

1 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.jesf-restful</groupId>
    <artifactId>redis-app</artifactId>
    <packaging>war</packaging>
    <version>1.0-SNAPSHOT</version>
    <name>redis-app Maven Webapp</name>
    <url>http://maven.apache.org</url>
    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>3.8.1</version>
            <scope>test</scope>
        </dependency>

        <!-- 映入JSON -->
        <dependency>
            <groupId>org.codehaus.jackson</groupId>
            <artifactId>jackson-mapper-asl</artifactId>
            <version>1.9.13</version>
        </dependency>

        <!-- 數據庫連接池druid、 用於數據庫字段加、解密 -->
        <!-- https://mvnrepository.com/artifact/com.alibaba/druid -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
            <version>1.0.26</version>
        </dependency>

        <!-- 導入jbcp的jar,用來在application.xml中配置數據庫, 如jndi,是主流數據庫連接池之一 -->
        <dependency>
            <groupId>commons-dbcp</groupId>
            <artifactId>commons-dbcp</artifactId>
            <version>1.2.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
       <!-- <dependency>
            <groupId>redis.clients</groupId>
            <artifactId>jedis</artifactId>
            <version>2.5.2</version>
        </dependency>-->

        <!-- https://mvnrepository.com/artifact/org.apache.commons/commons-pool2 -->
        <!--<dependency>
            <groupId>org.apache.commons</groupId>
            <artifactId>commons-pool2</artifactId>
            <version>2.0</version>
        </dependency>-->

        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>jstl</artifactId>
            <version>1.2</version>
            <scope>runtime</scope>
        </dependency>

        <!-- 引入redis依賴 -->
        <dependency>
            <groupId>org.mybatis.caches</groupId>
            <artifactId>mybatis-redis</artifactId>
            <version>1.0.0-beta2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis</artifactId>
            <version>3.2.7</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis-spring -->
        <dependency>
            <groupId>org.mybatis</groupId>
            <artifactId>mybatis-spring</artifactId>
            <version>1.2.2</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.36</version>
        </dependency>

        <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>3.1.0</version>
            <scope>provided</scope>
        </dependency>

        <!-- 序列化:將對象轉換爲JSON字符串 String strJson=JSON.toJSONString(實體對象); 反序列化: UserInfo
            userInfo=JSON.parseObject(json,UserInfo.class); -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.9</version>
        </dependency>

        <dependency>
            <groupId>commons-beanutils</groupId>
            <artifactId>commons-beanutils</artifactId>
            <version>1.7.0</version>
        </dependency>

        <dependency>
            <groupId>commons-lang</groupId>
            <artifactId>commons-lang</artifactId>
            <version>2.5</version>
        </dependency>

        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>1.1.3</version>
        </dependency>

        <dependency>
            <groupId>net.sf.json-lib</groupId>
            <artifactId>json-lib</artifactId>
            <version>2.4</version>
            <classifier>jdk15</classifier><!--指定jdk版本 -->
        </dependency>

        <!-- log4j -->
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-log4j12</artifactId>
            <version>1.7.21</version>
            <scope>compile</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-aop</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-beans</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-context-support</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-core</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-expression</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-instrument</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-instrument-tomcat</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jdbc</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-jms</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-messaging</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-orm</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-oxm</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.2.0.RELEASE</version>
            <scope>test</scope>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-tx</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-web</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-webmvc-portlet</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-websocket</artifactId>
            <version>4.2.0.RELEASE</version>
        </dependency>

    </dependencies>

    <build>
        <finalName>web-app</finalName>
        <resources>
            <resource>
                <directory>src/main/java</directory>
            </resource>
            <resource>
                <directory>src/main/resources</directory>
            </resource>
        </resources>
        <plugins>

            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>2.0.2</version>
                <configuration>
                    <source>1.8</source>
                    <target>1.8</target>
                </configuration>
            </plugin>

            <plugin>
                <groupId>org.mybatis.generator</groupId>
                <artifactId>mybatis-generator-maven-plugin</artifactId>
                <version>1.3.2</version>
                <configuration>
                    <verbose>true</verbose>
                    <overwrite>true</overwrite>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>

2 web.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
         id="WebApp_ID" version="3.1">
  <display-name>redisapp</display-name>
  <welcome-file-list>
    <welcome-file>index.html</welcome-file>
    <welcome-file>index.htm</welcome-file>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
  <!-- 配置spring資源路徑 -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:spring-mybatis.xml</param-value>
  </context-param>

  <!-- 配置log4j -->
  <context-param>
    <!--log4j配置地址 -->
    <param-name>log4jConfigLocation</param-name>
    <!-- <param-value>/WEB-INF/classes/log4j.properties</param-value> -->
    <param-value>classpath:log4j.properties</param-value>
  </context-param>
  <context-param>
    <!-- log4j 配置掃描刷新間隔 可以不用 -->
    <param-name>log4jRefreshInterval</param-name>
    <param-value>10000</param-value>
  </context-param>
  <!-- spring裏的log4j配置監聽器 -->
  <listener>
    <listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
  </listener>

  <!--配置spring上下文監聽器  -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!--防止spring內存溢出 -->
  <listener>
    <listener-class>org.springframework.web.util.IntrospectorCleanupListener</listener-class>
  </listener>

  <!-- 字符集過濾 -->
  <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>

  <!-- springmvc的配置 -->
  <servlet>
    <servlet-name>SpringMVCServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:spring.xml</param-value>
    </init-param>
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>SpringMVCServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
</web-app>

3 spring.xml配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xsi:schemaLocation=" 
                    http://www.springframework.org/schema/context 
                    http://www.springframework.org/schema/context/spring-context-4.2.xsd 
                    http://www.springframework.org/schema/beans 
                    http://www.springframework.org/schema/beans/spring-beans-4.2.xsd 
                    http://www.springframework.org/schema/mvc 
                    http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd 
                    http://www.springframework.org/schema/aop 
                    http://www.springframework.org/schema/aop/spring-aop-4.2.xsd 
                    http://www.springframework.org/schema/tx 
                    http://www.springframework.org/schema/tx/spring-tx-4.2.xsd
                    http://cxf.apache.org/bindings/soap 
                    http://cxf.apache.org/schemas/configuration/soap.xsd
                    http://cxf.apache.org/jaxws 
                    http://cxf.apache.org/schemas/jaxws.xsd"
xmlns:p="http://www.springframework.org/schema/p" 
xmlns:tx="http://www.springframework.org/schema/tx" 
xmlns:aop="http://www.springframework.org/schema/aop" 
xmlns:context="http://www.springframework.org/schema/context" 
xmlns:mvc="http://www.springframework.org/schema/mvc" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xmlns="http://www.springframework.org/schema/beans"
xmlns:jaxws="http://cxf.apache.org/jaxws"
xmlns:soap="http://cxf.apache.org/bindings/soap">
    <!--使用註解的方式  -->
    <!-- <mvc:annotation-driven/> -->
    <mvc:annotation-driven>
        <mvc:message-converters register-defaults="false">
            <!-- 避免IE執行AJAX時,返回JSON出現下載文件 -->
            <bean id="fastJsonHttpMessageConverter"
                  class="com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter">
                <property name="supportedMediaTypes">
                    <list>
                        <!-- 這裏順序不能反,一定先寫text/html,不然ie下出現下載提示 -->
                        <value>text/html;charset=UTF-8</value>
                        <value>application/json;charset=UTF-8</value>
                    </list>
                </property>
            </bean>
            <bean class="org.springframework.http.converter.StringHttpMessageConverter">
                <constructor-arg value="UTF-8" />
            </bean>
        </mvc:message-converters>
    </mvc:annotation-driven>
    <!-- 在哪個包下去查找這些註解配置的類 -->
    <!-- <context:component-scan base-package="com.sm.order;org.ws.webservice;com.rst.openservice;com.wei.server"></context:component-scan> -->
    <context:component-scan base-package="com.wyn.app"></context:component-scan>

    <!-- 啓動SpringMVC的註解功能,完成請求和註解POJO的映射 -->
    <!--<bean
            class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter">
        <property name="messageConverters">
            <list>
                <ref bean="fastJsonHttpMessageConverter" /> &lt;!&ndash; JSON轉換器 &ndash;&gt;
            </list>
        </property>
    </bean>-->

    <!--配置ModelAndView(jsp)解析器  -->
    <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">  
        <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/>  
        <property name="prefix" value="/WEB-INF/view/"></property>
        <property name="suffix" value=".jsp"></property><!--可爲空,方便實現自已的依據擴展名來選擇視圖解釋類的邏輯  -->
    </bean>

    <!-- 靜態資源的訪問方式 -->
    <mvc:default-servlet-handler/>
</beans>

4 spring-mybatis配置

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context-4.2.xsd
            http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
            http://www.springframework.org/schema/mvc
            http://www.springframework.org/schema/mvc/spring-mvc-4.2.xsd
            http://www.springframework.org/schema/aop
            http://www.springframework.org/schema/aop/spring-aop-4.2.xsd
            http://www.springframework.org/schema/tx
            http://www.springframework.org/schema/tx/spring-tx-4.2.xsd">

    <!-- 引入數據源的配置文件 -->
   <!-- <bean id="propertyConfigurer"
          class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="location" value="classpath:/META-INF/app_config/property/jdbc.properties" />
    </bean>-->

    <!-- 配置數據源 -->
    <!--<bean id="dataSource"
          class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="url" value="jdbc:mysql://localhost:3306/webredis?autoReconnect=true&amp;useSSL=false"></property>
        <property name="driverClassName" value="com.mysql.jdbc.Driver"></property>
        <property name="username" value="root"></property>
        <property name="password" value="123456"></property>
    </bean>-->

    <!-- 引入數據源的配置文件 -->
    <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="${driver}" />
        <property name="url" value="${url}" />
        <property name="username" value="${username}" />
        <property name="password" value="${password}" />
        <!-- 初始化連接大小 -->
        <property name="initialSize" value="${initialSize}"></property>
        <!-- 連接池最大數量 -->
        <property name="maxActive" value="${maxActive}"></property>
        <!-- 連接池最大空閒 -->
        <property name="maxIdle" value="${maxIdle}"></property>
        <!-- 連接池最小空閒 -->
        <property name="minIdle" value="${minIdle}"></property>
        <!-- 獲取連接最大等待時間 -->
        <property name="maxWait" value="${maxWait}"></property>
    </bean>

    <!-- spring和MyBatis完美整合,不需要mybatis的配置映射文件 -->
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <property name="dataSource" ref="dataSource"></property>
        <property name="mapperLocations">
            <list>
                <value>classpath:com/wyn/app/sqlmap/*.xml</value>
            </list>
        </property>
        <!--開啓redis緩存 -->
        <property name="configurationProperties">
            <props>
                <!--全局映射器啓用緩存-->
                <prop key ="cacheEnabled">true</prop>
                <!--查詢時,關閉關連對象即時加載以提高性能-->
                <prop key="lazyLoadingEnabled">false</prop>
                <!-- 設置關聯對象加載的形態,此處爲按需要加載字段(加載字段由sql決定),不會加載關聯表的所有字段,以提高性能-->
                <prop key="aggressiveLazyLoading">true</prop>
            </props>
        </property>
    </bean>
    <!-- DAO接口所在包名,Spring會自動查找其下的類 -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.wyn.app.dao" />
        <property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
    </bean>
    <!-- (事務管理)transaction manager, use JtaTransactionManager for global tx -->
    <bean id="transactionManager"  class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>
</beans>

jdbc.properties:

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/webredis
username=root
password=123456
#定義初始化連接數
initialSize=0
#定義最大連接數
maxActive=20
#定義最大空閒
maxIdle=20
#定義最小空閒
minIdle=1
#定義最長等待時間
maxWait=60000

5 dao層

package com.wyn.app.dao;

import com.wyn.app.entity.User;
import org.apache.ibatis.annotations.*;

import java.util.List;

public interface UserMapper {
    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table user
     *
     * @mbggenerated
     */
    @Delete({
        "delete from user",
        "where id = #{id,jdbcType=INTEGER}"
    })
    int deleteByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table user
     *
     * @mbggenerated
     */
    @Insert({
        "insert into user (id, username, ",
        "password, sex, mail, ",
        "status)",
        "values (#{id,jdbcType=INTEGER}, #{username,jdbcType=VARCHAR}, ",
        "#{password,jdbcType=VARCHAR}, #{sex,jdbcType=VARCHAR}, #{mail,jdbcType=VARCHAR}, ",
        "#{status,jdbcType=INTEGER})"
    })
    int insert(User record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table user
     *
     * @mbggenerated
     */
    int insertSelective(User record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table user
     *
     * @mbggenerated
     */
    @Select({
        "select",
        "id, username, password, sex, mail, status",
        "from user",
        "where id = #{id,jdbcType=INTEGER}"
    })
    @ResultMap("BaseResultMap")
    User selectByPrimaryKey(Integer id);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table user
     *
     * @mbggenerated
     */
    int updateByPrimaryKeySelective(User record);

    /**
     * This method was generated by MyBatis Generator.
     * This method corresponds to the database table user
     *
     * @mbggenerated
     */
    @Update({
        "update user",
        "set username = #{username,jdbcType=VARCHAR},",
          "password = #{password,jdbcType=VARCHAR},",
          "sex = #{sex,jdbcType=VARCHAR},",
          "mail = #{mail,jdbcType=VARCHAR},",
          "status = #{status,jdbcType=INTEGER}",
        "where id = #{id,jdbcType=INTEGER}"
    })
    int updateByPrimaryKey(User record);


    /*@function:查詢全部的用戶信息
    @param:void
    * */
    List<User> queryUsers();
}

6 service層

package com.wyn.app.service;

import com.wyn.app.entity.User;

import java.util.List;

/**
 * Created by wangyanan on 2017/9/27.
 */
public interface UserService {
    public boolean insertUser(User user);
    //查詢全部的用戶信息
    public List<User> queryAllUser();
}

7 serviceImp層

package com.wyn.app.serviceImp;

import com.wyn.app.dao.UserMapper;
import com.wyn.app.entity.User;
import com.wyn.app.service.UserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;

/**
 * Created by wangyanan on 2017/9/27.
 */
@Service
public class UserServiceImp implements UserService {
    @Resource
    UserMapper userMapper;

    public UserMapper getUserMapper() {
        return userMapper;
    }

    public void setUserMapper(UserMapper userMapper) {
        this.userMapper = userMapper;
    }

    public boolean insertUser(User user) {
        boolean flag=true;
        int a=userMapper.insertSelective(user);
        System.out.println("插入"+a+"數據");
        if(a==0){
            flag=false;
        }
        return flag;
    }

    @Override
    public List<User> queryAllUser() {
        return userMapper.queryUsers();
    }
}

8 controller層

package com.wyn.app.controller;

import com.wyn.app.entity.User;
import com.wyn.app.service.UserService;
import com.wyn.app.utils.BaseController;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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 javax.servlet.http.HttpServletResponse;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by wangyanan on 2017/9/27.
 */
@Controller
@RequestMapping("test")
public class DemoController extends BaseController {

    @Autowired
    @Qualifier(value = "userServiceImp")
    UserService userService;

   /* private static Logger logger = LoggerFactory.getLogger(DemoController.class);*/
    ThreadLocal<String> msg=new ThreadLocal<String> ();

    @RequestMapping(value = "/save.do",method = RequestMethod.GET)
    public void save(HttpServletResponse response){
        /*logger.info("debugger記錄:插入數據");*/
        boolean flag=true;
        try {
            User user=new User();
            user.setUsername("王亞南");
            int b= (int) (Math.random()*10000);
            System.out.println("隨機主鍵"+b);
            user.setId(b);
            flag=userService.insertUser(user);
            response.setCharacterEncoding("UTF-8");
            if (flag){
                response.getWriter().write("成功!");
            }else{
                response.getWriter().write("失敗");
            }
        }catch(Exception e){
            System.out.println("程序異常");
            e.printStackTrace();
        }
    }

    @RequestMapping(value = "/all",method = RequestMethod.GET)
    public String showUser(Model model){
        ModelAndView mav=new ModelAndView();
        List<User> userList=new ArrayList<User>();
        userList=userService.queryAllUser();
        model.addAttribute("userList",userList);
        return "main";
    }
}

9 sqlmap映射文件層

<?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.wyn.app.dao.UserMapper" >
  <resultMap id="BaseResultMap" type="com.wyn.app.entity.User" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    <id column="id" property="id" jdbcType="INTEGER" />
    <result column="username" property="username" jdbcType="VARCHAR" />
    <result column="password" property="password" jdbcType="VARCHAR" />
    <result column="sex" property="sex" jdbcType="VARCHAR" />
    <result column="mail" property="mail" jdbcType="VARCHAR" />
    <result column="status" property="status" jdbcType="INTEGER" />
  </resultMap>
  <sql id="Base_Column_List" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    id, username, password, sex, mail, status
  </sql>

  <!-- 引入自定義緩存類實現cache接口 ,放在所有語句的前方-->
  <cache type="com.wyn.app.utils.RedisCache"/>

  <select id="queryUsers" resultMap="BaseResultMap">
      SELECT * FROM USER
  </select>
  <insert id="insertSelective" parameterType="com.wyn.app.entity.User" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    insert into user
    <trim prefix="(" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        id,
      </if>
      <if test="username != null" >
        username,
      </if>
      <if test="password != null" >
        password,
      </if>
      <if test="sex != null" >
        sex,
      </if>
      <if test="mail != null" >
        mail,
      </if>
      <if test="status != null" >
        status,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides="," >
      <if test="id != null" >
        #{id,jdbcType=INTEGER},
      </if>
      <if test="username != null" >
        #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="sex != null" >
        #{sex,jdbcType=VARCHAR},
      </if>
      <if test="mail != null" >
        #{mail,jdbcType=VARCHAR},
      </if>
      <if test="status != null" >
        #{status,jdbcType=INTEGER},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="com.wyn.app.entity.User" >
    <!--
      WARNING - @mbggenerated
      This element is automatically generated by MyBatis Generator, do not modify.
    -->
    update user
    <set >
      <if test="username != null" >
        username = #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null" >
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="sex != null" >
        sex = #{sex,jdbcType=VARCHAR},
      </if>
      <if test="mail != null" >
        mail = #{mail,jdbcType=VARCHAR},
      </if>
      <if test="status != null" >
        status = #{status,jdbcType=INTEGER},
      </if>
    </set>
    where id = #{id,jdbcType=INTEGER}
  </update>
</mapper>

以上爲基本的springMVC+mybatis配置
下面進行redis的配置
10 配置redis所需的工具
這裏寫圖片描述
11 JedisUtils.java

package com.wyn.app.utils;

import org.mybatis.caches.redis.SerializeUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;

/**
 * Created by wangyanan on 2017/9/28.
 */
public class JedisUtils {
    private static Logger logger= LoggerFactory.getLogger(JedisUtils.class);

    private static JedisPool JEDISPOOL;

    public static void getInstence(){
        if(JEDISPOOL == null){
            logger.info("JeidsUtils getInstence...");
            try {
                JedisPoolConfig conf=new JedisPoolConfig();
                conf.setMaxIdle(ConfigUtils.maxIdle);
                conf.setTestOnBorrow(ConfigUtils.testOnBorrow);
                //當配置中配置有password時,則創建帶密碼的緩存池
                if(ConfigUtils.password !=null && !"".equals(ConfigUtils.password)){
                    JEDISPOOL=new JedisPool(conf,ConfigUtils.ip,ConfigUtils.port,ConfigUtils.timeout,ConfigUtils.password);
                }else{
                    //沒有配置則用無密碼的緩存池。
                    JEDISPOOL=new JedisPool(conf,ConfigUtils.ip,ConfigUtils.port,ConfigUtils.timeout);
                }
            } catch (Exception e) {
                logger.error("加載【jedis.properties】異常,異常信息爲:"+e.getMessage());
            }
        }
    }

    public static Jedis getJedis(){
        try {
            return JEDISPOOL.getResource();
        } catch (Exception e) {
            return null;
        }
    }

    public static void closeJedis(Jedis jedis){
        if(jedis !=null){
            jedis.close();
        }
    }

    public static void closeJedisPool(){
        if(JEDISPOOL !=null){
            System.out.println("關閉連接");
        }
    }
    //redis 序列化存儲Object
    public static void put(String id,Object key,Object value){
        Jedis jedis=getJedis();
        logger.info("redis put ... key =["+key+"]");
        try {
            jedis.hset(SerializeUtil.serialize(id), SerializeUtil.serialize(key), SerializeUtil.serialize(value));
            ConfigUtils.setSucc();
        } catch (Exception e) {
            ConfigUtils.setFail();
            logger.error("redis執行異常【"+e.getMessage()+"】");
        }finally{
            closeJedis(jedis);
        }
    }


    public static Object get(String id,Object key){
        Jedis jedis=getJedis();
        try {
            Object object = SerializeUtil.unserialize(jedis.hget(SerializeUtil.serialize(id), SerializeUtil.serialize(key)));
            logger.info("redis get ... key=["+key+"],value=["+object+"]");
            ConfigUtils.setSucc();
            return object;
        } catch (Exception e) {
            ConfigUtils.setFail();
            logger.error("Redis執行異常【"+e.getMessage()+"】");
        }finally{
            closeJedis(jedis);
        }

        return null;
    }


    public static Long remove(String id,Object key){
        Jedis jedis=getJedis();
        try {
            Long num = jedis.hdel(id.toString(), key.toString());
            ConfigUtils.setSucc();
            return num;
        } catch (Exception e) {
            ConfigUtils.setFail();
            logger.error("Redis執行異常,異常信息:"+e.getMessage());
        }finally{
            closeJedis(jedis);
        }

        return 0l;
    }

    public static void removeAll(String id){
        Jedis jedis=getJedis();
        try {
            jedis.del(id.toString());
            ConfigUtils.setSucc();
        } catch (Exception e) {
            ConfigUtils.setFail();
            logger.error("Redis執行異常【"+e.getMessage()+"】");
        }finally{
            closeJedis(jedis);
        }
    }


    public static int getSize(String id){
        Jedis jedis=getJedis();

        try {
            return  jedis.hgetAll(SerializeUtil.serialize(id)).size();
        } catch (Exception e) {
            ConfigUtils.setFail();
            logger.error("Redis執行異常【"+e.getMessage()+"】");
        }finally{
            closeJedis(jedis);
        }
        return -1;
    }
}

12 ConfigUtils.java

package com.wyn.app.utils;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.Properties;

/**
 * Created by wangyanan on 2017/9/28.
 */
public class ConfigUtils {
    private static Logger logger= LoggerFactory.getLogger(ConfigUtils.class);

    public static boolean redisSwitch;
    public static int maxIdle;
    public static boolean testOnBorrow;
    public static boolean testOnReturn;
    public static String ip;
    public static int port;
    public static String key;
    public static String password;
    public static int timeout;
    public static int fail_count=0;

    static{
        Properties props=new Properties();
        try {
            props.load(JedisUtils.class.getResourceAsStream("redis.properties"));

            redisSwitch=Boolean.valueOf(props.getProperty("redis.switch"));
            maxIdle=Integer.valueOf(props.getProperty("jedis.pool.maxIdle"));
            testOnBorrow=Boolean.valueOf(props.getProperty("jedis.pool.testOnBorrow"));
            testOnReturn=Boolean.valueOf(props.getProperty("jedis.pool.testOnReturn"));
            ip=String.valueOf(props.getProperty("redis.ip"));
            port=Integer.valueOf(props.getProperty("redis.port"));
            password=String.valueOf(props.getProperty("redis.password"));
            key=String.valueOf(props.getProperty("redis.key"));
            timeout=Integer.valueOf(props.getProperty("jedis.pool.timeout"));
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

    }
    //對redis開關進行設置,有三種情況:1.如果現在開關開,則關閉redispool  2.如果開關關閉,則設置redispool爲開啓狀態  3.現在狀態和要設置的狀態一致,不做操作。
    public static void setSwitch(boolean redisSwitch){
        if(true==ConfigUtils.redisSwitch && false== redisSwitch){
            logger.info("switch:open-->close");
            JedisUtils.closeJedisPool();
        }else if(ConfigUtils.redisSwitch==false && true == redisSwitch){
            logger.info("switch:close-->open");
            JedisUtils.getInstence();
        }
        ConfigUtils.redisSwitch=redisSwitch;
    }
    //當redis連接異常超過一定數量之後,不再走redis,但是沒有一個機制,當reids恢復後重新使用redis
    public static void setFail(){
        if(redisSwitch){
            fail_count=fail_count+1;

            if(fail_count >10){
                logger.info("setSwitch(false)");
                setSwitch(false);
            }
        }
    }

    public static void setSucc(){
        if(fail_count >0){
            fail_count=0;
        }
        if(!redisSwitch){
            setSwitch(true);
        }
    }
}

13 RedisCache.java

package com.wyn.app.utils;

import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

/**
 * Created by wangyanan on 2017/9/28.
 */
public class RedisCache implements Cache {
    private static Logger logger = LoggerFactory.getLogger(RedisCache.class);

    private String cacheId;
    /**
     * 讀寫鎖:分爲讀鎖和寫鎖,多個讀鎖不互斥,讀鎖與寫鎖互斥,這是由jvm自己控制的,你只要上好相應的鎖即可。如果你的代碼只讀數據,可以很多人
     * 同時讀,但不能同時寫,那就上讀鎖;如果你的代碼修改數據,只能有一個人在寫,且不能同時讀取,那就上寫鎖。總之,讀的時候上讀鎖,寫的時候上
     * 寫鎖!
     */
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock(true);
    private final Lock read = readWriteLock.readLock();
    private final Lock write = readWriteLock.writeLock();

    public RedisCache(String cacheId) {
        if (cacheId == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        this.cacheId = ConfigUtils.key + "." + cacheId;
        logger.info("查詢結果存入緩存對應的緩存空間生成的名字cacheId: " + this.cacheId);

        if (ConfigUtils.redisSwitch) {
            JedisUtils.getInstence();
        }
    }

    @Override
    public String getId() {
        return cacheId;
    }

    @Override
    public void putObject(Object key, Object value) {
        // TODO 從緩存中寫數據,用寫鎖鎖定,不允許讀
        logger.info("NTSRedisCache putObject=" + cacheId);
        if (ConfigUtils.redisSwitch) {
            write.lock();
            try {
                JedisUtils.put(cacheId, key, value);
            } finally {
                write.unlock();
            }

        }
    }

    @Override
    public Object getObject(Object key) {
        // TODO 從緩存中讀數據,用讀鎖鎖定,不允許寫
        logger.info("從緩存cacheId="+cacheId+"中拿數據key="+key+"對應的value");
        if (ConfigUtils.redisSwitch) {
            read.lock();
            try {
                return JedisUtils.get(cacheId, key);
            } finally {
                read.unlock();
            }
        }
        return null;
    }

    @Override
    public Object removeObject(Object key) {
        // TODO 從緩存中改動數據,用寫鎖鎖定,不允許讀,改動結束後釋放寫鎖。
        logger.info("NTSRedisCache clear =" + cacheId);
        if (ConfigUtils.redisSwitch) {
            write.lock();
            try {
                return JedisUtils.remove(cacheId, key);
            } finally {
                write.unlock();
            }
        }
        return null;
    }

    @Override
    public void clear() {
        // TODO  從緩存中改動數據,用寫鎖鎖定,不允許讀,改動結束後釋放寫鎖。
        logger.info("NTSRedisCache clear =" + cacheId);
        if (ConfigUtils.redisSwitch) {
            write.lock();
            try {
                JedisUtils.removeAll(cacheId);
            } finally {
                write.unlock();
            }
        }
    }

    @Override
    public int getSize() {
        // TODO Auto-generated method stub
        logger.info("NTSRedisCache clear =" + cacheId);
        if (ConfigUtils.redisSwitch) {
            read.lock();
            try {
                return JedisUtils.getSize(cacheId);
            } finally {
                read.unlock();
            }
        }
        return -1;
    }

    @Override
    public ReadWriteLock getReadWriteLock() {
        return readWriteLock;
    }
}

14 redis.properties

redis.ip=192.168.1.50
redis.port=6379
redis.key=SOA
redis.password=
#是否啓用redis?true啓用,false不啓用。
redis.switch=true

jedis.pool.maxActive=3000
jedis.pool.maxIdle=1000
jedis.pool.maxWait=1500
jedis.pool.testOnBorrow=true
jedis.pool.testOnReturn=true
jedis.pool.timeout=5000

15 運行結果
緩存實現:
這裏寫圖片描述
去除緩存(即去除 cache type=”com.wyn.app.utils.RedisCache”)後的實現結果:
這裏寫圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章