您的位置:首页 > 数据库 > Redis

mybatis + spring + redis(二级缓存)整合

2017-02-27 15:38 633 查看
原文地址为:http://user.qzone.qq.com/413670706/2

1.pom.xml中加入Maven依赖
 
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.yc</groupId>
<artifactId>wwt</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>

<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<junit.version>4.12</junit.version>
<log.version>2.6.2</log.version>
<spring.version>4.3.2.RELEASE</spring.version>
<jackson
4000
.version>2.8.2</jackson.version>
<mybatis.spring.version>1.3.0</mybatis.spring.version>
<dbcp.version>2.1.1</dbcp.version>
<mybatis.version>3.4.1</mybatis.version>
<mybatis.ehcache.version>1.0.3</mybatis.ehcache.version>
<oracle.version>12.1.0.1</oracle.version>
<mail.version>1.5.6</mail.version>
<redis.version>2.9.0</redis.version>
<spring-redis.version>1.7.5.RELEASE</spring-redis.version>
</properties>

<dependencies>
<!-- 单元测试 -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
<scope>test</scope>
</dependency>

<!-- 日志处理jar包 -->
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>${log.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-core</artifactId>
<version>${log.version}</version>
<scope>runtime</scope>
</dependency>

<!-- springmvc框架的jar包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<scope>runtime</scope>
</dependency>

<!-- spring 整合 数据访问操作的包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-jdbc</artifactId>
<version>${spring.version}</version>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context-support</artifactId>
<version>${spring.version}</version>
<scope>runtime</scope>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-websocket</artifactId>
<version>${spring.version}</version>
<scope>runtime</scope>
</dependency>

<!-- spring测试框包 -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>

<!-- spring整合的json处理框架 -->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>${jackson.version}</version>
<scope>runtime</scope>
</dependency>

<!-- spring与mybatis的适配包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis-spring</artifactId>
<version>${mybatis.spring.version}</version>
<scope>runtime</scope>
</dependency>

<!-- oracle数据库驱动包 -->
<dependency>
<groupId>com.hynnet</groupId>
<artifactId>oracle-driver-ojdbc6</artifactId>
<version>${oracle.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>

<!-- 数据源框架包 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>${dbcp.version}</version>
</dependency>

<!-- mybatis的框架包 -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>${mybatis.version}</version>
<scope>runtime</scope>
</dependency>

<!-- 第三方的缓存框架ehcache -->
<dependency>
<groupId>org.mybatis.caches</groupId>
<artifactId>mybatis-ehcache</artifactId>
<version>${mybatis.ehcache.version}</version>
<exclusions>
<exclusion>
<artifactId>slf4j-api</artifactId>
<groupId>org.slf4j</groupId>
</exclusion>
</exclusions>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>${mail.version}</version>
<scope>runtime</scope>
</dependency>

<!-- redis的依赖包坐标 -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>${redis.version}</version>
<scope>runtime</scope>
</dependency>

<!-- spring-redis的整合依赖包 -->
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-redis</artifactId>
<version>${spring-redis.version}</version>
<scope>runtime</scope>
</dependency>

</dependencies>
<build>
<finalName>wwt</finalName>
</build>
</project>


2.配制文件

 属性文件data.properties

# jdbc settings
jdbc.driverClassName=oracle.jdbc.driver.OracleDriver
jdbc.url=jdbc:oracle:thin:@localhost:1521:orcl
jdbc.username=mybatis
jdbc.password=a
jdbc.initialSize=10
jdbc.maxTotal=100
jdbc.minIdle=5
jdbc.validationQuery=select 1 from dual

# mail settings
mail.smtp.host=smtp.163.com
mail.smtp.username=xxxx@163.com
mail.smtp.password=xxxx
mail.smtp.defaultEncoding=utf-8
mail.smtp.auth=true
mail.smtp.timeout=20000

# redis settings
redis.hostName=127.0.0.1
redis.port=6379
redis.password=
redis.maxIdle=300
redis.maxTotal=600
redis.maxWaitMillis=1000
redis.testOnBorrow=true


 spring.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"
xmlns:util="http://www.springframework.org/schema/util" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"
xmlns:websocket="http://www.springframework.org/schema/websocket"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/util ; http://www.springframework.org/schema/util/spring-util.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.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.xsd http://www.springframework.org/schema/websocket http://www.springframework.org/schema/websocket/spring-websocket.xsd"> 
<!-- 扫描指定的包下面的类, 对其注解, 进行解析处理(变成spring容器管理的bean对象) -->
<context:component-scan base-package="com.yc.wwt">
<!-- 过滤不解析指定注解 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>

<!--引入外部属性文件 -->
<context:property-placeholder location="classpath:data.properties" />

<!-- 与mybatis整合数据源买交给spring容器管理 -->
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${jdbc.driverClassName}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="initialSize" value="${jdbc.initialSize}" />
<property name="maxTotal" value="${jdbc.maxTotal}" />
<property name="minIdle" value="${jdbc.minIdle}" />
<property name="validationQuery" value="${jdbc.validationQuery}" />
</bean>

<!-- 配制mybatis会话工厂对象bean -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" /> <!-- 数据源 -->
<property name="mapperLocations" value="classpath:mapper/*Mapper.xml" /> <!-- mybatis映射文件 -->
<property name="typeAliasesPackage" value="com.yc.wwt.entity" /><!-- 实体类的别名 -->
</bean>

<!-- 配制mybatis映射接口的代理实现类 :bean的名字与映射接口名的首字母小写一样 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.yc.wwt.mapper" />
<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />
</bean>

<!-- java邮件发送处理 -->
<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
<property name="host" value="${mail.smtp.host}" />
<property name="username" value="${mail.smtp.username}" />
<property name="password" value="${mail.smtp.password}" />
<property name="defaultEncoding" value="${mail.smtp.defaultEncoding}" />
<property name="javaMailProperties">
<props>
<prop key="mail.smtp.auth">${mail.smtp.auth}</prop>
<prop key="mail.smtp.timeout">${mail.smtp.timeout}</prop>
</props>
</property>
</bean>
<!-- redis的内存数据库的数据源-->
<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
<property name="maxIdle" value="${redis.maxIdle}"/>
<property name="maxWaitMillis" value="${redis.maxWaitMillis}"/>
<property name="maxTotal" value="${redis.maxTotal}"/>
<property name="testOnBorrow" value="${redis.testOnBorrow}"/>
</bean>
<!-- spring-redis数据连接池管理工厂-->
<bean id="jedisConnectionFactory" class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory">
<property name="hostName" value="${redis.hostName}"/>
<property name="password" value="${redis.password}"/>
<property name="port" value="${redis.port}"/>
<property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
</beans>


log4j2.xml日志配制文件

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<Appenders>
<Console name="STDOUT" target="SYSTEM_OUT">
<PatternLayout pattern="%d %-5p %C{1} (%F:%L) - %m%n"/>
</Console>
</Appenders>
<Loggers>
<!-- 指定包的日志输出级别 -->
<Logger name="com.yc.wwt" level="debug"/>
<!--  总日志输出级别 -->
<Root level="error">
<AppenderRef ref="STDOUT"/>
</Root>
</Loggers>
</Configuration>


3.创建缓存实现类RedisCache

package com.yc.wwt.cache;

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

import org.apache.ibatis.cache.Cache;
import org.apache.logging.log4j.LogManager;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.data.redis.serializer.JdkSerializationRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.SerializationException;

/**
* 使用第三方内存数据库Redis作为二级缓存(参考ehcache二级缓存框架实现)
*
* @author jp
*
*/
public class RedisCache implements Cache {
private static JedisConnectionFactory jedisConnectionFactory;

private final String id;

private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

public RedisCache(String id) {
if (id == null) {
LogManager.getLogger().error("缓存实例编号为null");
throw new IllegalArgumentException("Cache instances require an ID");
}
this.id = id;
LogManager.getLogger().debug("缓存实例编号为" + id);
}

public RedisConnection getConn() {
LogManager.getLogger().debug("获取Redis内存数据库的连接....");
return jedisConnectionFactory.getConnection();
}

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

@Override
// 存放数据到redis中
public void putObject(Object key, Object value) {
RedisConnection con = null;
try {
con = getConn();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
con.set(serializer.serialize(key), serializer.serialize(value));
LogManager.getLogger().debug("存放到Redis内存数据库中的数据Key:" + key + ", value:" + value);
} catch (SerializationException e) {
e.printStackTrace();
} finally {
if (con != null) {
con.close();
}
}

}

@Override
// 从redis中取出数据
public Object getObject(Object key) {
RedisConnection con = null;
try {
con = getConn();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
LogManager.getLogger().debug("从Redis内存数据库中取到Key:" + key + "的值");
return serializer.deserialize(con.get(serializer.serialize(key)));
} catch (SerializationException e) {
e.printStackTrace();
} finally {
if (con != null) {
con.close();
}
}
return null;
}

@Override
// 从redis中删除数据
public Object removeObject(Object key) {
RedisConnection con = null;
try {
con = getConn();
RedisSerializer<Object> serializer = new JdkSerializationRedisSerializer();
LogManager.getLogger().debug("从Redis内存数据库中删除Key:" + key + "的数据");
return con.expire(serializer.serialize(key), 0);
} catch (SerializationException e) {
e.printStackTrace();
} finally {
if (con != null) {
con.close();
}
}
return null;
}

@Override
// //清除redis中所有数据
public void clear() {
RedisConnection con = null;
try {
con = getConn();
con.flushDb();
con.flushAll();
LogManager.getLogger().debug("清空Redis内存数据库中的所有的数据");
} catch (SerializationException e) {
e.printStackTrace();
} finally {
if (con != null) {
con.close();
}
}
}

@Override
// 统计redis中的所有数据个数
public int getSize() {
RedisConnection con = null;
try {
con = getConn();
LogManager.getLogger().debug("统计Redis内存数据库中所有的数据 的个数");
return con.dbSize().intValue();
} catch (SerializationException e) {
e.printStackTrace();
} finally {
if (con != null) {
con.close();
}
}
return 0;
}

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

public static void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
RedisCache.jedisConnectionFactory = jedisConnectionFactory;
}
}


4.创建中间类RedisCacheTransfer,完成RedisCache.jedisConnectionFactory的静态注入

package com.yc.wwt.cache;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.jedis.JedisConnectionFactory;
import org.springframework.stereotype.Component;

/**
* 中间类RedisCacheTransfer,完成RedisCache.jedisConnectionFactory的静态注入
* @author jp
*/
@Component
public class RedisCacheTransfter {

@Autowired
public void setJedisConnectionFactory(JedisConnectionFactory jedisConnectionFactory) {
RedisCache.setJedisConnectionFactory(jedisConnectionFactory);
}
}


5.UserMapper.xml映射文件中加入redis二级缓存

<?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.yc.wwt.mapper.UserMapper">
<cache type="com.yc.wwt.cache.RedisCache"/>
<select id="findUsers" resultType="User">
select * from userinfo
</select>
</mapper>


6.UserMapper.java映射接口

package com.yc.wwt.mapper;

import java.util.List;

import com.yc.wwt.entity.User;

/**
* UserMapper.java映射接口
* @author jp
*
*/
public interface UserMapper {
List<User> findUsers();
}
}


