前期准备
(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" /> <!– JSON转换器 –>
</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&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”)后的实现结果: