日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

jdbc template 学习总结

發布時間:2025/4/14 编程问答 56 豆豆
生活随笔 收集整理的這篇文章主要介紹了 jdbc template 学习总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Spring JdbcTemplate方法詳解



?JdbcTemplate主要提供以下五類方法:
execute方法:可以用于執行任何SQL語句,一般用于執行DDL語句;


update方法及batchUpdate方法:update方法用于執行新增、修改、刪除等語句;batchUpdate方法用于


執行批處理相關語句;


query方法及queryForXXX方法:用于執行查詢相關語句;


call方法:用于執行存儲過程、函數相關語句。
?
JdbcTemplate類支持的回調類:
預編譯語句及存儲過程創建回調:用于根據JdbcTemplate提供的連接創建相應的語句;


? ? ? ? ?PreparedStatementCreator:通過回調獲取JdbcTemplate提供的Connection,由用戶使用該


Conncetion創建相關的PreparedStatement;
? ? ? ? ?CallableStatementCreator:通過回調獲取JdbcTemplate提供的Connection,由用戶使用該


Conncetion創建相關的CallableStatement;
預編譯語句設值回調:用于給預編譯語句相應參數設值;


? ? ? ? ?PreparedStatementSetter:通過回調獲取JdbcTemplate提供的PreparedStatement,由用戶來


對相應的預編譯語句相應參數設值;
? ? ? ? ?BatchPreparedStatementSetter:;類似于PreparedStatementSetter,但用于批處理,需要


指定批處理大小;
自定義功能回調:提供給用戶一個擴展點,用戶可以在指定類型的擴展點執行任何數量需要的操作;


? ? ? ? ?ConnectionCallback:通過回調獲取JdbcTemplate提供的Connection,用戶可在該Connection


執行任何數量的操作;
? ? ? ? ?StatementCallback:通過回調獲取JdbcTemplate提供的Statement,用戶可以在該Statement


執行任何數量的操作;
? ? ? ? ?PreparedStatementCallback:通過回調獲取JdbcTemplate提供的PreparedStatement,用戶可


以在該PreparedStatement執行任何數量的操作;
? ? ? ? ?CallableStatementCallback:通過回調獲取JdbcTemplate提供的CallableStatement,用戶可


以在該CallableStatement執行任何數量的操作;
結果集處理回調:通過回調處理ResultSet或將ResultSet轉換為需要的形式;


? ? ? ? ?RowMapper:用于將結果集每行數據轉換為需要的類型,用戶需實現方法mapRow(ResultSet?


rs, int rowNum)來完成將每行數據轉換為相應的類型。
? ? ? ? ?RowCallbackHandler:用于處理ResultSet的每一行結果,用戶需實現方法processRow


(ResultSet rs)來完成處理,在該回調方法中無需執行rs.next(),該操作由JdbcTemplate來執行,用戶


只需按行獲取數據然后處理即可。
? ? ? ? ?ResultSetExtractor:用于結果集數據提取,用戶需實現方法extractData(ResultSet rs)來


處理結果集,用戶必須處理整個結果集;
?
接下來讓我們看下具體示例吧,在示例中不可能介紹到JdbcTemplate全部方法及回調類的使用方法,我


們只介紹代表性的,其余的使用都是類似的;
?
?1)預編譯語句及存儲過程創建回調、自定義功能回調使用:
?
java代碼:


Java代碼 ?收藏代碼


public void testPpreparedStatement1() { ?


? int count = jdbcTemplate.execute(new PreparedStatementCreator() { ?


? ? ?@Override ?


? ? ?public PreparedStatement createPreparedStatement(Connection conn) ?


? ? ? ? ?throws SQLException { ?


? ? ? ? ?return conn.prepareStatement("select count(*) from test"); ?


? ? ?}}, new PreparedStatementCallback<Integer>() { ?


? ? ?@Override ?


? ? ?public Integer doInPreparedStatement(PreparedStatement pstmt) ?


? ? ? ? ?throws SQLException, DataAccessException { ?


? ? ? ? ?pstmt.execute(); ?


? ? ? ? ?ResultSet rs = pstmt.getResultSet(); ?


? ? ? ? ?rs.next(); ?


? ? ? ? ?return rs.getInt(1); ?


? ? ? }}); ? ? ?


? ?Assert.assertEquals(0, count); ?


} ?


?
首先使用PreparedStatementCreator創建一個預編譯語句,其次由JdbcTemplate通過


PreparedStatementCallback回調傳回,由用戶決定如何執行該PreparedStatement。此處我們使用的是


execute方法。
?
2)預編譯語句設值回調使用:
?
java代碼:


Java代碼 ?收藏代碼
? ? ? ?


public void testPreparedStatement2() { ?


? String insertSql = "insert into test(name) values (?)"; ?


? int count = jdbcTemplate.update(insertSql, new PreparedStatementSetter() { ?


? ? ? @Override ?


? ? ? public void setValues(PreparedStatement pstmt) throws SQLException { ?


? ? ? ? ? pstmt.setObject(1, "name4"); ?


? }}); ?


? Assert.assertEquals(1, count); ? ? ?


? String deleteSql = "delete from test where name=?"; ?


? count = jdbcTemplate.update(deleteSql, new Object[] {"name4"}); ?


? Assert.assertEquals(1, count); ?


} ?
?
? ? ? 通過JdbcTemplate的int update(String sql, PreparedStatementSetter pss)執行預編譯sql,


其中sql參數為“insert into test(name) values (?) ”,該sql有一個占位符需要在執行前設值,


PreparedStatementSetter實現就是為了設值,使用setValues(PreparedStatement pstmt)回調方法設值


相應的占位符位置的值。JdbcTemplate也提供一種更簡單的方式“update(String sql, Object...?


args)”來實現設值,所以只要當使用該種方式不滿足需求時才應使用PreparedStatementSetter。
?
3)結果集處理回調:
?
java代碼:


Java代碼 ?收藏代碼




public void testResultSet1() { ?


? jdbcTemplate.update("insert into test(name) values('name5')"); ?


? String listSql = "select * from test"; ?


? List result = jdbcTemplate.query(listSql, new RowMapper<Map>() { ?


? ? ? @Override ?


? ? ? public Map mapRow(ResultSet rs, int rowNum) throws SQLException { ?


? ? ? ? ? Map row = new HashMap(); ?


? ? ? ? ? row.put(rs.getInt("id"), rs.getString("name")); ?


? ? ? ? ? return row; ?


? }}); ?


? Assert.assertEquals(1, result.size()); ?


? jdbcTemplate.update("delete from test where name='name5'"); ? ? ??


} ?


?
RowMapper接口提供mapRow(ResultSet rs, int rowNum)方法將結果集的每一行轉換為一個Map,當然可


以轉換為其他類,如表的對象畫形式。
?
java代碼:


Java代碼 ?收藏代碼




public void testResultSet2() { ?


? jdbcTemplate.update("insert into test(name) values('name5')"); ?


? String listSql = "select * from test"; ?


? final List result = new ArrayList(); ?


? jdbcTemplate.query(listSql, new RowCallbackHandler() { ?


? ? ? @Override ?


? ? ? public void processRow(ResultSet rs) throws SQLException { ?


? ? ? ? ? Map row = new HashMap(); ?


? ? ? ? ? row.put(rs.getInt("id"), rs.getString("name")); ?


? ? ? ? ? result.add(row); ?


? }}); ?


? Assert.assertEquals(1, result.size()); ?


? jdbcTemplate.update("delete from test where name='name5'"); ?


} ?




RowCallbackHandler接口也提供方法processRow(ResultSet rs),能將結果集的行轉換為需要的形式。
?
java代碼:


Java代碼 ?收藏代碼




public void testResultSet3() { ?


? jdbcTemplate.update("insert into test(name) values('name5')"); ?


? String listSql = "select * from test"; ?


? List result = jdbcTemplate.query(listSql, new ResultSetExtractor<List>() { ?


? ? ? @Override ?


? ? ? public List extractData(ResultSet rs) ?


? ? ?throws SQLException, DataAccessException { ?


? ? ? ? ? List result = new ArrayList(); ?


? ? ? ? ? while(rs.next()) { ?


? ? ? ? ? ? ? Map row = new HashMap(); ?


? ? ? ? ? ? ? row.put(rs.getInt("id"), rs.getString("name")); ?


? ? ? ? ? ? ? result.add(row); ?


? ? ? ? ? ?} ?


? ? ? ? ? ?return result; ?


? }}); ?


? Assert.assertEquals(0, result.size()); ?


? jdbcTemplate.update("delete from test where name='name5'"); ?


} ?


