应召女友第二季资源一二季资源百度云求大佬

访问人次:
随笔- 235&
&&&&&&&&&&&
本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用
内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系。
本人互联网技术爱好者,互联网技术发烧友
微博:伊直都在0221
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1.JdbcTemplate 简介
  1)为了使 JDBC 更加易于使用, Spring 在 JDBC API 上定义了一个抽象层, 以此建立一个 JDBC 存取框架.
  2)作为 Spring JDBC 框架的核心, JDBC 模板的设计目的是为不同类型的 JDBC 操作提供模板方法. 每个模板方法都能控制整个过程, 并允许覆盖过程中的特定任务. 通过这种方式, 可以在尽可能保留灵活性的情况下, 将数据库存取的工作量降到最低.
本篇主要讲述JdbcTemplate 相关的API,主要以代码为例
2.构建工程 及 部分代码
  1)导入spring jar,额外加入 &mysql c3p0 jar包
      
  2)在配置文件中配置c3p0数据源
    db.properties
1 jdbc.user=root
2 jdbc.password=zhangzhen
3 jdbc.driverClass=com.mysql.jdbc.Driver
4 jdbc.jdbcUrl=jdbc:mysql:///spring
6 jdbc.initPoolSize=5
7 jdbc.maxPoolSize=10
      
    在配置文件中配置c3p0文件
1 &!-- 导入资源文件 --&
&context:property-placeholder location="classpath:db.properties"/&
&!-- 配置c3p0 数据源 --&
&bean id="dataSource" class="com.mchange.boPooledDataSource"&
&property name="user" value="${jdbc.user}"&&/property&
&property name="password" value="${jdbc.password}"&&/property&
&property name="jdbcUrl" value="${jdbc.jdbcUrl}"&&/property&
&property name="driverClass" value="${jdbc.driverClass}"&&/property&
&property name="initialPoolSize" value="${jdbc.initPoolSize}"&&/property&
&property name="maxPoolSize" value="${jdbc.maxPoolSize}"&&/property&
    3)配置 Spring 的jdbcTemplate
