一.创建工程
1.创建一个maven项目工程
2.创建项目目录
3.引入项目所需要的依赖
<dependencies>
<!-- spring框架 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-aspects</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
</dependency>
<!-- 数据源 -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.3.1</version>
</dependency>
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>1.2.4</version>
</dependency>
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.5</version>
</dependency>
<!-- jsp -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
<!-- 日志组件 -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.25</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-access</artifactId>
<version>1.2.3</version>
</dependency>
<!-- json -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.7.2</version>
</dependency>
<dependency>
<groupId>org.codehaus.jackson</groupId>
<artifactId>jackson-mapper-asl</artifactId>
<version>1.9.13</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.47</version>
</dependency>
<!-- lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.2</version>
<scope>provided</scope>
</dependency>
<!-- httpClient -->
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
<!--redis-->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>1.6.2.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/redis.clients/jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.7.3</version>
</dependency>
</dependencies>
4.部署tomcat并启动项目
5.安装mybatis-plugin以及lombok
https://blog.csdn.net/u010286027/article/details/85853659
二.SSM的小demo
1.添加spring配置(applicationContext-dao.xml)
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd">
<!-- 1.扫描service包 -->
<context:component-scan base-package="com.ssmApp" />
<!-- 2.配置数据源(c3p0数据库连接池) -->
<!-- 加载db.properties -->
<context:property-placeholder location="classpath:db.properties" />
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<!-- 基础配置 -->
<property name="jdbcUrl" value="${jdbc.url}"/>
<property name="driverClass" value="${jdbc.driver}"/>
<property name="user" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>
<!-- 3.配置sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<!-- 加载数据源 -->
<property name="dataSource" ref="dataSource" />
<!-- 加载mybatis的全局配置文件 -->
<property name="configLocation" value="classpath:mybatis/mybatis.xml" />
<!--设置映射文件位置-->
<property name="mapperLocations" value="classpath:mybatis/mappers/*.xml"/>
</bean>
<!-- 4.配置mapper扫描器 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<!-- 扫描包路径(如果需要扫描多个包,中间使用半角逗号隔开) -->
<property name="basePackage" value="com.ssmApp.dao.mapper"/>
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>
</beans>
2.添加springMVC配置
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!-- 1.配置处理器,可以扫描controller、service、... 这里让扫描controller,指定controller的包 -->
<context:annotation-config />
<context:component-scan base-package="com.ssmApp.controller"/>
<!-- 2.配置处理器适配器和映射器
使用mvc:annotation-driven代替上边注解映射器和注解适配器配置
mvc:annotation-driven默认加载很多的参数绑定方法,
比如json转换解析器就默认加载了,如果使用mvc:annotation-driven就不用配置上边的
RequestMappingHandlerMapping和RequestMappingHandlerAdapter
实际开发时使用mvc:annotation-driven -->
<mvc:annotation-driven conversion-service="conversionService"></mvc:annotation-driven>
</beans>
3.添加mybatis配置
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置别名 -->
<typeAliases>
<!-- 批量扫描别名 -->
<package name="com.ssmApp.dao.po"/>
</typeAliases>
</configuration>
4.添加web.xml配置
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<!-- 启动Web容器时,加载spring容器,自动装配ApplicationContext.xml的配置信息 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/applicationContext-*.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 加载springmvc配置文件 -->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/springmvc.xml</param-value>
</init-param>
</servlet>
<!-- 配置将所有请求交给springmvc来处理 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
5.添加数据库配置文件,服务端通用返回对象
6.controller层
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
UserImpl userImpl;
/**
* @description 根据用户id获取用户详细信息
* @param user
* @return User
**/
@RequestMapping(value = "/getDetail",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<User> getDetail(@RequestBody User user){
return userImpl.getDetail(user);
}
}
7.service层
public interface IUser {
ServerResponse<User> getDetail(User user);
}
@Service
public class UserImpl implements IUser {
@Autowired
UserMapper userMapper;
/**
* @description 根据用户id获取用户详细信息
* @param user
* @return User
**/
@Override
public ServerResponse getDetail(User user) {
User customer = userMapper.selectByPrimaryKey(user.getId());
if(customer == null){
return ServerResponse.createByErrorMessage("查询个人详细信息失败");
}
return ServerResponse.createBySuccess("查询个人详细信息成功",customer);
}
}
8.dao层
@Data
@NoArgsConstructor
@AllArgsConstructor
@ToString
public class User {
private String id;
private String nickName;
private String avatar;
private String signature;
private Integer point;
private Integer coin;
private Date createTime;
private Date updateTime;
}
public interface UserMapper {
User selectByPrimaryKey(String id);
}
<?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.ssmApp.dao.mapper.UserMapper">
<resultMap id="BaseResultMap" type="User">
<constructor>
<idArg column="id" javaType="String" jdbcType="VARCHAR" />
<arg column="nick_name" javaType="String" jdbcType="VARCHAR" />
<arg column="avatar" javaType="String" jdbcType="VARCHAR" />
<arg column="signature" javaType="String" jdbcType="VARCHAR" />
<arg column="point" javaType="Integer" jdbcType="INTEGER" />
<arg column="coin" javaType="Integer" jdbcType="INTEGER" />
<arg column="create_time" javaType="Date" jdbcType="TIMESTAMP" />
<arg column="update_time" javaType="Date" jdbcType="TIMESTAMP" />
</constructor>
</resultMap>
<sql id="Base_Column_List">
id, nick_name, avatar, signature, point, coin, create_time, update_time
</sql>
<select id="selectByPrimaryKey" parameterType="String" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where id = #{id,jdbcType=VARCHAR}
</select>
</mapper>
三.Spring的定时任务
1.在spring的主配置文件中添加约束和配置
xmlns:task="http://www.springframework.org/schema/task"
http://www.springframework.org/schema/task
http://www.springframework.org/schema/task/spring-task-3.2.xsd
<!-- 5.配置scheduler定时任务 -->
<task:annotation-driven/>
<task:scheduler id="myScheduler" pool-size="10"/>
2.demo
@Component
public class MyFirstSpringJob {
//每隔一分钟执行一次
@Scheduled(cron = "0 * * * * ?")
public void run() {
System.out.println("MyFirstSpringJob......");
}
}
@Component
public class MySecondSpringJob {
//逢每分钟的第3秒执行一次
@Scheduled(cron = "3 * * * * ?")
public void run() {
System.out.println("MySecondSpringJob......");
}
}
四.日志组件logback和全局异常处理
1.添加依赖
2.配置logback.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds" debug="false">
<!-- 滚动记录文件,先将日志记录到指定文件,当符合某个条件时,将日志记录到其他文件 -->
<appender name="info" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 日志记录的文件名 -->
<File>/Users/steven/Documents/logs/topicBet.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- 文件命令格式 -->
<fileNamePattern>/Users/steven/Documents/logs/topicBet.log.%d{yyyy-MM-dd}.gz</fileNamePattern>
<!-- 是否将日志追加到文件结尾 -->
<append>true</append>
<!-- 最大存储日期,单位天 -->
<maxHistory>10</maxHistory>
</rollingPolicy>
<!-- 日志的实际格式 -->
<encoder>
<pattern>[%d{HH:mm:ss.SSS}][%p][%c{40}][%t] %m%n</pattern>
</encoder>
</appender>
<!-- 错误级别的日志 -->
<appender name="error" class="ch.qos.logback.core.rolling.RollingFileAppender">
<File>/Users/steven/Documents/logs/error.log</File>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>/Users/steven/Documents/logs/error.log.%d{yyyy-MM-dd}.gz</fileNamePattern>
<append>true</append>
<maxHistory>10</maxHistory>
</rollingPolicy>
<encoder>
<pattern>[%d{HH:mm:ss.SSS}][%p][%c{40}][%t] %m%n</pattern>
</encoder>
<filter class="ch.qos.logback.classic.filter.LevelFilter">
<!-- 级别过滤器 -->
<level>ERROR</level>
<!--根据记录级别对记录事件进行过滤。如果事件的级别等于配置的级别,过滤器会根据onMatch和onMismatch属性接受或拒绝事件 -->
<onMatch>ACCEPT</onMatch>
<onMismatch>DENY</onMismatch>
</filter>
</appender>
<!-- info级别的日志,additivity不向上级logger传递打印信息 -->
<!-- 大于等于INFO级别的日志会被日志记录器记录 -->
<logger name="com.ssmApp" additivity="false" level="INFO">
<!--<appender-ref ref="console"/>-->
<appender-ref ref="info"/>
<appender-ref ref="error"/>
</logger>
<root level="DEBUG">
</root>
</configuration>
3.全局异常处理类
@Slf4j
@Component
public class ExceptionResolver implements HandlerExceptionResolver {
@Override
public ModelAndView resolveException(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Object o, Exception e) {
log.error("{} exception",httpServletRequest.getRequestURI(),e);
ModelAndView modelAndView = new ModelAndView(new MappingJackson2JsonView());
modelAndView.addObject("status",ResponseCode.ERROR.getCode());
modelAndView.addObject("message","接口异常,请联系客服人员!");
modelAndView.addObject("data",e.toString());
return modelAndView;
}
}
4.测试
@Controller
@RequestMapping("/user")
public class UserController {
@Autowired
UserImpl userImpl;
/**
* @description 根据用户id获取用户详细信息
* @param user
* @return User
**/
@RequestMapping(value = "/getDetail",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<User> getDetail(@RequestBody User user){
int i = 1/0;
return userImpl.getDetail(user);
}
}
五.HttpClient
1.添加jar包
<dependency>
<groupId>org.apache.httpcomponents</groupId>
<artifactId>httpclient</artifactId>
<version>4.5.2</version>
</dependency>
2.spring配置(applicationContext-httpclient.xml)
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">
<!--定义连接管理器 -->
<bean id="connectionManager"
class="org.apache.http.impl.conn.PoolingHttpClientConnectionManager"
destroy-method="close">
<!-- 最大连接数 -->
<property name="maxTotal" value="500" />
<!--设置每个主机最大的并发数 -->
<property name="defaultMaxPerRoute" value="100" />
</bean>
<!--定义HttpClient构建器 -->
<bean id="httpClientBuilder" class="org.apache.http.impl.client.HttpClientBuilder"
factory-method="create">
<property name="connectionManager" ref="connectionManager" />
</bean>
<!--定义httpClient对象,该bean一定是多例的 -->
<bean id="httpClient" class="org.apache.http.impl.client.CloseableHttpClient"
factory-bean="httpClientBuilder" factory-method="build" scope="prototype"></bean>
<!--定义requestConfig构建器 -->
<bean id="requestConfigBuilder" class="org.apache.http.client.config.RequestConfig.Builder">
<!--设置创建连接的最长时间 -->
<property name="connectTimeout" value="2000" />
<!--从连接池中获取到连接的最长时间 -->
<property name="connectionRequestTimeout" value="500" />
<!--数据传输的最长时间 -->
<property name="socketTimeout" value="6000" />
</bean>
<!--请求参数对象 -->
<bean class="org.apache.http.client.config.RequestConfig"
factory-bean="requestConfigBuilder" factory-method="build"></bean>
<!--定期清理无效连接 -->
<bean class="org.apache.http.impl.client.IdleConnectionEvictor"
destroy-method="shutdown">
<constructor-arg index="0" ref="connectionManager" />
<constructor-arg index="1" value="1" />
<constructor-arg index="2" value="MINUTES" />
</bean>
</beans>
3.HttpClientService
package com.topicBet.service.impl;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class HttpClientService
{
@Autowired
private CloseableHttpClient httpClient;
@Autowired
private RequestConfig requestConfig;
/**
* @Title: doGet
* @Description: 执行get请求,200返回响应内容,其他状态码返回null
* @param url 请求地址
* @return
* @throws IOException
* @throws
*/
public String doGet(String url) throws IOException
{
//创建httpClient对象
CloseableHttpResponse response = null;
HttpGet httpGet = new HttpGet(url);
//设置请求参数
httpGet.setConfig(requestConfig);
try
{
//执行请求
response = httpClient.execute(httpGet);
//判断返回状态码是否为200
if (response.getStatusLine().getStatusCode() == 200)
{
return EntityUtils.toString(response.getEntity(), "UTF-8");
}
}
finally
{
if (response != null)
{
response.close();
}
}
return null;
}
//POST请求
public String doPost(String url, Map<String, Object> paramsMap){
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().
setConnectTimeout(180 * 1000).setConnectionRequestTimeout(180 * 1000)
.setSocketTimeout(180 * 1000).setRedirectsEnabled(true).build();
httpPost.setConfig(requestConfig);
httpPost.addHeader("Content-Type", "application/x-www-form-urlencoded");
List<NameValuePair> nvp = new ArrayList<NameValuePair>();
for (String key : paramsMap.keySet()) {
nvp.add(new BasicNameValuePair(key, String.valueOf(paramsMap.get(key))));
}
try {
httpPost.setEntity(new UrlEncodedFormEntity(nvp, "UTF-8"));
HttpResponse response = httpClient.execute(httpPost);
String strResult = "";
if (response.getStatusLine().getStatusCode() == 200) {
strResult = EntityUtils.toString(response.getEntity());
return strResult;
} else {
return "Error Response: " + response.getStatusLine().toString();
}
} catch (Exception e) {
e.printStackTrace();
return "post failure :caused by-->" + e.getMessage().toString();
}finally {
if(null != httpClient){
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//POST请求,参数是json字符串
public String doPostForJson(String url, String jsonParams){
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().
setConnectTimeout(180 * 1000).setConnectionRequestTimeout(180 * 1000)
.setSocketTimeout(180 * 1000).setRedirectsEnabled(true).build();
httpPost.setConfig(requestConfig);
httpPost.setHeader("Content-Type","application/json");
try {
httpPost.setEntity(new StringEntity(jsonParams, ContentType.create("application/json", "utf-8")));
HttpResponse response = httpClient.execute(httpPost);
String strResult = "";
if (response.getStatusLine().getStatusCode() == 200) {
strResult = EntityUtils.toString(response.getEntity());
return strResult;
} else {
return "Error Response: " + response.getStatusLine().toString();
}
} catch (Exception e) {
e.printStackTrace();
return "post failure :caused by-->" + e.getMessage().toString();
}finally {
if(null != httpClient){
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
//POST请求,参数是xml字符串
public String doPostForXml(String url, String xmlParams){
CloseableHttpClient httpClient = HttpClients.createDefault();
HttpPost httpPost = new HttpPost(url);
RequestConfig requestConfig = RequestConfig.custom().
setConnectTimeout(180 * 1000).setConnectionRequestTimeout(180 * 1000)
.setSocketTimeout(180 * 1000).setRedirectsEnabled(true).build();
httpPost.setConfig(requestConfig);
httpPost.setHeader("Content-Type","application/xml");
try {
httpPost.setEntity(new StringEntity(xmlParams, ContentType.create("application/xml", "utf-8")));
HttpResponse response = httpClient.execute(httpPost);
String strResult = "";
if (response.getStatusLine().getStatusCode() == 200) {
strResult = EntityUtils.toString(response.getEntity());
return strResult;
} else {
return "Error Response: " + response.getStatusLine().toString();
}
} catch (Exception e) {
e.printStackTrace();
return "post failure :caused by-->" + e.getMessage().toString();
}finally {
if(null != httpClient){
try {
httpClient.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
4.使用案例
/**
* @description 根据用户id获取用户详细信息
* @param user
* @return User
**/
@RequestMapping(value = "/getDetail",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<User> getDetail(@RequestBody User user){
String param = "{\n" +
"\t\"id\":\"oZh8a0be94UHLQnsTNz0DHUj380E\"\n" +
"}";
String str = httpClientService.doPostForJson("https://www.leichuangkj.com/topicBet/user/getDetail",param);
System.out.println(str);
return userImpl.getDetail(user);
}
六.redis
1.引入依赖
2.配置
redis.maxTotal=10
redis.maxIdle=5
redis.maxWaitMillis=2000
redis.testOnBorrow=true
redis.host=127.0.0.1
redis.port=6379
redis.password=admin123
redis.timeout=0
redis.testWhileIdle=true
redis.timeBetweenEvictionRunsMillis=30000
redis.numTestsPerEvictionRun=50
<!-- 6.配置redis -->
<bean id="annotationPropertyConfigurerRedis"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="order" value="1" />
<property name="ignoreUnresolvablePlaceholders" value="true" />
<property name="locations">
<list>
<value>classpath:redis.properties</value>
</list>
</property>
</bean>
<!-- redis数据源 -->
<bean id="poolConfig" class="redis.clients.jedis.JedisPoolConfig">
<!-- 最大空闲数 -->
<property name="maxIdle" value="${redis.maxIdle}" />
<!-- 最大空连接数 -->
<property name="maxTotal" value="${redis.maxTotal}" />
<!-- 最大等待时间 -->
<property name="maxWaitMillis" value="${redis.maxWaitMillis}" />
<!-- 返回连接时,检测连接是否成功 -->
<property name="testOnBorrow" value="${redis.testOnBorrow}" />
</bean>
<!-- Spring-redis连接池管理工厂 -->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<!-- IP地址 -->
<property name="hostName" value="${redis.host}" />
<!-- 端口号 -->
<property name="port" value="${redis.port}" />
<property name="password" value="${redis.password}" />
<!-- 超时时间 默认2000-->
<property name="timeout" value="${redis.timeout}" />
<!-- 连接池配置引用 -->
<property name="poolConfig" ref="poolConfig" />
<!-- usePool:是否使用连接池 -->
<property name="usePool" value="true"/>
</bean>
<!-- redis template definition -->
<bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate">
<property name="connectionFactory" ref="jedisConnectionFactory" />
<property name="keySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="valueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<property name="hashKeySerializer">
<bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
</property>
<property name="hashValueSerializer">
<bean class="org.springframework.data.redis.serializer.JdkSerializationRedisSerializer" />
</property>
<!--开启事务 -->
<property name="enableTransactionSupport" value="true"></property>
</bean>
<!--自定义redis工具类,在需要缓存的地方注入此类 -->
<bean id="redisService" class="com.ssmApp.service.impl.RedisService">
<constructor-arg name="redisTemplate" ref="redisTemplate" />
</bean>
3.RedisService
@Service
public class RedisService {
private final RedisTemplate<String, Object> redisTemplate;
public RedisService(RedisTemplate<String, Object> redisTemplate) {
this.redisTemplate = redisTemplate;
}
//=============================common============================
/**
* 指定缓存失效时间
* @param key 键
* @param time 时间(秒)
* @return
*/
public boolean expire(String key,long time){
try {
if(time>0){
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据key 获取过期时间
* @param key 键 不能为null
* @return 时间(秒) 返回0代表为永久有效
*/
public long getExpire(String key){
return redisTemplate.getExpire(key,TimeUnit.SECONDS);
}
/**
* 判断key是否存在
* @param key 键
* @return true 存在 false不存在
*/
public boolean hasKey(String key){
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除缓存
* @param key 可以传一个值 或多个
*/
@SuppressWarnings("unchecked")
public void del(String ... key){
if(key!=null&&key.length>0){
if(key.length==1){
redisTemplate.delete(key[0]);
}else{
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
//============================String=============================
/**
* 普通缓存获取
* @param key 键
* @return 值
*/
public Object get(String key){
return key==null?null:redisTemplate.opsForValue().get(key);
}
/**
* 普通缓存放入
* @param key 键
* @param value 值
* @return true成功 false失败
*/
public boolean set(String key,Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通缓存放入并设置时间
* @param key 键
* @param value 值
* @param time 时间(秒) time要大于0 如果time小于等于0 将设置无限期
* @return true成功 false 失败
*/
public boolean set(String key,Object value,long time){
try {
if(time>0){
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
}else{
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 递增
* @param key 键
* @return
*/
public long incr(String key, long delta){
if(delta<0){
throw new RuntimeException("递增因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 递减
* @param key 键
* @return
*/
public long decr(String key, long delta){
if(delta<0){
throw new RuntimeException("递减因子必须大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
//================================Map=================================
/**
* HashGet
* @param key 键 不能为null
* @param item 项 不能为null
* @return 值
*/
public Object hget(String key,String item){
return redisTemplate.opsForHash().get(key, item);
}
/**
* 获取hashKey对应的所有键值
* @param key 键
* @return 对应的多个键值
*/
public Map<Object,Object> hmget(String key){
return redisTemplate.opsForHash().entries(key);
}
/**
* HashSet
* @param key 键
* @param map 对应多个键值
* @return true 成功 false 失败
*/
public boolean hmset(String key, Map<String,Object> map){
try {
redisTemplate.opsForHash().putAll(key, map);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* HashSet 并设置时间
* @param key 键
* @param map 对应多个键值
* @param time 时间(秒)
* @return true成功 false失败
*/
public boolean hmset(String key, Map<String,Object> map, long time){
try {
redisTemplate.opsForHash().putAll(key, map);
if(time>0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @return true 成功 false失败
*/
public boolean hset(String key,String item,Object value) {
try {
redisTemplate.opsForHash().put(key, item, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 向一张hash表中放入数据,如果不存在将创建
* @param key 键
* @param item 项
* @param value 值
* @param time 时间(秒) 注意:如果已存在的hash表有时间,这里将会替换原有的时间
* @return true 成功 false失败
*/
public boolean hset(String key,String item,Object value,long time) {
try {
redisTemplate.opsForHash().put(key, item, value);
if(time>0){
expire(key, time);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 删除hash表中的值
* @param key 键 不能为null
* @param item 项 可以使多个 不能为null
*/
public void hdel(String key, Object... item){
redisTemplate.opsForHash().delete(key,item);
}
/**
* 判断hash表中是否有该项的值
* @param key 键 不能为null
* @param item 项 不能为null
* @return true 存在 false不存在
*/
public boolean hHasKey(String key, String item){
return redisTemplate.opsForHash().hasKey(key, item);
}
/**
* hash递增 如果不存在,就会创建一个 并把新增后的值返回
* @param key 键
* @param item 项
* @param by 要增加几(大于0)
* @return
*/
public double hincr(String key, String item,double by){
return redisTemplate.opsForHash().increment(key, item, by);
}
/**
* hash递减
* @param key 键
* @param item 项
* @param by 要减少记(小于0)
* @return
*/
public double hdecr(String key, String item,double by){
return redisTemplate.opsForHash().increment(key, item,-by);
}
//============================set=============================
/**
* 根据key获取Set中的所有值
* @param key 键
* @return
*/
public Set<Object> sGet(String key){
try {
return redisTemplate.opsForSet().members(key);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 根据value从一个set中查询,是否存在
* @param key 键
* @param value 值
* @return true 存在 false不存在
*/
public boolean sHasKey(String key,Object value){
try {
return redisTemplate.opsForSet().isMember(key, value);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将数据放入set缓存
* @param key 键
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSet(String key, Object...values) {
try {
return redisTemplate.opsForSet().add(key, values);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 将set数据放入缓存
* @param key 键
* @param time 时间(秒)
* @param values 值 可以是多个
* @return 成功个数
*/
public long sSetAndTime(String key,long time,Object...values) {
try {
Long count = redisTemplate.opsForSet().add(key, values);
if(time>0) expire(key, time);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 获取set缓存的长度
* @param key 键
* @return
*/
public long sGetSetSize(String key){
try {
return redisTemplate.opsForSet().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 移除值为value的
* @param key 键
* @param values 值 可以是多个
* @return 移除的个数
*/
public long setRemove(String key, Object ...values) {
try {
Long count = redisTemplate.opsForSet().remove(key, values);
return count;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
//===============================list=================================
/**
* 获取list缓存的内容
* @param key 键
* @param start 开始
* @param end 结束 0 到 -1代表所有值
* @return
*/
public List<Object> lGet(String key,long start, long end){
try {
return redisTemplate.opsForList().range(key, start, end);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 获取list缓存的长度
* @param key 键
* @return
*/
public long lGetListSize(String key){
try {
return redisTemplate.opsForList().size(key);
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
/**
* 通过索引 获取list中的值
* @param key 键
* @param index 索引 index>=0时, 0 表头,1 第二个元素,依次类推;index<0时,-1,表尾,-2倒数第二个元素,依次类推
* @return
*/
public Object lGetIndex(String key,long index){
try {
return redisTemplate.opsForList().index(key, index);
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, Object value) {
try {
redisTemplate.opsForList().rightPush(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, Object value, long time) {
try {
redisTemplate.opsForList().rightPush(key, value);
if (time > 0) expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @return
*/
public boolean lSet(String key, List<Object> value) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 将list放入缓存
* @param key 键
* @param value 值
* @param time 时间(秒)
* @return
*/
public boolean lSet(String key, List<Object> value, long time) {
try {
redisTemplate.opsForList().rightPushAll(key, value);
if (time > 0) expire(key, time);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根据索引修改list中的某条数据
* @param key 键
* @param index 索引
* @param value 值
* @return
*/
public boolean lUpdateIndex(String key, long index,Object value) {
try {
redisTemplate.opsForList().set(key, index, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 移除N个值为value
* @param key 键
* @param count 移除多少个
* @param value 值
* @return 移除的个数
*/
public long lRemove(String key,long count,Object value) {
try {
Long remove = redisTemplate.opsForList().remove(key, count, value);
return remove;
} catch (Exception e) {
e.printStackTrace();
return 0;
}
}
}
4.使用案例
@Service
public class UserImpl implements IUser {
@Autowired
UserMapper userMapper;
@Autowired
RedisService redisService;
/**
* @description 根据用户id获取用户详细信息
* @param user
* @return User
**/
@Override
public ServerResponse getDetail(User user) {
String str = (String)redisService.get("user_"+user.getId());
if(str == null) {
User customer = userMapper.selectByPrimaryKey(user.getId());
if (customer == null) {
return ServerResponse.createByErrorMessage("查询个人详细信息失败");
}
redisService.set("user_"+user.getId(), JSON.toJSONString(customer));
return ServerResponse.createBySuccess("查询个人详细信息成功",customer);
}
return ServerResponse.createBySuccess("查询个人详细信息成功",JSON.parseObject(str));
}
}
七.@Value获取配置文件的值
1.准备配置文件url.properties
getDetail:https://www.leichuangkj.com/topicBet/user/getDetail
2.在spring配置文件中添加
<context:property-placeholder location="classpath:db.properties,classpath:url.properties" />
3.在springMVC配置文件中添加
<bean id="propertyHolder" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="systemPropertiesModeName" value="SYSTEM_PROPERTIES_MODE_OVERRIDE"/>
<property name="ignoreResourceNotFound" value="true"/>
<property name="locations">
<list>
<value>classpath:url.properties</value>
</list>
</property>
</bean>
4.在controller中使用
@Controller
@RequestMapping("/user")
public class UserController {
@Value("${getDetail}")
private String getDetail;
@Autowired
UserImpl userImpl;
@Autowired
HttpClientService httpClientService;
/**
* @description 根据用户id获取用户详细信息
* @param user
* @return User
**/
@RequestMapping(value = "/getDetail",method = RequestMethod.POST)
@ResponseBody
public ServerResponse<User> getDetail(@RequestBody User user){
String param = "{\n" +
"\t\"id\":\"oZh8a0be94UHLQnsTNz0DHUj380E\"\n" +
"}";
String str = httpClientService.doPostForJson(getDetail,param);
System.out.println(str);
return userImpl.getDetail(user);
}
}