?
ResultSetExtractor使用回調方法extractData(ResultSet rs)提供給用戶整個結果集,讓用戶決定如何


處理該結果集。
?
當然JdbcTemplate提供更簡單的queryForXXX方法,來簡化開發:
?
java代碼:


Java代碼 ?收藏代碼


//1.查詢一行數據并返回int型結果 ?


jdbcTemplate.queryForInt("select count(*) from test"); ?


//2. 查詢一行數據并將該行數據轉換為Map返回 ?


jdbcTemplate.queryForMap("select * from test where name='name5'"); ?


//3.查詢一行任何類型的數據,最后一個參數指定返回結果類型 ?


jdbcTemplate.queryForObject("select count(*) from test", Integer.class); ?


//4.查詢一批數據,默認將每行數據轉換為Map ? ? ??


jdbcTemplate.queryForList("select * from test"); ?


//5.只查詢一列數據列表,列類型是String類型,列名字是name ?


jdbcTemplate.queryForList(" ?


select name from test where name=?", new Object[]{"name5"}, String.class); ?


//6.查詢一批數據,返回為SqlRowSet,類似于ResultSet,但不再綁定到連接上 ?


SqlRowSet rs = jdbcTemplate.queryForRowSet("select * from test"); ?


?
3) 存儲過程及函數回調:
首先修改JdbcTemplateTest的setUp方法,修改后如下所示:
?
?
java代碼:


Java代碼 ?收藏代碼


? ? ??


@Before ?


public void setUp() { ?


? ? String createTableSql = "create memory table test" + ?


? ? "(id int GENERATED BY DEFAULT AS IDENTITY PRIMARY KEY, " + ?


? ? "name varchar(100))"; ?


? ? jdbcTemplate.update(createTableSql); ?


? ? ? ? ?


? ? String createHsqldbFunctionSql = ?


? ? ? "CREATE FUNCTION FUNCTION_TEST(str CHAR(100)) " + ?


? ? ? "returns INT begin atomic return length(str);end"; ?


? ? jdbcTemplate.update(createHsqldbFunctionSql); ?


? ? String createHsqldbProcedureSql = ?


? ? ? "CREATE PROCEDURE PROCEDURE_TEST" + ?


? ? ? "(INOUT inOutName VARCHAR(100), OUT outId INT) " + ?


? ? ? "MODIFIES SQL DATA " + ?


? ? ? "BEGIN ATOMIC " + ?


? ? ? " ?insert into test(name) values (inOutName); " + ?


? ? ? " ?SET outId = IDENTITY(); " + ?


? ? ? " ?SET inOutName = 'Hello,' + inOutName; " + ?


? ? "END"; ?


? ? jdbcTemplate.execute(createHsqldbProcedureSql); ?


} ?


?
? ? ? ?其中CREATE FUNCTION FUNCTION_TEST用于創建自定義函數,CREATE PROCEDURE PROCEDURE_TEST


用于創建存儲過程,注意這些創建語句是數據庫相關的,本示例中的語句只適用于HSQLDB數據庫。
?
? ? ? ?其次修改JdbcTemplateTest的tearDown方法,修改后如下所示:
?
java代碼:


Java代碼 ?收藏代碼




public void tearDown() { ?


? ? jdbcTemplate.execute("DROP FUNCTION FUNCTION_TEST"); ?


? ? jdbcTemplate.execute("DROP PROCEDURE PROCEDURE_TEST"); ?


? ? String dropTableSql = "drop table test"; ?


? ? jdbcTemplate.execute(dropTableSql); ?


} ?


?
? ? ? ?其中drop語句用于刪除創建的存儲過程、自定義函數及數據庫表。
?
? ? ? ?接下來看一下hsqldb如何調用自定義函數:
?
java代碼:


Java代碼 ?收藏代碼




