Spring JDBC持久化層框架“全家桶”教程丨【綻放吧!數(shù)據(jù)庫】

      網(wǎng)友投稿 772 2025-04-06

      全家桶目錄

      寫在前面

      一、什么是JdbcTemplate?

      二、JdbcTemplate框架搭建

      1、導入所需jar包

      2、配置JDBC數(shù)據(jù)源

      (1)、直接在中配置數(shù)據(jù)源

      (2)、引入外部配置文件

      3、配置JdbcTemplate對象

      三、持久化層操作詳解

      1、增刪改操作

      2、批量增刪改操作

      3、查詢單行數(shù)據(jù)

      4、查詢多行數(shù)據(jù)

      5、查詢單一指定數(shù)值

      四、使用具名參數(shù)的JdbcTemplate

      1、聲明具名參數(shù)類

      2、具名參數(shù)的普通使用

      3、通過SqlParameterSource對象傳入數(shù)值

      五、自動裝配JdbcTemplate并實現(xiàn)Dao

      六、寫在最后

      寫在前面

      Hello,你好呀,我是灰小猿,一個超會寫bug的程序猿!

      用堅持締造技術(shù)、用指尖敲動未來!愿我們每一次敲動鍵盤,都能讓生活變得更智能、世界變得更有趣!

      在使用spring進行業(yè)務(wù)邏輯層處理時,你是否有想過,如此強大的spring框架在對數(shù)據(jù)庫相關(guān)的業(yè)務(wù)處理時,是否有更加便捷的操作呢?Spring框架又能將傳統(tǒng)JDBC數(shù)據(jù)庫的操作優(yōu)化到什么樣的程度呢?

      今天我就來和大家一起探究一下針對JDBC數(shù)據(jù)庫操作的一個輕量級框架—JdbcTemplate。教你一篇文掌握Spring JDBC框架的核心。

      一、什么是JdbcTemplate?

      Spring的JdbcTemplate可以被看作是一個小型的輕量級持久化層框架,為了使JDBC操作更加便捷,Spring在JDBC API上定義了一個抽象層,以此來建立了一個JDBC存取框架。

      它作為Spring JDBC框架的核心,設(shè)計目的是為不同類型的JDBC操作提供模版方法,以至于通過這種方式,在盡可能保留靈活性的前提下,將數(shù)據(jù)庫存取的工作量降低到最低。

      現(xiàn)在對于什么是jdbcTemplate你應(yīng)該比較了解了吧?那么接下來我就來和大家詳細的聊一聊這個輕量級的框架是如何使用的。

      二、JdbcTemplate框架搭建

      使用JdbcTemplate進行數(shù)據(jù)庫的相關(guān)操作是需要提前搭建好相關(guān)環(huán)境配置的。那么我們就先來講一下如何在spring中配置JdbcTemplate。

      1、導入所需jar包

      我們知道平常在進行框架的搭建的時候都是需要依賴相關(guān)的Jar包來實現(xiàn)的。那么JdbcTemplate又需要哪些jar包呢?我給大家按照作用羅列并整理了出來,

      ①IOC容器所需要的JAR包

      commons-logging-1.1.1.jar

      spring-beans-4.0.0.RELEASE.jar

      spring-context-4.0.0.RELEASE.jar

      spring-core-4.0.0.RELEASE.jar

      spring-expression-4.0.0.RELEASE.jar

      ②JdbcTemplate所需要的JAR包

      spring-jdbc-4.0.0.RELEASE.jar

      spring-orm-4.0.0.RELEASE.jar

      spring-tx-4.0.0.RELEASE.jar

      ③數(shù)據(jù)庫驅(qū)動和數(shù)據(jù)源

      c3p0-0.9.1.2.jar

      mysql-connector-java-5.1.7-bin.jar

      以上這些jar包,包括SSM開發(fā)所需的所有jar包我給大家整理了出來,下載就能使用。

      SSM框架Jar包下載

      現(xiàn)在導入了所有所依賴的jar包,接下來就是利用這些資源搭建接下來的JdbcTemplate框架了,

      2、配置JDBC數(shù)據(jù)源

      既然是對數(shù)據(jù)庫的操作,那么就一定是需要數(shù)據(jù)源的,我們以MySQL數(shù)據(jù)庫為例進行數(shù)據(jù)源的配置操作,關(guān)于在IOC中對bean的賦值我之前也和大家講過,所以我們可以直接在IOC容器中配置出數(shù)據(jù)源,連接到指定的數(shù)據(jù)庫,這里需要借助CombopooledDataSource類,并在其中給user、password、jdbcurl、driverclass等這幾個屬性賦值。同時我們配置上連接池中的最大連接數(shù)量和最小連接數(shù)量(當然這兩個屬性也是可以不用配置的)。

      在這里配置數(shù)據(jù)源對屬性的賦值其實也有兩種方式:

      一種是直接將連接信息在標簽中寫死。

      Spring JDBC持久化層框架“全家桶”教程丨【綻放吧!數(shù)據(jù)庫】

      第二種是將數(shù)據(jù)源的連接信息寫在單獨的一個文件中,然后引入外部配置文件,這里我將兩種方法都介紹給大家:

      (1)、直接在中配置數(shù)據(jù)源

      使用這種方法只需要直接在value中將屬性的值寫死就可以了,同時寫入數(shù)據(jù)源的id,代碼如下:

      (2)、引入外部配置文件

      第二種方式是引入外部帶有數(shù)據(jù)源連接信息的配置文件,然后利用引入外部配置文件的標簽將數(shù)據(jù)源信息引入進來,再利用${}表達式將數(shù)據(jù)值賦值給屬性,使用這種方法的好處就是在數(shù)據(jù)源變更的時候方便更改變更信息,直接在數(shù)據(jù)源的文件中更新即可,不需要在IOC容器中更改代碼。

      這種方法需要我們首先建立數(shù)據(jù)源信息的配置文件,如jdbcconfig.properties,當然你還可以定義成其他名字,如“xxx.properties”。但是一般都要以“.properties”為文件后綴。文件中寫入數(shù)據(jù)源信息:

      jdbc.user=root jdbc.password=ADMIN jdbc.jdbcurl=jdbc:mysql://localhost:3306/jdbc_template jdbc.driverClass=com.mysql.jdbc.Driver

      在IOC容器中使用標簽context:property-placeholder引入外部配置文件“jdbcconfig.properties”。

      注意:這里的class表示類路徑下的文件。

      之后按照同樣的方式在容器中標簽下配置數(shù)據(jù)源,但是現(xiàn)在賦值是使用“${}”獲取到的jdbcconfig.properties中的配置數(shù)據(jù)。代碼如下:

      3、配置JdbcTemplate對象

      在我們配置好數(shù)據(jù)源之后,就是配置JdbcTemplate對象了,由于JdbcTemplate對象只是一個JDBC的操作模版,因此它需要引入外部要操作的數(shù)據(jù)源。具體操作是在IOC中為JdbcTemplate類的dataSource屬性賦予數(shù)據(jù)源。

      代碼如下:

      直到這里,JdbcTemplate這個“輕量級”框架才算搭建配置完成了,接下來就能正常使用JdbcTemplate進行數(shù)據(jù)庫中的相關(guān)操作了,我們先來寫一個測試語句分別測試一下在普通連接和使用JdbcTemplate連接的情況下,數(shù)據(jù)庫連接是否正常:

      public class JdbcTest { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); JdbcTemplate jdbcTemplate = context.getBean(JdbcTemplate.class); // 通過普通方法來獲取數(shù)據(jù)庫連接 @Test public void test() throws SQLException { System.out.println("jdbc_template執(zhí)行"); DataSource bean = context.getBean(DataSource.class); Connection connection = bean.getConnection(); System.out.println("普通方法來獲取數(shù)據(jù)庫連接:" + connection); } /** * 通過jdbcTemplate來獲取數(shù)據(jù)庫連接 * 實驗:測試數(shù)據(jù)源 * */ @Test public void test01() { System.out.println("jdbcTemplate來獲取數(shù)據(jù)庫連接:" + jdbcTemplate); } }

      運行出現(xiàn)如下信息,表示連接正常:

      確認數(shù)據(jù)庫連接正常之后,現(xiàn)在才是到了JdbcTemplate使用的核心部分,敲黑板!到重點咯!!!

      三、持久化層操作詳解

      JdbcTemplate有專門的操作函數(shù)來實現(xiàn)不同的增刪改查操作,接下來我將通過如下數(shù)據(jù)表“員工表employee”來給大家介紹一下他們的具體使用:

      1、增刪改操作

      非常神奇的是,JdbcTemplate的增刪改操作是使用同一個方法來完成的,即:

      JdbcTemplate.update(String, Object...)

      該方法最常用的有兩個參數(shù):

      第一個參數(shù)String傳入需要執(zhí)行的SQL語句,

      第二個參數(shù)Object...傳入sql語句中需要帶的參數(shù),使用object...的意思就是后面可能不止一個參數(shù)。該方法會有一個int類型的返回值,表示有多少行數(shù)據(jù)被修改了,下面我通過一個實例來給大家演示一下;

      例:將emp_id=5的記錄的salary字段更新為1300.00

      首先我們需要寫出相應(yīng)的sql語句,語句中需要傳入?yún)?shù)的位置使用“?”表示,之后調(diào)用update方法來實現(xiàn)修改操作,并返回被修改的行數(shù):

      /** 修改數(shù)據(jù)庫的數(shù)據(jù)表中的數(shù)據(jù) * 將emp_id=5的記錄的salary字段更新為1300.00*/ // @Test public void test02() { String sql = "UPDATE employee SET salary=? WHERE emp_id=?"; int update = jdbcTemplate.update(sql, 1300.00, 5); System.out.println("更新成功!" + update); }

      以上是一個修改操作,對于刪除和添加操作使用同樣的方式即可。

      2、批量增刪改操作

      上面是對于普通的單條數(shù)據(jù)的增刪改操作,但是如果有大量的數(shù)據(jù)需要執(zhí)行同一個操作呢?一個一個的來豈不是太麻煩了嘛?所以針對這一情況JdbcTemplate還特意提供了批量的增刪改方法,方便我們對大量數(shù)據(jù)的操作。具體使用是這樣的。

      通過調(diào)用以下函數(shù)來實現(xiàn):

      JdbcTemplate.batchUpdate(String, List)

      該方法會返回一個int類型的數(shù)組,數(shù)組中存放著每次執(zhí)行sql語句所修改的行數(shù)。

      其中的String仍然表示要執(zhí)行的sql語句,

      但是Object[]封裝了SQL語句每一次執(zhí)行時所需要的參數(shù),而在List集合封裝了SQL語句多次執(zhí)行時的所有參數(shù)。

      我們通過下面這個實例來驗證這一方法的操作:

      例:向employee表中批量插入數(shù)據(jù)

      首先需要將sql語句寫好,然后將需要傳遞的參數(shù)寫入到list集合中,之后再將sql語句和list集合傳入batchUpdate()方法即可。

      /** * 批量插入數(shù)據(jù) * */ @Test public void test03() { String sql = "INSERT INTO employee(emp_name,salary) VALUES(?,?)"; List batchArgs = new ArrayList(); batchArgs.add(new Object[]{"張三","999"}); batchArgs.add(new Object[]{"李四","1999"}); batchArgs.add(new Object[]{"王五","2999"}); int[] batchUpdate = jdbcTemplate.batchUpdate(sql, batchArgs); for (int i : batchUpdate) { System.out.println(i); } }

      3、查詢單行數(shù)據(jù)

      上面我們了解了在jdbcTemplate中如何進行增刪改操作,那么CRUD四兄弟怎么能少看查找這么重要的操作呢?這不它來了!!!

      在jdbcTemplate中查詢數(shù)據(jù)其實是十分簡單的,但是他為什么不與其他三個操作共同使用同一個操作方法呢?

      原因其實很簡單,還不就是增刪改操作會對數(shù)據(jù)表進行修改而返回int型的修改行數(shù),而查詢操作不會對數(shù)據(jù)表修改,同時返回其他類型的查詢結(jié)果!

      首先我們來看一下如何查詢單行數(shù)據(jù)。在jdbcTemplate中查詢單行數(shù)據(jù)所使用的函數(shù)是:

      JdbcTemplate.queryForObject(String, RowMapper, Object...)

      該方法的參數(shù)中String同樣的表示要執(zhí)行查找的sql語句,

      但是這里有一個坑要注意:中間傳遞的參數(shù) RowMapper這個是什么呢?其實這里值的是要傳遞需要返回的bean對象的類型,但是在進行真正的使用的時候我們并不是通過RowMapper來映射要返回的bean對象的,而是通過它的子類BeanPropertyRowMapper,他們的繼承關(guān)心是這樣的:

      在使用BeanPropertyRowMapper映射所返回的bean對象時,能夠找到該對象并映射成功則返回,如果找不到就報錯。

      第三個參數(shù)object...還是表示傳入的查詢參數(shù)。

      下面看這樣一個實例你就明白了。

      例:查詢emp_id=5的數(shù)據(jù)庫記錄,封裝為一個Java對象返回。

      /** * 查詢數(shù)據(jù)庫中的單條數(shù)據(jù) * 實驗4:查詢emp_id=5的數(shù)據(jù)庫記錄,封裝為一個Java對象返回 * 創(chuàng)建的javabean中的字段要和數(shù)據(jù)表中的字段名一樣,否則就需要進行映射 * 查詢單條數(shù)據(jù)使用 queryForObject,但是中間需要使用BeanPropertyRowMapper映射需要生成的bean對象 * 在查找不到的時候會報錯 * * */ @Test public void test04() { String sql = "SELECT * FROM employee WHERE emp_id=?"; Employee employee = null; try { employee = jdbcTemplate.queryForObject(sql, new BeanPropertyRowMapper(Employee.class),5); } catch (Exception e) { // TODO: handle exception } System.out.println(employee); }

      4、查詢多行數(shù)據(jù)

      與查詢單行數(shù)據(jù)不同,查詢多行數(shù)據(jù)需要使用的方法是:

      JdbcTemplate.query(String, RowMapper, Object...)

      但是其中所傳遞的參數(shù)是一樣的,唯一不同是該方法返回的是一個數(shù)組列表,其中包含了查詢到的每一條數(shù)據(jù)。

      如下面這個實例:

      例:查詢salary>4000的數(shù)據(jù)庫記錄,封裝為List集合返回。

      /** * 查詢數(shù)據(jù)庫中的多條數(shù)據(jù) * 實驗5:查詢salary>4000的數(shù)據(jù)庫記錄,封裝為List集合返回 * */ @Test public void test05() { String sql = "SELECT * FROM employee WHERE salary>?"; List employees = jdbcTemplate.query(sql, new BeanPropertyRowMapper(Employee.class),4000); for (Employee employee : employees) { System.out.println(employee); } }

      5、查詢單一指定數(shù)值

      現(xiàn)在我們知道了如何查詢單條數(shù)據(jù),也知道了如何查詢多條數(shù)據(jù),但是這些數(shù)據(jù)返回的都是成行的數(shù)據(jù),假如說我們只想得到某一行的數(shù)據(jù)呢?

      那也好辦。jdbcTemplate有一個專門的方法用來返回需要查詢單一數(shù)值。

      JdbcTemplate.queryForObject(String, Class, Object...)

      該方法中有一個返回值是class,它表示要返回的數(shù)據(jù)的類型,比如是int類型還是double類型。同時方法返回查詢到的該數(shù)值。

      如下面這里實例:

      例:查詢employee表中最大的salary。

      該方法很顯然是返回一個具體的數(shù)值,而且還是沒有參數(shù)的,那么我們在進行參數(shù)的傳遞的時候就不需要傳遞后面的object...類型參數(shù)。

      /** * 查詢數(shù)據(jù)表中的數(shù)據(jù),但是只返回一個數(shù)值 * 實驗6:查詢最大salary * */ @Test public void test06() { String sql = "SELECT MAX(salary) FROM employee"; Double quDouble = jdbcTemplate.queryForObject(sql, Double.class); System.out.println(quDouble); }

      以上就是使用jdbcTemplate實現(xiàn)不同增刪改查操作的全部方法了,但是操作jdbcTemplate還有一種方式,就是將sql語句中的“?”用具體的參數(shù)來表示。接下來我們來介紹一下這種方式執(zhí)行sql語句。

      四、使用具名參數(shù)的JdbcTemplate

      接下來要介紹的這個JdbcTemplate的操作方式與上面的有一點不太一樣,這里使用了一個具名參數(shù)來表示sql語句中需要傳入的參數(shù),那么什么是具名參數(shù)呢?

      具名參數(shù):指具有名字的參數(shù),參數(shù)不再是占位符,而是一個變量名

      語法格式:“:參數(shù)名”

      使用該具名參數(shù)之后,spring會自動的從傳入的參數(shù)中查找具有相應(yīng)名稱的參數(shù),并將它的值賦值給sql語句。

      而Spring有一個支持具名參數(shù)功能的jdbcTemplate,即NamedParameterJdbcTemplate類,在在Spring中可以通過NamedParameterJdbcTemplate類的對象使用帶有具名參數(shù)的SQL語句。

      1、聲明具名參數(shù)類

      使用NamedParameterJdbcTemplate類的方式與普通的JdbcTemplate類似,都需要在ioc中聲明,如下所示:

      2、具名參數(shù)的普通使用

      我們以插入語句為例,來演示一下具名參數(shù)的使用,

      傳統(tǒng)的sql語句是這樣的:

      INSERT INTO employee(emp_name,salary) values(?,?)

      使用具名參數(shù)的sql語句是這樣的;

      INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)

      如下面這個實例:

      例:使用帶有具名參數(shù)的SQL語句插入一條員工記錄,并以Map形式傳入?yún)?shù)值。

      /** * 實驗7:使用帶有具名參數(shù)的SQL語句插入一條員工記錄,并以Map形式傳入?yún)?shù)值 * 占位符查參數(shù):?的順序千萬不能錯,傳參的時候一定要注意 * */ @Test public void test07() { String sql = "INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)"; Map paramMap = new HashMap(); paramMap.put("emp_name", "趙六"); paramMap.put("salary", 998.12); int updateNum = jdbcTemplate2.update(sql, paramMap); System.out.println(updateNum); }

      這里有一點需要注意的是:無論是使用普通的sql語句、還是使用帶具名參數(shù)的sql語句。傳入的參數(shù)的順序都需要和sql語句中參數(shù)的順序一致,否則就會出現(xiàn)參數(shù)調(diào)用錯誤,這一點一定需要注意!

      3、通過SqlParameterSource對象傳入數(shù)值

      通過SqlParameterSource對象傳入數(shù)值其實也就是需要將參數(shù)以javabean的形式傳入,但是又有了需要注意的地方。

      注意:在使用sqlParmeterSource進行數(shù)據(jù)庫中數(shù)據(jù)裝填的時候,一定要注意values后面的參數(shù)名稱和bean中的參數(shù)名稱對應(yīng)

      否則就會報如下錯誤:

      No value supplied for the SQL parameter 'emp_Name': Invalid property 'emp_Name' of bean class [com.spring.beans.Employee]: Bean property 'emp_Name' is not readable or has an invalid getter method:

      下面以一個實例來說明通過SqlParameterSource對象傳入?yún)?shù)。

      例:使用帶有具名參數(shù)的SQL語句插入一條員工記錄,通過SqlParameterSource對象傳入?yún)?shù)。

      /** * 實驗8:重復(fù)實驗7,以SqlParameterSource形式傳入?yún)?shù)值 * */ @Test public void test08() { String sql = "INSERT INTO employee(emp_name,salary) values(:emp_name,:salary)"; Employee employee = new Employee(); employee.setEmp_name("吳九"); employee.setSalary(997.7); int updateNum = jdbcTemplate2.update(sql, new BeanPropertySqlParameterSource(employee)); System.out.println(updateNum); }

      五、自動裝配JdbcTemplate并實現(xiàn)Dao

      由于JdbcTemplate類是線程安全的,所以可以在IOC容器中聲明它的單個實例,并將這個實例注入到所有的Dao實例中,在Dao類中將JdbcTemplate實現(xiàn)自動裝配。并在其中實現(xiàn)增刪改查方法,通過自動裝配的jdbcTemplate可以在Dao中減少代碼的操作,更加輕松的實現(xiàn)增刪改查操作。

      通過該方法自動裝配JdbcTemplate并實現(xiàn)Dao的步驟我給大家總結(jié)了出來:

      建立dao類

      書寫其中的方法

      利用包掃描將其自動裝配

      從IOC容器中獲取dao類

      實現(xiàn)其中響應(yīng)的數(shù)據(jù)庫操作的方法

      下面通過實例進行驗證。

      例:創(chuàng)建BookDao,自動裝配JdbcTemplate對象,并實現(xiàn)一個添加添加操作。

      在Dao類中,我們使用@Autowired注解自動裝配jdbcTemplate,并實現(xiàn)一個數(shù)據(jù)添加的方法:

      @Repository public class EmployeeDao { // 將jdbcTemplate自動注入 @Autowired JdbcTemplate jdbcTemplate; /** * 保存數(shù)據(jù)到數(shù)據(jù)表 * */ public int saveEmployee(Employee employee) { String sql = "insert into employee(emp_name,salary) values(?,?)"; return jdbcTemplate.update(sql, employee.getEmp_name(),employee.getSalary()); } }

      使用測試方法進行測試:

      /** * 實驗9:創(chuàng)建BookDao,自動裝配JdbcTemplate對象 * */ @Test public void test09() { Employee employee = new Employee(); employee.setEmp_name("王八"); employee.setSalary(888.7); int saveEmployeeNum = employeeDao.saveEmployee(employee); System.out.println(saveEmployeeNum); }

      六、寫在最后

      叮叮!到這里,Spring的JdbcTemplate框架全部的操作使用就跟大家講解完畢了,

      其中包括從普通的JdbcTemplate搭建,到實現(xiàn)簡單的CURD、再到復(fù)雜的具名參數(shù)。希望小伙伴們通過這一篇文章就能掌握JdbcTemplate的使用教程。同時在學習過程中有遇到不理解或者不會的地方,歡迎留言提出,我們一起學習!

      再先進的技術(shù)都需要一鍵一鍵的敲出來,奮斗吧!致奔波在Java道路上的每一位“創(chuàng)造者”!

      我是灰小猿,我們下期見!

      【綻放吧!數(shù)據(jù)庫】有獎?wù)魑幕馃徇M行中:https://bbs.huaweicloud.com/blogs/285617

      Java JDBC SQL 數(shù)據(jù)庫

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      版權(quán)聲明:本文內(nèi)容由網(wǎng)絡(luò)用戶投稿,版權(quán)歸原作者所有,本站不擁有其著作權(quán),亦不承擔相應(yīng)法律責任。如果您發(fā)現(xiàn)本站中有涉嫌抄襲或描述失實的內(nèi)容,請聯(lián)系我們jiasou666@gmail.com 處理,核實后本網(wǎng)站將在24小時內(nèi)刪除侵權(quán)內(nèi)容。

      上一篇:Istio入門與實戰(zhàn)》 ——3 使用Vagrant管理虛擬機
      下一篇:怎樣刪除標記空格的小黑點(如何去掉文檔中的小黑點)
      相關(guān)文章
      亚洲伦另类中文字幕| 亚洲国产成人99精品激情在线| 亚洲第一AV网站| 亚洲国产精品ⅴa在线观看| 亚洲an日韩专区在线| 亚洲码一区二区三区| 久久久久亚洲AV无码专区首JN | 国产亚洲3p无码一区二区| 亚洲国产精品综合久久一线| 国产亚洲精品免费| 亚洲AV网站在线观看| 偷自拍亚洲视频在线观看99| 婷婷亚洲综合一区二区| 日本亚洲欧美色视频在线播放 | 亚洲精品人成网在线播放影院| 亚洲免费视频网址| 国产成人精品日本亚洲专一区| 亚洲一区在线观看视频| 国产精品亚洲精品观看不卡| 亚洲综合色婷婷在线观看| 亚洲欧美日韩久久精品| 国产精品亚洲专区无码WEB| 日韩亚洲变态另类中文| 国产成人综合亚洲AV第一页| 久久精品夜色噜噜亚洲A∨| 亚洲一区视频在线播放| 亚洲无线码在线一区观看| 亚洲精品V欧洲精品V日韩精品| 亚洲国产精品成人精品无码区| 亚洲AV乱码久久精品蜜桃| 亚洲视频在线免费播放| 亚洲免费观看在线视频| 亚洲精品无播放器在线播放 | 亚洲精品久久无码| 全亚洲最新黄色特级网站| 亚洲一区二区三区国产精品无码| 亚洲一区二区三区久久| 亚洲精品无码aⅴ中文字幕蜜桃| 亚洲A∨午夜成人片精品网站| 伊人久久综在合线亚洲91| 亚洲爆乳精品无码一区二区三区|