7.User.java数据传递实体类

package com.yc.wwt.entity;

import java.io.Serializable;
import java.util.Date;
/**
* 用户类
* @author jp
*
*/
public class User implements Serializable{
private static final long serialVersionUID = -7824750550745235402L;
private Integer usId;
private String email;
private String uname;
private String pwd;
private String tel;
private String province;
private String city;
private String area;
private String photo;
private Double money;
private Date udate;
private Integer point;
private Integer status;

public Integer getUsId() {
return usId;
}

public void setUsId(Integer usId) {
this.usId = usId;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

public String getUname() {
return uname;
}

public void setUname(String uname) {
this.uname = uname;
}

public String getPwd() {
return pwd;
}

public void setPwd(String pwd) {
this.pwd = pwd;
}

public String getTel() {
return tel;
}

public void setTel(String tel) {
this.tel = tel;
}

public String getProvince() {
return province;
}

public void setProvince(String province) {
this.province = province;
}

public String getCity() {
return city;
}

public void setCity(String city) {
this.city = city;
}

public String getArea() {
return area;
}

public void setArea(String area) {
this.area = area;
}

public String getPhoto() {
return photo;
}

public void setPhoto(String photo) {
this.photo = photo;
}

public Double getMoney() {
return money;
}

public void setMoney(Double money) {
this.money = money;
}

public Date getUdate() {
return udate;
}

public void setUdate(Date udate) {
this.udate = udate;
}

public Integer getPoint() {
return point;
}

public void setPoint(Integer point) {
this.point = point;
}

public Integer getStatus() {
return status;
}

public void setStatus(Integer status) {
this.status = status;
}

@Override
public String toString() {
return "\nUser [usId=" + usId + ", email=" + email + ", uname=" + uname + ", pwd=" + pwd + ", tel=" + tel + ", province=" + province + ", city=" + city + ", area=" + area + ", photo=" + photo + ", money=" + money + ", udate=" + udate + ", point=" + point + ", status=" + status + "]";
}

}


8.测试代码

package com.yc.wwt.mapper;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:spring.xml")
public class UserMapperTest {
@Autowired
private UserMapper userMapper;

@Test
public void testFindUsers() {
System.out.println(userMapper.findUsers());

System.out.println(userMapper.findUsers());

System.out.println(userMapper.findUsers());
}

}


测试结果:

2016-11-22 17:10:25,820 DEBUG RedisCache (RedisCache.java:33) - 缓存实例编号为com.yc.wwt.mapper.UserMapper
2016-11-22 17:10:26,215 DEBUG RedisCache (RedisCache.java:37) - 获取Redis内存数据库的连接....
2016-11-22 17:10:26,293 DEBUG RedisCache (RedisCache.java:71) - 从Redis内存数据库中取到Key:-459579279:426116879:com.yc.wwt.mapper.UserMapper.findUsers:0:2147483647:select * from userinfo:SqlSessionFactoryBean的值
2016-11-22 17:10:26,293 DEBUG LoggingCache (LoggingCache.java:62) - Cache Hit Ratio [com.yc.wwt.mapper.UserMapper]: 0.0
2016-11-22 17:10:26,981 DEBUG BaseJdbcLogger (BaseJdbcLogger.java:145) - ==>  Preparing: select * from userinfo
2016-11-22 17:10:27,004 DEBUG BaseJdbcLogger (BaseJdbcLogger.java:145) - ==> Parameters:
2016-11-22 17:10:27,035 DEBUG BaseJdbcLogger (BaseJdbcLogger.java:145) - <==      Total: 2
2016-11-22 17:10:27,051 DEBUG RedisCache (RedisCache.java:37) - 获取Redis内存数据库的连接....
2016-11-22 17:10:27,051 DEBUG RedisCache (RedisCache.java:54) - 存放到Redis内存数据库中的数据Key:-459579279:426116879:com.yc.wwt.mapper.UserMapper.findUsers:0:2147483647:select * from userinfo:SqlSessionFactoryBean, value:[
User [usId=10021, email=413670706@qq.com, uname=admin, pwd=6f9b0a55df8ac28564cb9f63a10be8af6ab3f7c2, tel=18075895475, province=湖南, city=衡阳, area=珠晖区, photo=null, money=0.0, udate=Fri Nov 18 14:36:22 CST 2016, point=null, status=1],
User [usId=10025, email=jp_706@126.com, uname=root, pwd=6f9b0a55df8ac28564cb9f63a10be8af6ab3f7c2, tel=18075895475, province=湖南, city=衡阳, area=珠晖区, photo=null, money=0.0, udate=Fri Nov 18 15:11:32 CST 2016, point=null, status=1]]
[
User [usId=10021, email=413670706@qq.com, uname=admin, pwd=6f9b0a55df8ac28564cb9f63a10be8af6ab3f7c2, tel=18075895475, province=湖南, city=衡阳, area=珠晖区, photo=null, money=0.0, udate=Fri Nov 18 14:36:22 CST 2016, point=null, status=1],
User [usId=10025, email=jp_706@126.com, uname=root, pwd=6f9b0a55df8ac28564cb9f63a10be8af6ab3f7c2, tel=18075895475, province=湖南, city=衡阳, area=珠晖区, photo=null, money=0.0, udate=Fri Nov 18 15:11:32 CST 2016, point=null, status=1]]
2016-11-22 17:10:27,051 DEBUG RedisCache (RedisCache.java:37) - 获取Redis内存数据库的连接....
2016-11-22 17:10:27,051 DEBUG RedisCache (RedisCache.java:71) - 从Redis内存数据库中取到Key:-459579279:426116879:com.yc.wwt.mapper.UserMapper.findUsers:0:2147483647:select * from userinfo:SqlSessionFactoryBean的值
2016-11-22 17:10:27,051 DEBUG LoggingCache (LoggingCache.java:62) - Cache Hit Ratio [com.yc.wwt.mapper.UserMapper]: 0.5
[
User [usId=10021, email=413670706@qq.com, uname=admin, pwd=6f9b0a55df8ac28564cb9f63a10be8af6ab3f7c2, tel=18075895475, province=湖南, city=衡阳, area=珠晖区, photo=null, money=0.0, udate=Fri Nov 18 14:36:22 CST 2016, point=null, status=1],
User [usId=10025, email=jp_706@126.com, uname=root, pwd=6f9b0a55df8ac28564cb9f63a10be8af6ab3f7c2, tel=18075895475, province=湖南, city=衡阳, area=珠晖区, photo=null, money=0.0, udate=Fri Nov 18 15:11:32 CST 2016, point=null, status=1]]
2016-11-22 17:10:27,051 DEBUG RedisCache (RedisCache.java:37) - 获取Redis内存数据库的连接....
2016-11-22 17:10:27,051 DEBUG RedisCache (RedisCache.java:71) - 从Redis内存数据库中取到Key:-459579279:426116879:com.yc.wwt.mapper.UserMapper.findUsers:0:2147483647:select * from userinfo:SqlSessionFactoryBean的值
2016-11-22 17:10:27,067 DEBUG LoggingCache (LoggingCache.java:62) - Cache Hit Ratio [com.yc.wwt.mapper.UserMapper]: 0.6666666666666666
[
User [usId=10021, email=413670706@qq.com, uname=admin, pwd=6f9b0a55df8ac28564cb9f63a10be8af6ab3f7c2, tel=18075895475, province=湖南, city=衡阳, area=珠晖区, photo=null, money=0.0, udate=Fri Nov 18 14:36:22 CST 2016, point=null, status=1],
User [usId=10025, email=jp_706@126.com, uname=root, pwd=6f9b0a55df8ac28564cb9f63a10be8af6ab3f7c2, tel=18075895475, province=湖南, city=衡阳, area=珠晖区, photo=null, money=0.0, udate=Fri Nov 18 15:11:32 CST 2016, point=null, status=1]]
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: