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”)后的实现结果:
这里写图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值