public void testCallableStatementCreator1() { ?


? ? final String callFunctionSql = "{call FUNCTION_TEST(?)}"; ?


? ? List<SqlParameter> params = new ArrayList<SqlParameter>(); ?


? ? params.add(new SqlParameter(Types.VARCHAR)); ?


? ? params.add(new SqlReturnResultSet("result", ?


? ? ? ?new ResultSetExtractor<Integer>() { ?


? ? ? ? ? ?@Override ?


? ? ? ? ? ?public Integer extractData(ResultSet rs) throws SQLException, ?


? ? ? ? ? ? ? ?DataAccessException { ?


? ? ? ? ? ? ? ?while(rs.next()) { ?


? ? ? ? ? ? ? ? ? ?return rs.getInt(1); ?


? ? ? ? ? ? ? ?} ?


? ? ? ? ? ? ? return 0; ?


? ? ? ?})); ?


? ? Map<String, Object> outValues = jdbcTemplate.call( ?


? ? ? ?new CallableStatementCreator() { ?


? ? ? ? ? ? @Override ?


? ? ? ? ? ? public CallableStatement createCallableStatement(Connection conn) throws?


SQLException { ?


? ? ? ? ? ? ? CallableStatement cstmt = conn.prepareCall(callFunctionSql); ?


? ? ? ? ? ? ? cstmt.setString(1, "test"); ?


? ? ? ? ? ? ? return cstmt; ?


? ? }}, params); ?


? ? Assert.assertEquals(4, outValues.get("result")); ?


} ?


? ?


?
{call FUNCTION_TEST(?)}:定義自定義函數的sql語句,注意hsqldb {?= call …}和{call …}含義是


一樣的,而比如mysql中兩種含義是不一樣的;


params:用于描述自定義函數占位符參數或命名參數類型;SqlParameter用于描述IN類型參數、


SqlOutParameter用于描述OUT類型參數、SqlInOutParameter用于描述INOUT類型參數、


SqlReturnResultSet用于描述調用存儲過程或自定義函數返回的ResultSet類型數據,其中


SqlReturnResultSet需要提供結果集處理回調用于將結果集轉換為相應的形式,hsqldb自定義函數返回


值是ResultSet類型。


CallableStatementCreator:提供Connection對象用于創建CallableStatement對象


outValues:調用call方法將返回類型為Map<String, Object>對象;


outValues.get("result"):獲取結果,即通過SqlReturnResultSet對象轉換過的數據;其中


SqlOutParameter、SqlInOutParameter、SqlReturnResultSet指定的name用于從call執行后返回的Map中


獲取相應的結果,即name是Map的鍵。


注:因為hsqldb {?= call …}和{call …}含義是一樣的,因此調用自定義函數將返回一個包含結果的


ResultSet。
?
最后讓我們示例下mysql如何調用自定義函數:
?
java代碼:


Java代碼 ?收藏代碼




public void testCallableStatementCreator2() { ?


? ? JdbcTemplate mysqlJdbcTemplate = new JdbcTemplate(getMysqlDataSource); ?


? ? //2.創建自定義函數 ?


String createFunctionSql = ?


? ? "CREATE FUNCTION FUNCTION_TEST(str VARCHAR(100)) " + ?


? ? ?"returns INT return LENGTH(str)"; ?


String dropFunctionSql = "DROP FUNCTION IF EXISTS FUNCTION_TEST"; ?


mysqlJdbcTemplate.update(dropFunctionSql); ? ? ? ??


mysqlJdbcTemplate.update(createFunctionSql); ?


//3.準備sql,mysql支持{?= call …} ?


final String callFunctionSql = "{?= call FUNCTION_TEST(?)}"; ?


//4.定義參數 ?


List<SqlParameter> params = new ArrayList<SqlParameter>(); ?


params.add(new SqlOutParameter("result", Types.INTEGER)); ?


params.add(new SqlParameter("str", Types.VARCHAR)); ?


Map<String, Object> outValues = mysqlJdbcTemplate.call( ?


new CallableStatementCreator() { ?


? ? @Override ?


? ? public CallableStatement createCallableStatement(Connection conn) throws SQLException {?


?


? ? ? CallableStatement cstmt = conn.prepareCall(callFunctionSql); ?


? ? ? cstmt.registerOutParameter(1, Types.INTEGER); ?


? ? ? cstmt.setString(2, "test"); ?


? ? ? ? return cstmt; ?


? ? }}, params); ?


? ?Assert.assertEquals(4, outValues.get("result")); ?


} ?


public DataSource getMysqlDataSource() { ?


? ? String url = "jdbc:mysql://localhost:3306/test"; ?


? ? DriverManagerDataSource dataSource = ?


? ? ? ? new DriverManagerDataSource(url, "root", ""); ? ? dataSource.setDriverClassName


("com.mysql.jdbc.Driver"); ?


? ? return dataSource; ?


} ?


? ?


getMysqlDataSource:首先啟動mysql(本書使用5.4.3版本),其次登錄mysql創建test數據庫


(“create database test;”),在進行測試前,請先下載并添加mysql-connector-java-5.1.10.jar


到classpath;


{?= call FUNCTION_TEST(?)}:可以使用{?= call …}形式調用自定義函數;


params:無需使用SqlReturnResultSet提取結果集數據,而是使用SqlOutParameter來描述自定義函數返


回值;


CallableStatementCreator:同上個例子含義一樣;


cstmt.registerOutParameter(1, Types.INTEGER):將OUT類型參數注冊為JDBC類型Types.INTEGER,此


處即返回值類型為Types.INTEGER。


outValues.get("result"):獲取結果,直接返回Integer類型,比hsqldb簡單多了吧。


?
最后看一下如何如何調用存儲過程:
?
java代碼:


Java代碼 ?收藏代碼




public void testCallableStatementCreator3() { ?


? ? final String callProcedureSql = "{call PROCEDURE_TEST(?, ?)}"; ?


? ? List<SqlParameter> params = new ArrayList<SqlParameter>(); ?


? ? params.add(new SqlInOutParameter("inOutName", Types.VARCHAR)); ?


? ? params.add(new SqlOutParameter("outId", Types.INTEGER)); ?


? ? Map<String, Object> outValues = jdbcTemplate.call( ?


? ? ? new CallableStatementCreator() { ?


? ? ? ? @Override ?


? ? ? ? public CallableStatement createCallableStatement(Connection conn) throws?


SQLException { ?


? ? ? ? ? CallableStatement cstmt = conn.prepareCall(callProcedureSql); ?


? ? ? ? ? cstmt.registerOutParameter(1, Types.VARCHAR); ?


? ? ? ? ? cstmt.registerOutParameter(2, Types.INTEGER); ?


? ? ? ? ? cstmt.setString(1, "test"); ?


? ? ? ? ? return cstmt; ?


? ? }}, params); ?


? ? Assert.assertEquals("Hello,test", outValues.get("inOutName")); ?


? ? Assert.assertEquals(0, outValues.get("outId")); ?


} ?


? ?


{call PROCEDURE_TEST(?, ?)}:定義存儲過程sql;


params:定義存儲過程參數;SqlInOutParameter描述INOUT類型參數、SqlOutParameter描述OUT類型參


數;


CallableStatementCreator:用于創建CallableStatement,并設值及注冊OUT參數類型;


outValues:通過SqlInOutParameter及SqlOutParameter參數定義的name來獲取存儲過程結果。


?
? ? ? ?JdbcTemplate類還提供了很多便利方法,在此就不一一介紹了,但這些方法是由規律可循的,第


一種就是提供回調接口讓用戶決定做什么,第二種可以認為是便利方法(如queryForXXX),用于那些比


較簡單的操作。
========

使用Spring的jdbcTemplate進一步簡化JDBC操作

http://www.cnblogs.com/Fskjb/archive/2009/11/18/1605622.html


先看applicationContext.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-2.5.xsd"><bean id="springDSN"class="org.springframework.jdbc.datasource.DriverManagerDataSource"><property name="driverClassName"value="com.microsoft.jdbc.sqlserver.SQLServerDriver"></property><property name="url"value="jdbc:microsoft:sqlserver://localhost:1433;databasename=bbs"></property><property name="username" value="sa"></property><property name="password" value="sa"></property></bean><bean id="jdbcTemplate"class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"lazy-init="false" autowire="default" dependency-check="default"><property name="dataSource"><ref bean="springDSN" /></property></bean> </beans>

在看SpringUtil類?
package com.r.dao;import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext;public final class SpringUtil {private static ApplicationContext ctx = new ClassPathXmlApplicationContext("applicationContext.xml");public static Object getBean(String beanName){return ctx.getBean(beanName);} }
?
最后看DAO:
import java.math.BigDecimal; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Map;import org.springframework.jdbc.core.JdbcTemplate;import com.r.vo.Book;public class BookDao {private JdbcTemplate jdbcT = (JdbcTemplate) SpringUtil.getBean("jdbcTemplate");public List findALL() {String sql = "select * from BookInfo";return jdbcT.queryForList(sql); }public List<Book> findALLBooks() {List<Book> books = new ArrayList<Book>();;String sql = "select * from BookInfo";List list = jdbcT.queryForList(sql); Iterator iterator = list.iterator();Book book = null;while (iterator.hasNext()) {Map map4book = (Map) iterator.next();book = new Book();book.setBid((Integer) map4book.get("bid"));book.setBookName((String)map4book.get("bookName"));book.setBookType((String)map4book.get("bookType")); book.setBookPic(((BigDecimal)map4book.get("bookPic")).doubleValue() ); book.setCount((Integer) map4book.get("count"));books.add(book);}return books;} public int delete(int bid){String sql = "delete from BookInfo where bid =?";return jdbcT.update(sql, new Object[]{bid});} public static void main(String[] args) { List<Book> books = new BookDao().findALLBooks();;for(Book book:books){System.out.println(book.getBid()+","+book.getBookName()+","+book.getBookType());}} }
?
細心你,會發現JdbcTemplate的實例中有一系列的方法如:queryForXXX,update,delete大大簡化了JDBC


操作。


當然,還可以再進一步的優化一下,就是通過依賴注入,直接把jdbcTemplate注入到dao類的jdbcT字段。


先看新的applicationContext.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-2.5.xsd">


? ? <bean id="springDSN"
? ? ? ? class="org.springframework.jdbc.datasource.DriverManagerDataSource">
? ? ? ? <property name="driverClassName"
? ? ? ? ? ? value="com.microsoft.jdbc.sqlserver.SQLServerDriver">
? ? ? ? </property>
? ? ? ? <property name="url"
? ? ? ? ? ? value="jdbc:microsoft:sqlserver://localhost:1433;databasename=bbs">
? ? ? ? </property>
? ? ? ? <property name="username" value="sa"></property>
? ? ? ? <property name="password" value="sa"></property>
? ? </bean>


? ? <bean id="jdbcTemplate"
? ? ? ? class="org.springframework.jdbc.core.JdbcTemplate" abstract="false"
? ? ? ? lazy-init="false" autowire="default" dependency-check="default">
? ? ? ? <property name="dataSource">
? ? ? ? ? ? <ref bean="springDSN" />
? ? ? ? </property>
? ? </bean>


? ? <bean id="bookDao" class="com.yy.struts.dao.BookDao">
? ? ? ?<property name="jdbcT">
? ? ? ? ? <ref bean="jdbcTemplate" />
? ? ? ?</property>
? ? </bean>
</beans>
復制代碼
?那么新的DAO類:


復制代碼
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;


import org.springframework.jdbc.core.JdbcTemplate;


import com.r.vo.Book;


public class BookDao {


? ? private JdbcTemplate jdbcT;


? ? public List findALL() {
? ? ? ? String sql = "select * from BookInfo";
? ? ? ? return jdbcT.queryForList(sql); ? ? ? ?
? ? }


? ? public List<Book> findALLBooks() {
? ? ? ? List<Book> books = new ArrayList<Book>();;
? ? ? ? String sql = "select * from BookInfo";
? ? ? ? List list = jdbcT.queryForList(sql);?
? ? ? ? Iterator iterator = list.iterator();
? ? ? ? Book book = null;
? ? ? ? while (iterator.hasNext()) {
? ? ? ? ? ? Map map4book = (Map) iterator.next();
? ? ? ? ? ? book = new Book();
? ? ? ? ? ? book.setBid((Integer) map4book.get("bid"));
? ? ? ? ? ? book.setBookName((String)map4book.get("bookName"));
? ? ? ? ? ? book.setBookType((String)map4book.get("bookType")); ? ? ? ?
? ? ? ? ? ? book.setBookPic(((BigDecimal)map4book.get("bookPic")).doubleValue() ); ? ? ? ? ?


??
? ? ? ? ? ? book.setCount((Integer) map4book.get("count"));
? ? ? ? ? ? books.add(book);
? ? ? ? }
? ? ? ? return books;
? ? } ? ?
? ? public int delete(int bid){
? ? ? ? String sql = "delete from BookInfo where bid =?";
? ? ? ? return jdbcT.update(sql, new Object[]{bid});
? ? } ? ??
? ? public static void main(String[] args) { ? ? ? ?
? ? ? ? List<Book> books = new BookDao().findALLBooks();;
? ? ? ? for(Book book:books){
? ? ? ? ? ? System.out.println(book.getBid()+","+book.getBookName()+","+book.getBookType


());
? ? ? ? }
? ? }
}
復制代碼
?


?通過依賴注入,對象之間的關系由SPRING來維護,這樣能降低類與類的耦合度
========

JdbcTemplate學習筆記



1、使用JdbcTemplate的execute()方法執行SQL語句


Java 代碼
? ??
jdbcTemplate.execute("CREATE TABLE USER (user_id integer, name varchar(100))");
? ??
jdbcTemplate.execute("CREATE TABLE USER (user_id integer, name varchar(100))"); ?
2、如果是UPDATE或INSERT,可以用update()方法。


Java 代碼
? ??
jdbcTemplate.update("INSERT INTO USER VALUES('" ?
? ??
+ user.getId() + "', '" ?
? ??
+ user.getName() + "', '" ?
? ??
+ user.getSex() + "', '" ?
? ??
+ user.getAge() + "')"); ?
? ??
jdbcTemplate.update("INSERT INTO USER VALUES('" ?
? ??
+ user.getId() + "', '" ?
? ??
+ user.getName() + "', '" ?
? ??
+ user.getSex() + "', '" ?
? ??
+ user.getAge() + "')"); ?
3、帶參數的更新


Java代碼
? ??
jdbcTemplate.update("UPDATE USER SET name = ? WHERE user_id = ?", new Object[] {name, id});?


? ?
? ??
jdbcTemplate.update("UPDATE USER SET name = ? WHERE user_id = ?", new Object[] {name, id});?


?
Java代碼
? ??
jdbcTemplate.update("INSERT INTO USER VALUES(?, ?, ?, ?)", new Object[] {user.getId(),?


user.getName(), user.getSex(), user.getAge()}); ? ?
? ??
jdbcTemplate.update("INSERT INTO USER VALUES(?, ?, ?, ?)", new Object[] {user.getId(),?


user.getName(), user.getSex(), user.getAge()}); ?
4、使用JdbcTemplate進行查詢時,使用queryForXXX()等方法


Java代碼
? ??
int count = jdbcTemplate.queryForInt("SELECT COUNT(*) FROM USER"); ? ?
? ??
int count = jdbcTemplate.queryForInt("SELECT COUNT(*) FROM USER"); ?
Java代碼
? ??
String name = (String) jdbcTemplate.queryForObject("SELECT name FROM USER WHERE user_id =?


?", new Object[] {id}, java.lang.String.class); ? ?
? ??
String name = (String) jdbcTemplate.queryForObject("SELECT name FROM USER WHERE user_id =?


?", new Object[] {id}, java.lang.String.class); ?
Java代碼
? ??
List rows = jdbcTemplate.queryForList("SELECT * FROM USER"); ? ?
? ??
List rows = jdbcTemplate.queryForList("SELECT * FROM USER"); ?
Java代碼
? ??
List rows = jdbcTemplate.queryForList("SELECT * FROM USER"); ?
? ??
Iterator it = rows.iterator(); ?
? ??
while(it.hasNext()) { ?
? ??
Map userMap = (Map) it.next(); ?
? ??
System.out.print(userMap.get("user_id") + "\t"); ?
? ??
System.out.print(userMap.get("name") + "\t"); ?
? ??
System.out.print(userMap.get("sex") + "\t"); ?
? ??
System.out.println(userMap.get("age") + "\t"); ?
? ??
} ?
? ??
??
? ??
List rows = jdbcTemplate.queryForList("SELECT * FROM USER"); ?
? ??
??
? ??
Iterator it = rows.iterator(); ?
? ??
while(it.hasNext()) { ?
? ??
Map userMap = (Map) it.next(); ?
? ??
System.out.print(userMap.get("user_id") + "\t"); ?
? ??
System.out.print(userMap.get("name") + "\t"); ?
? ??
System.out.print(userMap.get("sex") + "\t"); ?
? ??
System.out.println(userMap.get("age") + "\t");?
? ??
? ??
} ?
JdbcTemplate將我們使用的JDBC的流程封裝起來,包括了異常的捕捉、SQL的執行、查詢結果的轉換等等


。spring大量使用Template Method模式來封裝固定流程的動作,XXXTemplate等類別都是基于這種方式


的實現。


除了大量使用Template Method來封裝一些底層的操作細節,spring也大量使用callback方式類回調相關


類別的方法以提供JDBC相關類別的功能,使傳統的JDBC的使用者也能清楚了解spring所提供的相關封裝


類別方法的使用。


JDBC的PreparedStatement


Java代碼
? ??
final String id = user.getId(); ? ?
? ??
final String name = user.getName(); ? ?
? ??
final String sex = user.getSex() + ""; ? ?
? ??
final int age = user.getAge(); ?
? ??
??
? ??
jdbcTemplate.update("INSERT INTO USER VALUES(?, ?, ?, ?)", ?
? ??
??
? ??
new PreparedStatementSetter() { ? ?
? ??
public void setValues(PreparedStatement ps) throws SQLException { ? ?
? ??
ps.setString(1, id); ?
? ??
ps.setString(2, name); ?
? ??
ps.setString(3, sex); ?
? ??
ps.setInt(4, age); ?
? ??
} ?
? ??
}); ?
? ??
??
? ??
final String id = user.getId(); ?
? ??
final String name = user.getName(); ?
? ??
final String sex = user.getSex() + ""; ?
? ??
final int age = user.getAge(); ?
? ??
? ??
? ??
jdbcTemplate.update("INSERT INTO USER VALUES(?, ?, ?, ?)", ?
? ??
? ??
? ??
new PreparedStatementSetter() { ? ? ?
? ??
public void setValues(PreparedStatement ps) throws SQLException { ? ?
? ??
ps.setString(1, id); ? ?
? ??
ps.setString(2, name); ? ? ?
? ??
ps.setString(3, sex); ? ?
? ??
ps.setInt(4, age); ? ? ?
? ??
} ? ?
? ??
}); ? ? ? ?
Java代碼
? ??
final User user = new User(); ? ? ?
? ??
jdbcTemplate.query("SELECT * FROM USER WHERE user_id = ?", ? ?
? ??
new Object[] {id}, ? ?
? ??
new RowCallbackHandler() { ? ?
? ??
public void processRow(ResultSet rs) throws SQLException { ? ?
? ??
user.setId(rs.getString("user_id")); ?
? ??
user.setName(rs.getString("name")); ?
? ??
user.setSex(rs.getString("sex").charAt(0)); ? ?
? ??
user.setAge(rs.getInt("age")); ? ?
? ??
} ?
? ??
}); ?
? ??
??
? ??
final User user = new User(); ?
? ??
? ??
? ??
jdbcTemplate.query("SELECT * FROM USER WHERE user_id = ?", ? ?
? ??
new Object[] {id}, ? ? ?
? ??
new RowCallbackHandler() { ?
? ??
??
? ??
??
? ??
public void processRow(ResultSet rs) throws SQLException { ? ?
? ??
user.setId(rs.getString("user_id")); ? ?
? ??
user.setName(rs.getString("name")); ? ?
? ??
user.setSex(rs.getString("sex").charAt(0)); ? ?
? ??
user.setAge(rs.getInt("age")); ? ?
? ??
} ? ?
? ??
}); ?
Java代碼
? ??
class UserRowMapper implements RowMapper { ?
? ??
??
? ??
public Object mapRow(ResultSet rs, int index) throws SQLException { ?
? ??
??
? ??
User user = new User(); ?
? ??
user.setId(rs.getString("user_id")); ? ? ?
? ??
user.setName(rs.getString("name")); ? ?
? ??
user.setSex(rs.getString("sex").charAt(0)); ? ? ?
? ??
user.setAge(rs.getInt("age")); ? ? ?
? ??
return user; ? ? ? ??
? ??
} ? ? ? ??
? ??
} ?
? ??
? ??
? ??
public List findAllByRowMapperResultReader() { ? ? ?
? ??
??
? ??
String sql = "SELECT * FROM USER"; ?
? ??
??
? ??
return jdbcTemplate.query(sql, new RowMapperResultReader(new UserRowMapper())); ?
? ??
??
? ??
} ?
? ??
??
? ??
class UserRowMapper implements RowMapper { ?
? ??
??
? ??
public Object mapRow(ResultSet rs, int index) throws SQLException { ?
? ??
User user = new User(); ? ?
? ??
user.setId(rs.getString("user_id")); ? ?
? ??
user.setName(rs.getString("name")); ? ?
? ??
user.setSex(rs.getString("sex").charAt(0)); ? ?
? ??
user.setAge(rs.getInt("age")); ? ?
? ??
return user; ? ?
? ??
} ? ?
? ??
} ?
? ??
??
? ??
public List findAllByRowMapperResultReader() { ? ? ?
? ??
String sql = "SELECT * FROM USER"; ? ?
? ??
return jdbcTemplate.query(sql, new RowMapperResultReader(new UserRowMapper())); ?
? ??
} ?
在getUser(id)里面使用UserRowMapper


Java代碼
? ??
public User getUser(final String id) throws DataAccessException { ? ?
? ??
String sql = "SELECT * FROM USER WHERE user_id=?"; ? ?
? ??
final Object[] params = new Object[] { id }; ? ?
? ??
List list = jdbcTemplate.query(sql, params, new RowMapperResultReader(new UserRowMapper


())); ? ? ?
? ??
return (User) list.get(0); ? ?
? ??
}
? ??
??
? ??
public User getUser(final String id) throws DataAccessException { ?
? ??
String sql = "SELECT * FROM USER WHERE user_id=?"; ? ? ?
? ??
final Object[] params = new Object[] { id }; ? ? ?
? ??
List list = jdbcTemplate.query(sql, params, new RowMapperResultReader(new UserRowMapper


())); ? ? ?
? ??
return (User) list.get(0); ? ? ?
? ??
}
網上收集


org.springframework.jdbc.core.PreparedStatementCreator 返回預編譯SQL 不能于Object[]一起用


Java代碼
? ??
public PreparedStatement createPreparedStatement(Connection con) throws SQLException { ? ?
? ??
return con.prepareStatement(sql); ? ?
? ??
} ?
? ??
??
? ??
public PreparedStatement createPreparedStatement(Connection con) throws SQLException { ? ?
? ??
return con.prepareStatement(sql); ? ?
? ??
} ?
1.增刪改


org.springframework.jdbc.core.JdbcTemplate 類(必須指定數據源dataSource)


Java代碼
? ??
template.update("insert into web_person values(?,?,?)",Object[]); ? ?
? ??
template.update("insert into web_person values(?,?,?)",Object[]); ?
? ??



Java代碼
? ??
template.update("insert into web_person values(?,?,?)",new PreparedStatementSetter(){ //匿


名內部類 只能訪問外部最終局部變量 ? ?
? ??
public void setValues(PreparedStatement ps) throws SQLException { ? ?
? ??
ps.setInt(index++,3); ? ?
? ??
}); ?
? ??
??
? ??
template.update("insert into web_person values(?,?,?)",new PreparedStatementSetter(){ //匿


名內部類 只能訪問外部最終局部變量 ?
? ??
??
? ??
public void setValues(PreparedStatement ps) throws SQLException { ? ?
? ??
ps.setInt(index++,3); ? ?
? ??
}); ?
? ??
??
? ??
org.springframework.jdbc.core.PreparedStatementSetter //接口 處理預編譯SQL ? ? ? ?
? ??
public void setValues(PreparedStatement ps) throws SQLException { ? ?
? ??
ps.setInt(index++,3); ? ?
? ??
} ?
? ??
??
? ??
public void setValues(PreparedStatement ps) throws SQLException { ? ?
? ??
ps.setInt(index++,3); ? ?
? ??
} ?
2.查詢JdbcTemplate.query(String,[Object


[]/PreparedStatementSetter],RowMapper/RowCallbackHandler)


org.springframework.jdbc.core.RowMapper 記錄映射接口 處理結果集


Java代碼
? ??
public Object mapRow(ResultSet rs, int arg1) throws SQLException { //int表當前行數 ? ?
? ??
person.setId(rs.getInt("id")); ? ?
? ??
} ? ?
? ??
List template.query("select * from web_person where id=?",Object[],RowMapper); ? ?
? ??
public Object mapRow(ResultSet rs, int arg1) throws SQLException { //int表當前行數 ? ?
? ??
person.setId(rs.getInt("id")); ? ?
? ??
} ? ?
? ??
List template.query("select * from web_person where id=?",Object[],RowMapper); ?
org.springframework.jdbc.core.RowCallbackHandler 記錄回調管理器接口 處理結果集


Java代碼
? ??
template.query("select * from web_person where id=?",Object[],new RowCallbackHandler(){ ? ?
? ??
public void processRow(ResultSet rs) throws SQLException { ? ?
? ??
person.setId(rs.getInt("id")); ? ?
? ??
}); ?
======== 《新程序員》:云原生和全面數字化實踐50位技術專家共同創作,文字、視頻、音頻交互閱讀

總結

以上是生活随笔為你收集整理的jdbc template 学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

免费的黄色的网站 | 青青河边草免费直播 | 日韩动态视频 | 最新中文字幕 | av 一区二区三区 | 亚洲精品免费在线 | 精品久久久久久久久亚洲 | 五月天色站 | 最近中文字幕第一页 | www.888av| 欧美日韩中文在线观看 | 一区中文字幕在线观看 | 一区二区三区av在线 | 日韩一级电影在线观看 | 日韩成人精品一区二区三区 | 精品国产一区二区三区免费 | 97在线公开视频 | 高清视频一区 | 日韩欧美一区二区在线播放 | 久久99影院| 欧美精品久久久久久久久久白贞 | 美女国产免费 | 久久伊人操 | 久久久午夜精品理论片中文字幕 | 香蕉视频免费在线播放 | 亚洲第一av在线播放 | 亚洲国产婷婷 | 久久精品91久久久久久再现 | 97超碰福利久久精品 | 97超碰在线播放 | 欧美日韩国产一二三区 | 国产一级视频免费看 | 国产精品久久久久aaaa | 久久成人亚洲欧美电影 | 日韩一级片大全 | 亚州av网站大全 | 色综合天天射 | 草久在线播放 | 丁香五婷 | 色狠狠久久av五月综合 | 欧美成人理伦片 | av成人免费网站 | 最近更新好看的中文字幕 | 日本公妇色中文字幕 | 激情九九| 色综合夜色一区 | 久久精品成人欧美大片古装 | 天天操月月操 | 久久国产精品久久精品 | 久久免费99 | 日韩免费电影一区二区 | 精品99在线视频 | 99热在| 久草在线久草在线2 | 又黄又爽免费视频 | 黄色毛片电影 | 国产午夜精品理论片在线 | 在线观看午夜av | 国产99久久九九精品免费 | 丁香婷婷综合色啪 | 精品视频专区 | 成人一区二区三区中文字幕 | 国产精品一区在线观看你懂的 | 亚洲精品乱码久久久久久蜜桃动漫 | 三上悠亚一区二区在线观看 | 国产区高清在线 | 在线 影视 一区 | www.夜夜操.com | 国产精品大尺度 | 亚洲黄色免费 | 亚洲传媒在线 | av免费电影在线 | 欧美日韩一级久久久久久免费看 | 国产精品久久久久久久午夜 | 香蕉久久国产 | 综合激情av| 婷婷六月综合亚洲 | 欧美亚洲成人免费 | 亚洲午夜av | 精品国产区 | 日韩在线观看一区二区 | 手机看片国产日韩 | 久久草精品 | 五月天久久综合网 | av一本久道久久波多野结衣 | 国产精品综合久久 | 在线日本v二区不卡 | 国产日韩中文在线 | 91视频91蝌蚪 | 丝袜美腿在线视频 | 欧美三级高清 | 人人爽人人乐 | 日韩黄色在线电影 | 天天av在线播放 | 亚洲一区二区精品 | 亚洲狠狠操 | 中文字幕在线看片 | 在线观看岛国片 | 免费三级av| 欧美一区二区在线免费观看 | 色多多视频在线观看 | 五月天六月婷婷 | 中文在线天堂资源 | 欧美xxxxx在线视频 | 亚洲成人av影片 | 99视频在线精品国自产拍免费观看 | 婷婷资源站| 国产精品精品国产婷婷这里av | 免费日韩在线 | 欧美精品乱码99久久影院 | 国产在线一线 | 成年人黄色在线观看 | 中文国产字幕在线观看 | 欧美日韩另类在线 | 91夜夜夜 | 亚洲视频综合 | 天天爽网站 | 国产传媒一区在线 | 国产精品va在线播放 | 三三级黄色片之日韩 | 久色小说 | 日韩中文字幕免费视频 | 成人一级免费电影 | 少妇bbbb搡bbbb搡bbbb | 人人看人人| 日日干 天天干 | 91大片网站 | www.久久久.cum| 国内免费久久久久久久久久久 | 99精品在这里 | 天天干天天干天天干天天干天天干天天干 | 天天玩天天操天天射 | 蜜臀av免费一区二区三区 | 久久国产品 | 99久久日韩精品视频免费在线观看 | 久久精品电影网 | 午夜精品久久久 | 伊人天堂av | 精品综合久久 | 91在线看视频 | 久久夜夜操 | 91精品国产综合久久福利 | www.一区二区三区 | 九九热视频在线播放 | 国产色爽 | 欧美巨乳网 | 在线观看网站黄 | 久久婷婷激情 | 久草在线网址 | 美女久久久 | 色综合天天视频在线观看 | 国产日产精品一区二区三区四区 | 91成人观看| 国内精品久久影院 | 久久综合九色综合久99 | 91资源在线视频 | 国产精品一区二区吃奶在线观看 | 91九色蝌蚪视频 | 亚洲乱码国产乱码精品天美传媒 | 日韩欧美国产精品 | 免费黄色在线网址 | 久99久视频| 91成人在线看 | 亚洲国产欧美在线人成大黄瓜 | 成人永久在线 | 日日干日日 | 国产资源中文字幕 | 日韩三级中文字幕 | 中文在线资源 | 国产主播大尺度精品福利免费 | 97超碰福利久久精品 | 在线电影 一区 | 久久久久久麻豆 | 欧洲精品视频一区二区 | 久久不卡国产精品一区二区 | 探花视频在线观看+在线播放 | 亚洲国产大片 | 五月天激情电影 | 国产1区在线观看 | 天天射天天干天天插 | 免费日p视频 | 99精品久久精品一区二区 | 日韩av一区二区三区在线观看 | 一色屋精品视频在线观看 | 99精品国产免费久久久久久下载 | 国产原创在线 | 黄色毛片观看 | 丁香婷婷电影 | 国产毛片久久久 | 久草在线中文888 | 在线观看视频色 | 日韩精品一区二区三区外面 | 这里只有精品视频在线 | 日韩精品久久久久久中文字幕8 | 精品国产aⅴ一区二区三区 在线直播av | 国产二区视频在线观看 | 91av小视频 | 成人在线电影观看 | 国产亚洲成人网 | 中文字幕乱码视频 | 最新日韩中文字幕 | 久久艹影院 | 青青啪 | 久久久精品日本 | 性色av免费在线观看 | 97免费在线观看视频 | 欧美在线日韩在线 | 欧美乱大交 | 97日日碰人人模人人澡分享吧 | 91xav| av电影中文 | 午夜美女福利 | 黄色录像av | 国产精品毛片一区二区在线 | 午夜国产在线观看 | 日本精品一二区 | 日韩三级中文字幕 | 日韩久久在线 | 99色资源 | 日韩电影在线观看中文字幕 | 婷婷国产在线观看 | 久久夜色精品国产欧美一区麻豆 | 日本三级香港三级人妇99 | 91亚洲视频在线观看 | 伊人色**天天综合婷婷 | 亚洲精品视频在线观看免费视频 | 菠萝菠萝在线精品视频 | 激情视频91 | 日韩国产精品一区 | 中文字幕av一区二区三区四区 | 尤物97国产精品久久精品国产 | 亚洲成人午夜av | 天天天天干| 亚洲精品高清在线 | 久久久久久久久免费 | 5月丁香婷婷综合 | 亚洲精品videossex少妇 | 午夜精选视频 | 五月宗合网 | 人人爱人人添 | 黄色软件在线观看免费 | 国产精品破处视频 | 久草视频资源 | 成人av在线网址 | 日本系列中文字幕 | 国产破处在线视频 | 91伊人影院 | 国产一区二区久久久 | 在线最新av| 日韩三级成人 | 五月婷亚洲 | 在线观看视频你懂得 | 超碰免费在线公开 | 中文字幕精 | 亚洲精品五月天 | 午夜性生活片 | 日韩视频一二三区 | 亚洲五月| 视频在线一区二区三区 | 久久avav| 91污污| 久久精品婷婷 | 久99久中文字幕在线 | 欧美一二三区在线播放 | 毛片.com| 日韩精品久久中文字幕 | 国产亚洲高清视频 | 欧美大片在线观看一区 | 麻豆一精品传二传媒短视频 | 免费视频久久久久 | 视频在线观看99 | 欧洲黄色片 | 日韩av在线不卡 | 欧美日韩精品电影 | 欧美日韩国产高清视频 | 欧美a在线免费观看 | 亚洲理论片在线观看 | 特级aaa毛片 | 免费av在 | 国产手机在线精品 | 中文字幕第一页在线播放 | 亚洲伦理一区 | 久久精品中文字幕免费mv | 在线观看你懂的网站 | 一区二区三区高清不卡 | 午夜.dj高清免费观看视频 | 精品五月天 | 国产一区二区三区高清播放 | 天堂av在线网址 | 免费观看版| 99精品福利视频 | 亚洲精区二区三区四区麻豆 | 国产糖心vlog在线观看 | 爱爱av在线| 国产精品麻豆果冻传媒在线播放 | 91在线porny国产在线看 | 久久夜色精品国产欧美乱极品 | 国产一区二区在线免费 | 一区在线播放 | www.av小说| 久久人人97超碰精品888 | 国产97在线观看 | 日韩精品亚洲专区在线观看 | 看片一区二区三区 | 欧美日韩精品区 | 国产视频在线播放 | 国产精品午夜免费福利视频 | 国产伦理久久精品久久久久_ | 日韩在线视频免费播放 | 天天摸天天操天天舔 | 在线一级片 | 激情综合电影网 | 麻豆传媒视频在线 | 精品专区 | 久久美女精品 | 欧美另类高清 videos | 麻豆视频入口 | 激情综合中文娱乐网 | 91精品爽啪蜜夜国产在线播放 | 超碰97国产 | 在线免费视 | 国产成人一区二区啪在线观看 | 久久精品男人的天堂 | 欧美激情精品久久 | 精品国产成人av在线免 | 日本久久综合视频 | 成人啪啪18免费游戏链接 | 午夜精品一区二区三区四区 | av一区二区在线观看中文字幕 | 伊人五月综合 | 日批在线观看 | 日日夜夜人人精品 | 在线播放91 | 9i看片成人免费看片 | 久久不射电影网 | 成人在线免费小视频 | 在线a亚洲视频播放在线观看 | 人人插人人爱 | 人人狠| 日日操网站 | 玖玖视频精品 | 免费视频91蜜桃 | 探花视频网站 | 国产亚洲精品福利 | 人人澡人人爽 | 亚洲jizzjizz日本少妇 | 一级做a爱片性色毛片www | 亚洲九九爱 | 超碰97在线资源 | 在线观看国产福利片 | 黄av在线| 国产在线探花 | 黄色官网在线观看 | av高清一区 | 色综合久久精品 | 国产999久久久 | 亚洲国产日韩欧美在线 | 99久久99久久综合 | 激情在线网址 | 国内久久久久久 | 日韩在线第一区 | 久草在线欧美 | 1000部国产精品成人观看 | 狠狠狠操| 伊人www22综合色 | 国产xvideos免费视频播放 | 亚洲成人精品国产 | 国产黄色在线网站 | 久久精品国产免费看久久精品 | 香蕉视频在线免费看 | 成人久久18免费网站 | 91麻豆精品国产91久久久更新时间 | 最新三级在线 | 日韩理论电影在线 | 午夜精品一区二区三区在线 | 国产精品二区三区 | 久久精品1区 | 国产区精品在线观看 | 久久视频免费在线观看 | 国产精品大片免费观看 | 国产又粗又猛又爽又黄的视频先 | 69精品在线 | 国产91精品久久久久 | 免费看片在线观看 | 夜夜澡人模人人添人人看 | 亚洲国产成人久久 | 高清国产午夜精品久久久久久 | 黄色成人影院 | 国产精品自产拍在线观看桃花 | 九色最新网址 | 夜夜干天天操 | 成人黄色电影免费观看 | 国产91在线播放 | 国产69精品久久app免费版 | 成人一区不卡 | 综合网伊人 | 91亚洲精品久久久蜜桃 | 国产精品色婷婷视频 | 激情五月网站 | 国产毛片久久久 | 蜜臀aⅴ国产精品久久久国产 | 97人人模人人爽人人少妇 | av免费在线网 | 婷婷干五月 | 日本黄色大片儿 | 天天插日日射 | 国产黄色精品网站 | 91在线欧美| 500部大龄熟乱视频使用方法 | 成人福利在线播放 | 中文字幕在线国产精品 | 天天干婷婷| 国产视频在线播放 | 99久久精品国产一区 | 国产精品亚洲综合久久 | 中日韩三级视频 | 91精品亚洲影视在线观看 | 成年人视频在线观看免费 | 国产手机视频精品 | 久久久久久看片 | 超级av在线| 欧美久久久一区二区三区 | 国产精品久久久999 国产91九色视频 | 国产成人在线综合 | 亚洲精品久久久蜜桃 | 日韩高清一区 | 国产这里只有精品 | 91精选 | 91精品国| a色视频 | 视频在线在亚洲 | 色视频在线观看 | 五月天久久久久久 | 午夜国产福利在线观看 | 日韩av手机在线看 | 欧美久久九九 | 天堂av网站 | 精品1区2区| 久久精选视频 | 99免费精品| 精品免费久久久久久 | 亚洲精品一区二区网址 | 黄色精品一区二区 | 国产在线探花 | 69欧美视频| 成人av.com| 波多野结衣最新 | 国内精品久久久久久久久久久 | 在线亚洲精品 | 欧美性做爰猛烈叫床潮 | 在线播放 日韩专区 | 在线电影 你懂得 | 日本性高潮视频 | 色综合天 | 婷婷六月网| 国产成人精品免高潮在线观看 | 婷婷精品国产欧美精品亚洲人人爽 | 九九久久国产精品 | 久草在线视频在线 | 极品久久久久 | 日韩在线欧美在线 | 色妞久久福利网 | 免费在线国产视频 | 国产精品久久久久久久久久尿 | 免费在线观看黄色网 | 丁香六月婷 | 麻豆极品 | 成年人看片 | 在线免费观看成人 | 91完整版 | 成人免费在线播放 | 91午夜精品 | 精品一二三区视频 | 麻豆91在线播放 | 91精品视频免费在线观看 | 免费观看日韩 | 91刺激视频 | 伊人天天狠天天添日日拍 | 久草观看视频 | 久久久久久高潮国产精品视 | 91精品在线观看视频 | 中文字幕国产一区 | 国产午夜精品久久久久久久久久 | 亚洲成人av影片 | 国产午夜影院 | 欧美成人性战久久 | 天天在线操 | 亚洲国产午夜精品 | 97精品国产97久久久久久 | 免费合欢视频成人app | 成人欧美一区二区三区在线观看 | 永久免费的啪啪网站免费观看浪潮 | 狠狠插狠狠干 | 亚洲日本va午夜在线电影 | 亚洲欧美日韩中文在线 | 九色自拍视频 | 久久精品视频观看 | 人人爽人人澡人人添人人人人 | 欧美少妇的秘密 | av高清影院 | 天天插天天| 91亚洲狠狠婷婷综合久久久 | 一区二区三区在线观看中文字幕 | 最新午夜 | 91你懂的 | 亚洲年轻女教师毛茸茸 | 日韩欧美精品在线视频 | 久久成人资源 | 国产在线高清视频 | 狠狠干综合 | 高清av免费观看 | 精品久久久99 | 日本在线视频一区二区三区 | 天天爱天天操 | 午夜123| 国产精品24小时在线观看 | 成人四虎 | 天海翼一区二区三区免费 | 欧美另类z0zx| 91视频在线免费下载 | 成年人视频在线免费 | 天天操夜夜拍 | av中文字幕网站 | 欧美极度另类性三渗透 | 久久久精品高清 | 99久久精品国产一区二区成人 | 超碰在线天天 | 日韩国产欧美在线播放 | 国产色婷婷精品综合在线手机播放 | 日韩久久一区二区 | 人人澡人人舔 | 天天色天天骑天天射 | 国产精品美女久久久久久免费 | 色综合天天综合在线视频 | 丁香九月婷婷 | av免费播放 | 在线观看视频一区二区三区 | 国产不卡一区二区视频 | 国产精品黑丝在线观看 | 在线免费高清一区二区三区 | 久久久精品 | 亚洲视频久久久久 | 国产精品久久久久免费观看 | 九热精品| 一本—道久久a久久精品蜜桃 | 91男人影院| 亚洲最大成人网4388xx | 久久精品视频中文字幕 | 日本女人在线观看 | 亚洲特级片 | 一区二区三区免费在线观看 | 亚洲激情久久 | 看国产黄色大片 | 成人一区二区在线 | 亚洲欧洲日韩在线观看 | 偷拍久久久 | 久久精品国产第一区二区三区 | 97国产精品亚洲精品 | 日本九九视频 | 国产黄色在线网站 | 国产韩国日本高清视频 | 色国产在线 | 国产麻豆精品久久一二三 | 99在线免费视频 | 日韩精品免费一区二区三区 | 日韩欧美视频二区 | 91亚洲在线 | 中文字幕日韩在线播放 | 色综合久久中文综合久久牛 | 久久精品网站免费观看 | 久久久久中文字幕 | 国产精品videoxxxx| www.色com| 中日韩三级视频 | 免费观看完整版无人区 | 色a综合 | 日韩精品久久久久久中文字幕8 | 亚洲乱码精品久久久久 | 欧美国产日韩激情 | 黄色av电影免费观看 | 久久综合免费视频 | 日日夜夜天天久久 | 一区二区日韩av | 久久久久久久久综合 | 91精品久久久久久综合乱菊 | 美女视频一区二区 | 亚洲国产精品成人综合 | 97超碰总站| 国产精品美女久久久久久久久久久 | 黄色电影小说 | 成人少妇影院yyyy | 99精品区 | 不卡的av电影在线观看 | 成人一级视频在线观看 | 丁香5月婷婷| 色婷婷国产精品一区在线观看 | 不卡精品视频 | 九九九九九九精品任你躁 | 国产亚洲片 | 在线视频日韩一区 | 超级碰碰碰碰 | 成人三级av| 欧美性天天 | 国产不卡在线播放 | 久久久久国产精品厨房 | 国产精品毛片一区二区 | 午夜久久美女 | 色妞久久福利网 | 色婷婷九月 | 青青河边草免费直播 | 久久精品一区二区三区中文字幕 | 在线小视频 | 日日综合 | 亚洲精品国产综合久久 | 狠狠操精品| 欧美一级片在线免费观看 | 国产免费黄视频在线观看 | 成人免费视频网 | 人人搞人人爽 | 91av原创 | av先锋中文字幕 | 中文字幕在线免费播放 | 国产永久网站 | 日韩专区在线观看 | 成人国产精品av | 免费在线黄色av | 亚洲一区二区三区91 | 国产精品免费麻豆入口 | 欧美日韩一区二区久久 | 国产黄大片在线观看 | 五月婷婷中文网 | 麻豆影视在线播放 | 中文字幕一区二区三区在线观看 | 久久精品视频99 | 人人草人人做 | 888av | 亚洲精品女 | 色综合天天狠天天透天天伊人 | 国产福利a | 久久久午夜视频 | 亚洲专区一二三 | 久久免费视频精品 | 亚州av成人 | 国产午夜精品av一区二区 | 国产精品自产拍在线观看 | 日韩在线视频观看 | 黄www在线观看 | 特级黄色视频毛片 | 亚洲精品在线免费看 | 国产黄网在线 | 波多野结衣精品 | 欧美欧美 | 97视频人人| 久草免费福利在线观看 | 亚洲va欧美 | 亚洲综合色站 | 午夜美女av | 久久99久久99久久 | 在线观看日本韩国电影 | 在线免费观看视频a | 99热在线观看免费 | 国产精品乱码久久 | 色五月成人 | 欧美亚洲一级片 | 日一日干一干 | 免费视频一区二区 | 国产福利免费在线观看 | 99精品视频免费 | 日本一区二区三区免费观看 | 日韩高清在线一区二区三区 | 国产无遮挡又黄又爽在线观看 | 美女视频黄频大全免费 | 久久99精品久久久久久秒播蜜臀 | 中文字幕av一区二区三区四区 | 色在线免费观看 | 日韩av手机在线观看 | 精品91视频| 日韩精品视频在线观看网址 | 人人干天天干 | 国产精品不卡av | 久热免费| 国产高清免费av | 在线看岛国av | 国产精品丝袜久久久久久久不卡 | 日韩最新中文字幕 | 国产精品高清av | 毛片网站在线观看 | 摸bbb搡bbb搡bbbb | 久久久蜜桃| 成人一级免费视频 | 国产日产精品久久久久快鸭 | 亚洲视频高清 | 亚洲三区在线 | 国产馆在线播放 | 狠狠色丁香婷婷综合欧美 | 国产精品美女久久久 | 国产一区二三区好的 | 超碰在97| 亚洲激情| 91中文字幕在线播放 | 麻豆视频91 | 成人高清在线观看 | 亚洲最大激情中文字幕 | 中文字幕av全部资源www中文字幕在线观看 | 亚洲精品一区二区网址 | 成人 国产 在线 | 99re国产视频 | 黄色亚洲 | 国产精品第二页 | 青青河边草观看完整版高清 | 五月婷婷毛片 | 一区 在线观看 | 国产精品岛国久久久久久久久红粉 | 激情丁香综合 | 天天操天天射天天 | 特级西西444www大胆高清无视频 | 国产精品国内免费一区二区三区 | 国产精品一区二区三区在线 | 久草视频观看 | 亚洲国产视频网站 | 免费久久久久久 | 精品久久久久久久久久久院品网 | 色视频网站在线 | 国产精品久久久久久久久费观看 | 91视频com| 久久的色 | 国产一级片观看 | 国产欧美在线一区二区三区 | 色偷偷人人澡久久超碰69 | av免费网页 | 色之综合网 | 日韩精品一卡 | 亚洲综合日韩在线 | 国产亚洲婷婷免费 | 黄色com| 久久亚洲精品国产亚洲老地址 | 天天爽天天爽 | 99精品视频在线播放观看 | 免费黄色av电影 | 精品国产一区二区久久 | 久久精品99视频 | av网站大全免费 | 99久久99久久精品免费 | 在线中文字幕视频 | 欧美一区日韩一区 | www国产在线 | 久久免费电影网 | 欧美黄在线 | 91尤物在线播放 | 日韩在线不卡视频 | 东方av免费在线观看 | 日韩高清国产精品 | av电影不卡在线 | 天天操天天爱天天爽 | 国内精品国产三级国产aⅴ久 | 色爱成人网 | 三级黄色在线观看 | 国产一级片直播 | 精品国产中文字幕 | 精品专区一区二区 | 国产精品精 | 国产区在线 | 日本精品一区二区在线观看 | 日韩欧美一区视频 | 91亚洲国产 | 中文字幕乱偷在线 | 91成人免费| 黄色网址a | 99久久精品免费一区 | 午夜精品视频在线 | 91成人免费| 日韩在线视频观看免费 | 欧美国产高清 | 91福利影院在线观看 | 91中文字幕在线视频 | 丁香5月婷婷 | 成人国产精品久久久久久亚洲 | 亚洲国产中文在线观看 | 999成人免费视频 | 丁香五月亚洲综合在线 | 精品视频一区在线 | 国产成人亚洲在线电影 | 日本精品一区二区三区在线播放视频 | 久久新 | 国外av在线 | 人人澡人人爱 | 久久国产精品久久久久 | 人人爱爱人人 | 99c视频高清免费观看 | 青青网视频 | 欧洲亚洲激情 | 一级片色播影院 | 99精品视频在线免费观看 | 亚洲视频在线免费观看 | 97超碰资源 | 日韩av黄 | 久久精品一二区 | av丝袜在线| 综合成人在线 | 西西大胆啪啪 | 久久艹免费 | 五月开心激情 | 亚洲精品国偷拍自产在线观看蜜桃 | 国产色一区 | 久久亚洲私人国产精品va | 国产成人777777| 999电影免费在线观看2020 | 黄色在线观看污 | 一二区电影 | 午夜美女网站 | 天天爱天天草 | 81精品国产乱码久久久久久 | 97在线精品 | 在线观看成人一级片 | 91福利区一区二区三区 | 久久国产精品99久久久久 | 99精品在线免费视频 | 日本中文一级片 | 亚洲精色 | 正在播放久久 | 精品亚洲免费 | 国产精品亚洲片在线播放 | 亚洲精品视频久久 | 激情久久久久 | 日韩毛片一区 | 久久亚洲欧美 | 亚洲精品www久久久久久 | 亚洲午夜久久久久久久久久久 | 久久精品伊人 | av在线免费播放网站 | 亚洲免费av网站 | 久久爱综合 | 91麻豆产精品久久久久久 | 黄色在线观看免费网站 | 国产日韩在线一区 | 麻豆久久久久 | 99视频免费| 国产午夜亚洲精品 | 免费av网站观看 | 99国产精品一区二区 | 搡bbbb搡bbb视频 | 成人av一区二区在线观看 | 又色又爽的网站 | 国产精品免费视频一区二区 | av网站播放 | 在线视频 国产 日韩 | 超碰人人在线观看 | 欧美日韩高清 | 性日韩欧美在线视频 | 中文字幕在线国产 | 欧美另类一二三四区 | 成人小视频在线免费观看 | 欧美日韩国产高清视频 | 在线日韩视频 | 国产91对白在线播 | 国产一二区在线观看 | 在线电影 一区 | 在线观看亚洲视频 | 国产最新视频在线观看 | 欧美俄罗斯性视频 | 日韩欧美在线一区二区 | 久久久久免费精品 | 国内精品久久久久久久久 | 综合久久久久久 | 婷婷中文字幕综合 | 99精品视频免费观看视频 | 在线色资源 | 欧美先锋影音 | 国产日韩欧美在线影视 | 国内精品久久久精品电影院 | 99精品视频在线 | 一级国产视频 | 亚洲精品乱码久久久久久9色 | 97人人精品 | 13日本xxxxxⅹxxx20 | 免费三级网 | 国产98色在线 | 日韩 | 久久超级碰视频 | 久艹在线免费观看 | 成人97视频 | 五月婷婷综合激情网 | 中文区中文字幕免费看 | 国产免费观看高清完整版 | 成人黄色小说视频 | 丁香六月在线 | 最近中文字幕免费观看 | 日本中文字幕在线看 | 亚洲年轻女教师毛茸茸 | 久久精品区| 天天操人人要 | 国产精品久久久久久久久久久久久 | av手机在线播放 | 国产美女视频 | 久久99在线观看 | 一区二区精品在线 | 国产清纯在线 | 国产视频一区二区三区在线 | 日本韩国欧美在线观看 | 玖玖在线精品 | 欧美日韩xx | www.av免费| 国产亚洲精品免费 | 中中文字幕av在线 | 超级碰碰碰免费视频 | 色播五月激情综合网 | 婷婷国产在线 | 蜜臀久久99精品久久久酒店新书 | 在线观看精品黄av片免费 | 黄色片网站免费 | 免费高清无人区完整版 | 日韩一区二区免费在线观看 | 久久国产精彩视频 | 中文字幕成人在线观看 | 国产在线最新 | 色综合婷婷久久 | 婷婷综合五月天 | 午夜黄色一级片 | 国产资源 | 色多多污污 | 97天天综合网 | 久爱精品在线 | 日韩黄色在线电影 | 人人舔人人爱 | 亚洲三级精品 | 天天干天天操人体 | 欧美a免费 | 在线免费观看国产视频 | 91丨九色丨高潮丰满 | 久草在线视频免费资源观看 | 午夜精品福利一区二区 | 麻豆传媒视频观看 | 一级片免费视频 | 国产精品xxxx18a99| a午夜在线 | 狠色在线| 国内久久久久久 | 中文字幕在线视频网站 | 久久少妇 | 黄色毛片电影 | 国产天天爽 | 久久一精品 | 久久免费视频8 | 天堂在线一区二区三区 | 国内精品久久久久影院一蜜桃 | 国产无套视频 | 日韩和的一区二在线 | 国产专区视频在线观看 | 久草视频免费看 | 成人不用播放器 | 欧美视频在线观看免费网址 | 亚洲激情六月 | 国产精品久久电影网 | 国产一区视频在线观看免费 | 福利视频入口 | 日批视频 | 丁香六月在线观看 | 天天操比 | 久草精品网 | 久久情网 | 成人黄视频| 伊人超碰在线 | 色播99 | 亚洲劲爆av| 日韩欧美视频一区二区三区 | 视频国产在线 | 91热爆视频 | 91观看视频 | 在线a亚洲视频播放在线观看 | 99在线视频网站 | 国产精品成人在线观看 | 成人精品视频久久久久 | 国产精品久久久影视 | 中文字幕在| 伊人色播| 激情综合亚洲 | 香蕉视频网站在线观看 | 日韩特级黄色片 | 精品久久久久久久久久久久久久久久久久 | 三级毛片视频 | 久久成人国产精品入口 | 成人少妇影院yyyy | 日日碰狠狠躁久久躁综合网 | 午夜精品一区二区三区免费视频 | 精品无人国产偷自产在线 | av电影中文字幕在线观看 | 麻豆你懂的 | 九九热只有这里有精品 | av永久网址 | 天天色宗合 | 国产高清中文字幕 | 国产亚洲在线 | 日韩成人欧美 | 香蕉色综合 | 97电影手机 | 国产又粗又猛又爽 | 日韩国产在线观看 | 碰超在线| 免费看片网站91 |