1 &!-- 配置Spring 的jdbcTemplate
&bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"&
&property name="dataSource" ref="dataSource"&&/property&
3.完整代码
  application.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:context="http://www.springframework.org/schema/context"
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-4.0.xsd"&
&!-- 导入资源文件 --&
&context:property-placeholder location="classpath:db.properties"/&
&!-- 配置c3p0 数据源 --&
&bean id="dataSource" class="com.mchange.boPooledDataSource"&
&property name="user" value="${jdbc.user}"&&/property&
&property name="password" value="${jdbc.password}"&&/property&
&property name="jdbcUrl" value="${jdbc.jdbcUrl}"&&/property&
&property name="driverClass" value="${jdbc.driverClass}"&&/property&
&property name="initialPoolSize" value="${jdbc.initPoolSize}"&&/property&
&property name="maxPoolSize" value="${jdbc.maxPoolSize}"&&/property&
&!-- 配置Spring 的jdbcTemplate
&bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"&
&property name="dataSource" ref="dataSource"&&/property&
Department.java
1 package com.jason.spring.
3 public class Department {
public Integer getId() {
public void setId(Integer id) {
public String getName() {
public void setName(String name) {
this.name =
public String toString() {
return "Department [id=" + id + ", name=" + name + "]";
Employee.java
1 package com.jason.spring.
3 public class Employee {
private String lastN
public Integer getId() {
public void setId(Integer id) {
public String getLastName() {
return lastN
public void setLastName(String lastName) {
this.lastName = lastN
public String getEmail() {
public void setEmail(String email) {
this.email =
public Department getDepartment() {
public void setDepartment(Department department) {
this.department =
public String toString() {
return "Employee [id=" + id + ", lastName=" + lastName + ", email="
+ email + ", department=" + department + "]";
单元测试类
1 package com.jason.spring.
3 import static org.junit.Assert.*;
5 import java.sql.SQLE
6 import java.util.ArrayL
7 import java.util.L
9 import javax.sql.DataS
11 import org.junit.T
12 import org.springframework.context.ApplicationC
13 import org.springframework.context.support.ClassPathXmlApplicationC
14 import org.springframework.jdbc.core.BeanPropertyRowM
15 import org.springframework.jdbc.core.JdbcT
16 import org.springframework.jdbc.core.RowM
19 public class JDBCTest {
private ApplicationContext ctx = null;
private JdbcTemplate jdbcT
ctx = new ClassPathXmlApplicationContext("application.xml");
jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
* @Author:jason_
* @Title: testQueryForObject2
* @Time:日
* @Description: 获取单个列的值,或做统计查询
* 使用 queryForObject(String sql, Class&Long& requiredType) 方法
public void testQueryForObject2(){
String sql ="SELECT count(id) FROM employee ";
long count = jdbcTemplate.queryForObject(sql, Long.class);
System.out.println(count);
* @Author:jason_
* @Title: testQueryForList
* @Time:日
* @Description: 查到实体类的集合
* 注意:调用的方法不是queryForList
public void testQueryForList(){
String sql = "SELECT id, last_name lastName, email FROM employee WHERE id & ?";
RowMapper&Employee& rowMapper = new BeanPropertyRowMapper&&(Employee.class);
List&Employee& employees = jdbcTemplate.query(sql, rowMapper, 5);
System.out.println(employees);
* @Author:jason_
* @Title: testQueryForObject
* @Time:日
* @Description: 从数据库中获取一条记录,实际得到对应的对象
注意:.queryForObject(String sql, Class&Employee& requiredType, Object... args) 返回的是一个字段
需要使用:queryForObject(String sql, RowMapper&Employee& rowMapper, Object... args)
1.RowMapper 指定如何映射结果的行,常用的实现类为 BeanPropertyRowMapper
2.使用SQL 中列的别名完成列名 和 类的属性名的映射:last_name
3.不支持级联属性,jdbcTemplate 是一个JDBC的小工具,不是ORM框架
public void testQueryForObject(){
String sql = "SELECT id, last_name lastName, email, dept_id as \"department.id\" FROM employee WHERE id = ?";
RowMapper&Employee& rowMapper = new BeanPropertyRowMapper&&(Employee.class);
Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, 1);
System.out.println(employee);
* @Author:jason_
* @Title: testBatchUpdate
* @Time:日
* @Description: 执行批量的 INSERT, UPDATE, DELETE
最后一个参数是Object[] 的list 类型:因为修改一条记录需要一个Object 数据,多条记录 对应多个Object 形成数组
public void testBatchUpdate(){
String sql = "INSERT INTO employee(last_name, email, dept_id) VALUES(?,?,?)";
List&Object[]& batchArgs = new ArrayList&&();
batchArgs.add(new Object[]{"AA","",1});
batchArgs.add(new Object[]{"bb","",2});
batchArgs.add(new Object[]{"cc","",3});
batchArgs.add(new Object[]{"dd","",4});
batchArgs.add(new Object[]{"ee","",5});
batchArgs.add(new Object[]{"ff","",1});
jdbcTemplate.batchUpdate(sql, batchArgs);
* @Author:jason_
* @Title: testUpdate
* @Time:日
* @Description: 执行 INSERT, UPDATE, DELETE
public void testUpdate(){
String sql = "UPDATE employee SET last_name = ? WHERE id = ?";
jdbcTemplate.update(sql,"JACK",4);
public void testDataSource() throws SQLException {
DataSource dataSources = ctx.getBean(DataSource.class);
System.out.println(dataSources.getConnection());
4.简化 JDBC 模板查询
  1)每次使用都创建一个 JdbcTemplate 的新实例, 这种做法效率很低下.
  2)JdbcTemplate 类被设计成为线程安全的, 所以可以再 IOC 容器中声明它的单个实例, 并将这个实例注入到所有的 DAO 实例中.
  3)JdbcTemplate 也利用了 Java 1.5 的特定(自动装箱, 泛型, 可变长度等)来简化开发
  注入JDBC 模板
& 注解方式实现自动注入 
1 import org.springframework.beans.factory.annotation.A
2 import org.springframework.jdbc.core.BeanPropertyRowM
3 import org.springframework.jdbc.core.JdbcT
4 import org.springframework.jdbc.core.RowM
5 import org.springframework.stereotype.R
7 @Repository
8 public class EmployeeDao {
@Autowired
private JdbcTemplate jdbcT
public Employee get(Integer id){
String sql = "SELECT id, last_name lastName, email FROM employees WHERE id = ?";
RowMapper&Employee& rowMapper = new BeanPropertyRowMapper&&(Employee.class);
Employee employee = jdbcTemplate.queryForObject(sql, rowMapper, id);
5.在 JDBC 模板中使用具名参数
  1)在经典的 JDBC 用法中, SQL 参数是用占位符 ? 表示,并且受到位置的限制. 定位参数的问题在于, 一旦参数的顺序发生变化, 就必须改变参数绑定.
  2)在 Spring JDBC 框架中, 绑定 SQL 参数的另一种选择是使用具名参数(named parameter).
  3)具名参数: SQL 按名称(以冒号开头)而不是按位置进行指定. 具名参数更易于维护, 也提升了可读性. 具名参数由框架类在运行时用占位符取代
  4)具名参数只在 NamedParameterJdbcTemplate 中得到支持
  具体实现
  5)在 SQL 语句中使用具名参数时, 可以在一个 Map 中提供参数值, 参数名为键
  6)也可以使用 SqlParameterSource 参数
&  &7)批量更新时可以提供 Map 或 SqlParameterSource 的数组
& & & & & & & & & &&
1 public class JDBCTest {
private ApplicationContext ctx = null;
private JdbcTemplate jdbcT
private NamedParameterJdbcTemplate namedParameterJdbcT
ctx = new ClassPathXmlApplicationContext("application.xml");
jdbcTemplate = (JdbcTemplate) ctx.getBean("jdbcTemplate");
namedParameterJdbcTemplate
= (NamedParameterJdbcTemplate) ctx.getBean("namedParameterJdbcTemplate");
* 使用具名参数使用这个方法:update(String sql, SqlParameterSource paramSource)
* 1.sql 语句中的参数名 和 类的属性一致
* 2.使用 SqlParameterSource 的 BeanPropertySqlParameterSource实现类,作为参数
public void testNamedParameterJdbcTemplate2(){
String sql = "INSERT INTO employee(last_name, email, dept_id) VALUES(:lastName, :email, :deptId)";
Employee employee = new Employee();
employee.setLastName("wl");
employee.setEmail("");
employee.setDeptId(5);
SqlParameterSource parameterSource = new BeanPropertySqlParameterSource(employee);
namedParameterJdbcTemplate.update(sql, parameterSource);
* @Author:jason_
* @Title: testNamedParameterJdbcTemplate
* @Time:日
* @Description: 使用具名参数
可以为参数起名
1.好处:若有多个参数,则不用再去对应位置,直接对应参数名,便于维护
2.缺点:较为麻烦一台
public void testNamedParameterJdbcTemplate(){
String sql = "INSERT INTO employee(last_name, email, dept_id) VALUES(:ln, :email, :deptid)";
Map&String, Object& paramMap
= new HashMap&String, Object&();
paramMap.put("ln", "FF");
paramMap.put("email", "");
paramMap.put("deptid", 5);
namedParameterJdbcTemplate.update(sql, paramMap);
配置namedParameterJdbcTemplate 的bean  
1 &!-- 配置具名参数 namedParameterJdbcTemplate,该对象可以使用具名参数,其没有无参数的构造器,必须为其构造器指定参数,一般为dataSource --&
&bean id="namedParameterJdbcTemplate" class="org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate"&
&constructor-arg ref="dataSource"&&/constructor-arg&
阅读(...) 评论()之前介绍了很多Web层的例子,包括、,但是这些内容还不足以构建一个动态的应用。通常我们做App也好,做Web应用也好,都需要内容,而内容通常存储于各种类型的数据库,服务端在接收到访问请求之后需要访问数据库获取并处理成展现给用户使用的数据形式。
本文介绍在Spring Boot基础下配置数据源和通过JdbcTemplate编写数据访问的示例。
数据源配置在我们访问数据库的时候,需要先配置一个数据源,下面分别介绍一下几种不同的数据库配置方式。
首先,为了连接数据库需要引入jdbc支持,在pom.xml中引入如下配置:
&org.springframework.boot&
&spring-boot-starter-jdbc&&
嵌入式数据库支持嵌入式数据库通常用于开发和测试环境,不推荐用于生产环境。Spring Boot提供自动配置的嵌入式数据库有H2、HSQL、Derby,你不需要提供任何连接配置就能使用。
比如,我们可以在pom.xml中引入如下配置使用HSQL
&org.hsqldb&
&runtime&&
连接生产数据源以MySQL数据库为例,先引入MySQL连接的依赖包,在pom.xml中加入:
&mysql-connector-java&
在src/main/resources/application.properties中配置数据源信息
1234spring.datasource.url=jdbc:mysql://localhost:3306/testspring.datasource.username=dbuserspring.datasource.password=dbpassspring.datasource.driver-class-name=com.mysql.jdbc.Driver
连接JNDI数据源当你将应用部署于应用服务器上的时候想让数据源由应用服务器管理,那么可以使用如下配置方式引入JNDI数据源。
1spring.datasource.jndi-name=java:jboss/datasources/customers
使用JdbcTemplate操作数据库Spring的JdbcTemplate是自动配置的,你可以直接使用@Autowired来注入到你自己的bean中来使用。
举例:我们在创建User表,包含属性name、age,下面来编写数据访问对象和单元测试用例。
定义包含有插入、删除、查询的抽象接口UserService
1234567891011121314151617181920212223242526public interface UserService {
* 新增一个用户
void create(String name, Integer age);
* 根据name删除一个用户高
void deleteByName(String name);
* 获取用户总量
Integer getAllUsers();
* 删除所有用户
void deleteAllUsers();}
通过JdbcTemplate实现UserService中定义的数据访问操作
1234567891011121314151617181920212223242526@Servicepublic class UserServiceImpl implements UserService {
@Autowired
private JdbcTemplate jdbcT
public void create(String name, Integer age) {
jdbcTemplate.update("insert into USER(NAME, AGE) values(?, ?)", name, age);
public void deleteByName(String name) {
jdbcTemplate.update("delete from USER where NAME = ?", name);
public Integer getAllUsers() {
return jdbcTemplate.queryForObject("select count(1) from USER", Integer.class);
public void deleteAllUsers() {
jdbcTemplate.update("delete from USER");
}}
创建对UserService的单元测试用例,通过创建、删除和查询来验证数据库操作的正确性。
123456789101112131415161718192021222324252627282930313233343536@RunWith(SpringJUnit4ClassRunner.class)@SpringApplicationConfiguration(Application.class)public class ApplicationTests { @Autowired private UserService userS @Before public void setUp() {
userSerivce.deleteAllUsers(); } @Test public void test() throws Exception {
userSerivce.create("a", 1);
userSerivce.create("b", 2);
userSerivce.create("c", 3);
userSerivce.create("d", 4);
userSerivce.create("e", 5);
Assert.assertEquals(5, userSerivce.getAllUsers().intValue());
userSerivce.deleteByName("a");
userSerivce.deleteByName("e");
Assert.assertEquals(3, userSerivce.getAllUsers().intValue()); }}
上面介绍的JdbcTemplate只是最基本的几个操作,更多其他数据访问操作的使用请参考:
通过上面这个简单的例子,我们可以看到在Spring Boot下访问数据库的配置依然秉承了框架的初衷:简单。我们只需要在pom.xml中加入数据库依赖,再到application.properties中配置连接信息,不需要像Spring应用中创建JdbcTemplate的Bean,就可以直接在自己的对象中注入使用。
如果您有任何想法或问题需要讨论或交流,可进入发表您的想法或问题。spring JdbcTemplate批量插入 怎么获得数据库自动增长的id - ITeye问答
如下,插入一条记录的时候可以这样返回id(一下代码只是说明事例):
//保存一个test对象,并返回该对象
public Test save(Test test){
KeyHolder keyHolder = new GeneratedKeyHolder();
getJdbcTemplate().update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(
Connection con) throws SQLException {
PreparedStatement ps = con.prepareStatement("insert into tb_test (name,sex) values (?,?)",
Statement.RETURN_GENERATED_KEYS);
ps.setString(1, test.getName());
ps.setString(2, test.getSex());
}, keyHolder);
//这里可以获得数据库id
test.setId(Integer.valueOf(keyHolder.getKeyList().get(0)
.toString()));
// 批量插入,
public List&Test& saveOrUpdateAll(final List&Test& list) {
getJdbcTemplate().batchUpdate(
"insert into tb_test (name,sex) values (?,?)",
new BatchPreparedStatementSetter() {
public void setValues(PreparedStatement ps, int i)
throws SQLException {
ps.setString(1, list.get(i).getName());
ps.setString(2, list.get(i).getSex());
public int getBatchSize() {
return list.size();
//哪个方法可以获得list中每个test对象的id?我不想重新进行查询
问题补充:飞雪无情 写道你已经写好了插入一个对象的方法,就是public Test save(Test test),批量插入的时候可以直接使用该方法的。# public List&Test& saveOrUpdateAll(final List&Test& list) {
List&Test& resultList=new ArrayList&Test&();
for(Test test:list){
resultList.add(save(test));
return resultL
这样就好了。
我也考虑过这样的方式,但是把:
getJdbcTemplate().update(new PreparedStatementCreator() {
public PreparedStatement createPreparedStatement(
Connection con) throws SQLException {
PreparedStatement ps = con.prepareStatement("insert into tb_test (name,sex) values (?,?)",
Statement.RETURN_GENERATED_KEYS);
ps.setString(1, test.getName());
ps.setString(2, test.getSex());
}, keyHolder);
这么一段代码放在循环里面,会不会性能有些影响吧?Spring既然提供了batchUpdate,该会不会在批处理上有些性能优势呢?
问题补充:飞雪无情 写道spring这个批量插入有点限制,比如你这个特殊需要,我感觉它实现不了,所以你用我上面说的那个方法迂回实现。我感觉性能方面应该不会有太大的影响。你看spring的批量插入的时候这个BatchPreparedStatementSetter借口的方法setValues(PreparedStatement ps, int i)& ,提供了一个索引i,它肯定也遍历了,要么怎么知道i的值。所以有特殊需求的时候就用上面那种方案,没有的时候推荐用spring提供了批量操作,我们项目中就这么做的。
看了Spring这两个方法的源码,觉得这个东西在封装的时候考虑的不是很周全,确实局限性太大了,比如我批量保存的时候有可能一部分是插入,一部分是更新,这个时候也只能按照你说的这种方式了,比较而言还是orm框架持久层用起来的方便。
spring的这个两个方法看了源码感觉在设计上确实存在缺陷,灵活性不够,其实返回数据库执行的条数意义根本就不大
//其实我想的是这样的一个方法
* @author BAOSJ
* @param sql
* @param values
* @param batchSize
* @throws Exception
public List&Object& saveOrUpdateAll(String sql, List&Object[]& values,
Integer batchSize) throws Exception {
ResultSet rs =
PreparedStatement ps =
Connection conn =
// 返回执行对象的id
List&Object& ids = new ArrayList&Object&();
conn = getConnection();
conn.setAutoCommit(false);
ps = conn.prepareStatement(sql,
PreparedStatement.RETURN_GENERATED_KEYS);
for (int i = 0; i & values.size(); i++) {
Object[] objects = values.get(i);
for (int j = 0; j & objects. j++) {
ps.setObject(i + 1, objects[j]);
if (i % batchSize == 0 || values.size() &= batchSize) {
ps.executeBatch();
rs = ps.getGeneratedKeys();
int c = 0;
while (rs.next()) {
ids.add(rs.getObject(c));
} catch (Exception e) {
conn.rollback();
} finally {
destroy(rs, ps, conn);
//update源码
public int update(final PreparedStatementCreator psc, final KeyHolder generatedKeyHolder)
throws DataAccessException {
Assert.notNull(generatedKeyHolder, "KeyHolder must not be null");
logger.debug("Executing SQL update and returning generated keys");
Integer result = (Integer) execute(psc, new PreparedStatementCallback() {
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {
int rows = ps.executeUpdate();
List generatedKeys = generatedKeyHolder.getKeyList();
generatedKeys.clear();
ResultSet keys = ps.getGeneratedKeys();
if (keys != null) {
RowMapper rowMapper = getColumnMapRowMapper();
RowMapperResultSetExtractor rse = new RowMapperResultSetExtractor(rowMapper, 1);
generatedKeys.addAll((List) rse.extractData(keys));
JdbcUtils.closeResultSet(keys);
if (logger.isDebugEnabled()) {
logger.debug("SQL update affected " + rows + " rows and returned " + generatedKeys.size() + " keys");
return new Integer(rows);
return result.intValue();
//batchUpdate源码
public int[] batchUpdate(String sql, final BatchPreparedStatementSetter pss) throws DataAccessException {
if (logger.isDebugEnabled()) {
logger.debug("Executing SQL batch update [" + sql + "]");
return (int[]) execute(sql, new PreparedStatementCallback() {
public Object doInPreparedStatement(PreparedStatement ps) throws SQLException {
int batchSize = pss.getBatchSize();
InterruptibleBatchPreparedStatementSetter ipss =
(pss instanceof InterruptibleBatchPreparedStatementSetter ?
(InterruptibleBatchPreparedStatementSetter) pss : null);
if (JdbcUtils.supportsBatchUpdates(ps.getConnection())) {
for (int i = 0; i & batchS i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
ps.addBatch();
return ps.executeBatch();
List rowsAffected = new ArrayList();
for (int i = 0; i & batchS i++) {
pss.setValues(ps, i);
if (ipss != null && ipss.isBatchExhausted(i)) {
rowsAffected.add(new Integer(ps.executeUpdate()));
int[] rowsAffectedArray = new int[rowsAffected.size()];
for (int i = 0; i & rowsAffectedArray. i++) {
rowsAffectedArray[i] = ((Integer) rowsAffected.get(i)).intValue();
return rowsAffectedA
if (pss instanceof ParameterDisposer) {
((ParameterDisposer) pss).cleanupParameters();
采纳的答案
spring这个批量插入有点限制,比如你这个特殊需要,我感觉它实现不了,所以你用我上面说的那个方法迂回实现。我感觉性能方面应该不会有太大的影响。你看spring的批量插入的时候这个BatchPreparedStatementSetter借口的方法setValues(PreparedStatement ps, int i)& ,提供了一个索引i,它肯定也遍历了,要么怎么知道i的值。所以有特殊需求的时候就用上面那种方案,没有的时候推荐用spring提供了批量操作,我们项目中就这么做的。
嗯。我刚刚给你写完就想看看源代码,发现我这没有,又下载的,还没好呢,网速太慢。。你上面的我看的,采用java.sql包中的自己写方便灵活,可以满足你的要求,你也写出来。看上面的spring源代码,spring的批量插入限制是很大,解耦BatchPreparedStatementSetter只有两个方法,一个是设置,一个是数据的个数,都被用在batchUpdate方法中进行循环setValues啦,最后使用的是java sql API PreparedStatement的批量更新(支持的话,不支持有它自己的批量更新)。。其实spring设计这个只是为了批量更新,不想做其他的事情。看来也合理,速度也不错。不知道以后会不会有可以自定义这种实现,用于满足比如你这样的特殊需要。
你已经写好了插入一个对象的方法,就是public Test save(Test test),批量插入的时候可以直接使用该方法的。# public List&Test& saveOrUpdateAll(final List&Test& list) {
List&Test& resultList=new ArrayList&Test&();
for(Test test:list){
resultList.add(save(test));
return resultL
这样就好了。
已解决问题
未解决问题

我要回帖

更多关于 应召女友第二季bt 的文章

 

随机推荐