JDBC教学ppt课件Java程序设计案例教程.pptx

上传人:春哥&#****71; 文档编号:87375142 上传时间:2023-04-16 格式:PPTX 页数:93 大小:6.85MB
返回 下载 相关 举报
JDBC教学ppt课件Java程序设计案例教程.pptx_第1页
第1页 / 共93页
JDBC教学ppt课件Java程序设计案例教程.pptx_第2页
第2页 / 共93页
点击查看更多>>
资源描述

《JDBC教学ppt课件Java程序设计案例教程.pptx》由会员分享,可在线阅读,更多相关《JDBC教学ppt课件Java程序设计案例教程.pptx(93页珍藏版)》请在得力文库 - 分享文档赚钱的网站上搜索。

1、JDBC 教学课件Java程序设计案例教程8.1 什么是JDBCJDBC的全称是Java数据库连接(JavaDatabaseConnectivity),它是一套用于执行SQL语句的JavaAPI。我们的应用程序可通过这套API连接到关系型数据库,并使用这套API来执行相关的SQL语句完成对数据库中数据的新增、删除、修改和查询等操作。简单来说,就是借助于Java提供的这套API(即JDBC)来实现对关系型数据库的相关操作。8.1 什么是JDBC但是,这里要注意的是,Java给我们提供的这套操作关系型数据库所对应的API仅仅是一套接口,或者说是一些抽象类,Java并没有提供一些具体的类来操作关系型

2、数据库,那Java为什么没有提供具体的类来操作关系型数据库呢?8.1 什么是JDBC不同的数据库(如MySQL、Oracle等)底层实现细节以及内部的数据处理方式是不同的,如果Java提供具体的类来操作关系型数据库,此时,它就需要针对每一种关系型数据库来提供具体的类(比如MySQL、Oracle分别提供具体的类),那么就会出现两个问题,第一,对于开发人员来说,开发成本大大增加了,因为Java需要对每一种关系型数据库提供具体的类。第二,对于使用者来说,后期的维护成本提高了。假设项目刚开始使用MySQL数据库,此时就需要借助于MySQL所对应的具体API来操作,后期如果底层数据库改成了Oracle

3、,此时就需要修改代码,使用Oracle所对应的具体API来操作,即随着底层数据库的变更,我们需要频繁地修改相关代码,这样就使维护成本增高了。8.1 什么是JDBC因此,基于上述两点,Java提供操作数据库的这套API就不是具体的类,而是一套接口。后期开发人员在进行开发的时候只需要面向这一套接口编程(即JDBC)就行了。那么仅有接口能实现数据库的相关操作吗?答案是肯定不行,因为接口的方法都是抽象方法,没有具体的方法体。所以要操作这些数据库,还必须有接口所对应的实现类。因为数据库厂商非常清楚自己数据库的细节及处理方式,所以这个接口所对应的实现类是由数据库厂商开发的,我们将这些实现类称为数据库驱动。

4、这样,即使后期数据库发生变更,我们只需要更改数据库驱动就可以,程序代码不需要更改。8.1 什么是JDBC应用程序使用JDBC访问数据库的方式如下图。8.1 什么是JDBC由上图可以看出,JDBC起到应用程序和底层数据库的桥梁的作用。JDBC要求各个数据库厂商按照统一的规范提供数据库驱动程序,在程序中由JDBC与具体的数据库驱动联系,因此,用户就不必直接与底层的数据库交互,使代码的通用性更强。即当应用程序使用JDBC访问特定的数据库时,需要通过不同数据库驱动与不同数据库连接,连接后就可对数据库进行相应操作。8.2 JDBC常用API在开发JDBC程序前,先了解一下JDBC常用的API。JDBCA

5、PI主要位于java.sql包中,该包定义了一系列访问数据库的接口和类。8.2.1 Driver接口Driver接口是所有JDBC驱动程序必须实现的接口,该接口专门提供给数据库厂商使用。需要注意的是,在编写JDBC程序时,必须要把所使用的数据库驱动程序或类库加载到项目的classpath中(这里指MySQL驱动JAR包)。8.2.2 DriverManager 接口DriverManager接口用于加载JDBC驱动、创建与数据库的连接。在DriverManager接口中,定义了两个比较重要的静态方法,见下表。方法名称方法名称功能描述功能描述staticvoidregisterDriver(Dr

6、iverdriver)用于向DriverManager注册给定的JDBC驱动程序staticConnectiongetConnection(Stringurl,Stringuser,Stringpwd)用于建立和数据库的连接,并返回表示连接的Connection对象8.2.3 Connection接口Connection接口用于处理与特定数据库的连接,Connection对象是表示数据库连接的对象,只有获得该连接对象,才能访问并操作数据库。Connection接口的常用方法如下表。方法名称方法名称功能描述功能描述StatementcreateStatement()用于创建一个Statement

7、对象将SQL语句发送到数据库PreparedStatementprepareStatement(Stringsql)用于创建一个PreparedStatement对象将参数化的SQL语句发送到数据库CallableStatementprepareCall(Stringsql)用于创建一个CallableStatement对象来调用数据库存储过程8.2.4 Statement接口Statement接口用于执行静态的SQL语句,并返回一个结果对象。Statement接口对象可以通过Connection实例的createStatement()方法获得,该对象会把静态的SQL语句发送到数据库中编译执行

8、,然后返回数据库的处理结果。Statement接口提供了3个常用的执行SQL语句的方法。方法名称方法名称功能描述功能描述booleanexecute(Stringsql)用于执行各种SQL语句。该方法返回一个boolean类型的值,如果为true,表示所执行的SQL语句有查询结果,可以通过Statement的getResultSet()方法获得查询结果。intexecuteUpdate(Stringsql)用于执行SQL中的insert、update和delete语句。该方法返回一个int类型的值,表示数据库中受该SQL语句影响的记录条数。ResultSet executeQuery(Stri

9、ngsql)用于执行SQL中的select语句。该方法返回一个表示查询结果的ResultSet对象。8.2.4 Statement接口注意,Statement接口要求执行静态的SQL语句。SQL语句就是在程序里面已经把SQL语句拼接好了,后期对于数据库而言,这个SQL语句就是固定的,具体事例如下:8.2.4 Statement接口8.2.5 PreparedStatement 接口Statement接口封装了JDBC执行SQL语句的方法,可以完成Java程序执行SQL语句的操作。然而在实际开发过程中往往需要将程序中的变量作为SQL语句的查询条件,而使用Statement接口操作这些SQL语句会

10、过于繁琐,并且存在安全方面的问题。针对这一问题,JDBCAPI提供了扩展的PreparedStatement接口。PreparedStatement是Statement的子接口,用于执行预编译的SQL语句。PreparedStatement接口扩展了带有参数SQL语句的执行操作,该接口中的SQL语句可以使用占位符“?”代替参数,然后通过setter()方法为SQL语句的参数赋值。8.2.5 PreparedStatement 接口PreparedStatement接口提供了一些常用方法,如下表。方法名称方法名称功能描述功能描述intexecuteUpdate()在PreparedStateme

11、nt对象中执行 SQL 语句,SQL语句必须是一个DML语句或者是无返回内容的SQL 语句,如 DDL 语句。ResultSetexecuteQuery()在PreparedStatement对象中执行 SQL 查询,该方法返回的是ResultSet对象。voidsetInt(intparameterIndex,intx)将指定参数设置成给定的int值。voidsetString(intparameterIndex,Stringx)将指定参数设置成给定的String值。8.2.5 PreparedStatement 接口通过setter()方法为SQL语句中的参数赋值时,可以通过已定义的SQL

12、类型参数兼容输入参数。例如,如果参数具有的SQL类型为Integer,那么应该使用setInt()方法或setObject()方法设置多种类型的输入参数,具体示例如下所示:8.2.5 PreparedStatement 接口8.2.6 ResultSet接口ResultSet接口用于保存JDBC执行查询时返回的结果集,该结果集封装在一个逻辑表格中。在ResultSet接口内部有一个指向表格数据行的游标(或指针),ResultSet对象初始化时,游标在表格的第一行之前,调用next()方法可以将游标移动到下一行。如果下一行没有数据,则返回false。在应用程序中经常使用next()方法作为whi

13、le循环的条件来迭代ResultSet结果集。ResultSet接口的常用方法如下表。方法名称方法名称功能描述功能描述StringgetString(intcolumnIndex)用 于 获 取 指 定 字 段 的 String类 型 的 值,参 数columnIndex代表字段的索引。StringgetString(StringcolumnName)用 于 获 取 指 定 字 段 的 String类 型 的 值,参 数columnName代表字段的名称。intgetInt(intcolumnIndex)用于获取指定字段的int类型的值,参数columnIndex代表字段的索引。intgetI

14、nt(StringcolumnName)用于获取指定字段的int类型的值,参数columnName代表字段的名称。booleannext()将游标从当前位置向下移一行。8.2.6 ResultSet接口从上个表格中可以看出,ResultSet接口中定义了一些getter方法,而采用哪种getter方法获取数据取决于字段的数据类型。程序既可以通过字段的名称来获取指定数据,也可以通过字段的索引来获取指定的数据,字段的索引是从1开始编号的。例如,数据表的第一列字段名为id,字段类型为int,那么既可以使用getInt(1)获取该列的值,也可以使用getInt(“id”)获取该列的值。8.2.6 Re

15、sultSet接口8.3.1 实现JDBC相关步骤使用JDBC的常用API实现JDBC程序的步骤如下图。接下来分步骤讲解使用JDBC的API连接数据库的过程。1.把数据库所对应的驱动JAR包加载到当前项目的classpath路径下首先,在IntelliJIDEA开发工具中,在当前项目下,新建一个lib文件夹。然后,把数据库驱动包放入文件夹lib中,右击当前驱动包,选择【AddasLibrary】,然后单击【OK】就加载到了classpath路径下。8.3.1 实现JDBC相关步骤2.加载并注册数据库驱动在连接数据库之前,要加载数据库的驱动到JVM(Java虚拟机)。加载操作可以通过java.l

16、ang.Class类的静态方法forName(StringclassName)或DriverManager类的静态方法registerDriver(Driverdriver)实现,具体示例如下所示:DriverManager.registerDriver(Driverdriver);或Class.forName(DriverName);8.3.1 实现JDBC相关步骤在实际开发中,我们常用第2种方式注册数据库驱动,DriverName表示数据库的驱动类。以MySQL数据库为例,MySQL驱动类在6.0.2版本之前为com.mysql.jdbc.Driver,而在6.0.2版本之后为com.my

17、sql.cj.jdbc.Driver,我们要根据自己数据库版本选择对应的驱动类。8.3.1 实现JDBC相关步骤3.通过DriverManager获取数据库连接获取数据库连接的具体方式如下:Connectionconn=DriverManager.getConnection(Stringurl,Stringuser,Stringpwd);从上述代码可以看出,getConnection()方法有3个参数,分别表示连接数据库的地址、登录数据库的用户名和密码。以MySQL数据库为例,MySQL数据库地址的书写格式如下:jdbc:mysql:/hostname:port/databasename8.3

18、.1 实现JDBC相关步骤在上面代码中,jdbc:mysql:是固定的写法,mysql指的是MySQL数据库,hostname指的是主机的名称(如果数据库在本机中,hostname可以为localhost或127.0.0.1;如果要连接的数据库在其他电脑上,hostname为所要连接电脑的IP),port指的是连接数据库的端口号(MySQL端口号默认为3306),databasename指的是MySQL中相应数据库的名称。8.3.1 实现JDBC相关步骤4.通过Connection对象获取Statement对象Connection创建Statement对象的方法有以下3个:createStat

19、ement():创建基本的Statement对象。prepareStatement():创建PreparedStatement对象。prepareCall():创建CallableStatement对象。以创建基本的Statement对象为例,创建方式如下:Statementstmt=conn.createStatement();8.3.1 实现JDBC相关步骤5.使用Statement执行SQL语句所有的Statement都有以下3种执行SQL语句的方法:execute():可以执行任何SQL语句。executeQuery():通常执行查询语句,执行后返回代表结果集的ResultSet对象。

20、executeUpdate():主要用于执行DML和DDL语句。执行DML语句,如INSERT、UPDATE或DELETE时,返回受SQL语句影响的行数;执行DDL语句返回0。8.3.1 实现JDBC相关步骤以executeQuery()方法为例,executeQuery()方法调用形式如下:8.3.1 实现JDBC相关步骤6.解析结果如果执行的SQL语句是查询语句,执行结果将返回一个ResultSet对象,该对象保存了SQL语句查询的结果。程序可以通过操作该ResultSet对象取出查询结果。如果执行的是增删改的操作,则返回的是一个int值,表示受SQL语句影响的行数。7.关闭连接,释放资源

21、每次操作数据库结束后都要关闭数据库连接,释放资源,关闭顺序和声明顺序相反。需要关闭的资源包括ResultSet、Statement和Connection等。8.3.1 实现JDBC相关步骤根据上面所讲解的步骤就可以编写Java程序演示JDBC的使用了。但是,在讲解之前,我们先简单演示一下数据库(以MySQL为例)的安装及配置。分为如下几步:1.先去官网上下载MySQL社区版本的压缩包。链接如下:8.3.2 实现JDBC的预操作根据上面所讲解的步骤就可以编写Java程序演示JDBC的使用了。但是,在讲解之前,我们先简单演示一下数据库(以MySQL为例)的安装及配置。分为如下几步:1.先去官网上下

22、载MySQL社区版本的压缩包。链接如下:8.3.2 实现JDBC的预操作2.配置初始化的my.ini文件将下载好的压缩包解压,和我们的JDK以及IntellijIDEA开发工具一样,放到D盘的develop文件夹下。解压之后的目录如下图。8.3.2 实现JDBC的预操作由上图可以看出解压后的目录并没有的my.ini文件,所以我们需要自行创建在安装根目录下添加的my.ini(新建文本文件,将文件类型改为的.ini),写入基本配置:8.3.2 实现JDBC的预操作8.3.2 实现JDBC的预操作3.初始化MySQL在安装时,避免权限问题出错我们尽量使用管理员身份运行CMD,否则在安装时会报错,会导

23、致安装失败的情况。点击搜索,输入cmd,找到命令提示符后,右键,以管理员身份运行。如下图所示。8.3.2 实现JDBC的预操作打开后进入mysql-8.0.28-winx64的bin目录,如下图所示。在bin目录下执行如下命令:8.3.2 实现JDBC的预操作初始化MySQL如下图所示。注意:MY-010454服务器为rootlocalhost生成临时密码:H4p2ByzlnU+T,其中rootlocalhost:后面的H4p2ByzlnU+T就是初始密码(不含首位空格)。在没有更改密码前,需要记住这个密码,后续登录需要用到。8.3.2 实现JDBC的预操作4.安装并启动MySQL服务安装My

24、SQL服务,执行如下命令:执行命令后,如下图所示。8.3.2 实现JDBC的预操作4.安装并启动MySQL服务启动MySQL服务,执行如下命令。执行命令后如下图所示。8.3.2 实现JDBC的预操作5.修改密码在mysql-8.0.28-winx64的bin目录下,进行数据库连接,执行如下命令:执行命令后如下图所示。8.3.2 实现JDBC的预操作有了mysql这个的时候,我们就可以去改密码了,将密码改成“1234”,执行如下命令:执行上述命令,如下图所示。MySQL相关操作完成,退出命令窗口就可以了。现在我们就可以来编写一个案例程序演示JDBC的使用了。该程序从users表中读取数据,完成数

25、据库的增加操作。8.3.2 实现JDBC的预操作8.3.3 Statement 对象的增删查改1.搭建数据库环境按【Windows+R】组合键,输入【cmd】打开命令行模式,并且,进入mysql-8.0.28-winx64的bin目录,如下图所示。8.3.3 Statement 对象的增删查改然后连接mysql,输入如下命令。输入密码“1234”连接MySQL数据库如下图所示。8.3.3 Statement 对象的增删查改连接数据库之后,我们先来查看当前的数据库。输入如下命令:当前系统存在的数据库如下图所示。8.3.3 Statement 对象的增删查改现在,我们在MySQL中创建一个名称为j

26、dbc的数据库,命令如下:然后使用jbdc数据库,命令如下:8.3.3 Statement 对象的增删查改接下来,在jdbc数据库下创建一个表users,命令如下:8.3.3 Statement 对象的增删查改创建jdbc数据库和表users过程如下图所示。jdbc数据库和users表创建成功后,再向users表中插入3条数据,插入的SQL语句如下所示:8.3.3 Statement 对象的增删查改执行上述程序,如下图所示。8.3.3 Statement 对象的增删查改接下来,可以使用如下命令查看表的情况:执行上述命令后,如下图所示。8.3.3 Statement 对象的增删查改通过上图可看出

27、,jdbc中有一个users表通过如下命令查看use表的结构:再输入如下命令,查看user表的所有数据:8.3.3 Statement 对象的增删查改执行上述命令,如下图所示:从上图可以看出,users表中有刚刚插入的3条数据。8.3.3 Statement 对象的增删查改2.创建项目环境,导入数据库驱动在IDEA中新建一个名称为chapter08的Java项目。在当前项目下,新建一个文件夹,右击【chapter08】选择【New】【Directory】,在弹出窗口中将该文件夹命名为lib,项目根目录中就会出现一个名称为lib的文件夹。8.3.3 Statement 对象的增删查改将下载好的M

28、ySQL数据库驱动文件mysql-connector-java-8.0.28.jar复制到项目的lib目录中,并把jar包添加到项目里。但是我们还没有把jar包加载到classpath下。右击这个jar包,选择【AddasLibrary】,如下图所示。8.3.3 Statement 对象的增删查改8.3.3 Statement 对象的增删查改然后单击【ok】按钮,如下图所示。至此,jar包添加完成并且成功加载到classpath路径下。8.3.3 Statement 对象的增删查改3.编写JDBC程序在项目chapter08的src目录下,新建包cn.itcast01,并且在该包下,新建一个类

29、Example01。该类用于实现往数据库jbdc中的表users中添加一条数据:8.3.3 Statement 对象的增删查改8.3.3 Statement 对象的增删查改程序运行结果如下图。8.3.3 Statement 对象的增删查改由上图可以看出,受影响的SQL语句有1条。我们回到命令行模式,来查询一下users表,如下图所示。8.3.3 Statement 对象的增删查改由上图运行结果可以看出,users表新增了一条赵六数据。至此,第一个JDBC程序完成。接下来我们来完成修改操作,其实只需要更改SQL语句相关部分的代码就可以了。如案例2所示。8.3.3 Statement 对象的增删查

30、改8.3.3 Statement 对象的增删查改程序运行结果如下图。8.3.3 Statement 对象的增删查改由上面两图的运行结果可以看出,受影响的SQL语句只有一条,并且users表中已经成功修改。接下来,再来演示一下删除操作。仍然是只需要修改一下SQL语句相关的代码就可以:8.3.3 Statement 对象的增删查改8.3.3 Statement 对象的增删查改程序运行结果如下图。8.3.3 Statement 对象的增删查改由上面两个图的运行结果可以看出,受影响的SQL语句只有一条,并且users表中已经成功删除第2条lisi相关数据。最后,我们来完成查询操作。8.3.3 Stat

31、ement 对象的增删查改8.3.3 Statement 对象的增删查改程序运行结果如下图。由上述代码可以看出,当执行查询语句时,我们使用的不再是Statement对象的executeUpdate()方法而是Statement对象的executeQuery()方法。executeQuery()方法获取的是一个ResultSet结果集,由于我们的结果集有多条数据,因此肯定需要用循环获取所有数据库数据。8.3.3 Statement 对象的增删查改至此JDBC的增删查改程序已经演示完成了。在实现第一个JDBC程序时,还有以下3点需要注意:(1)、注册驱动虽然使用DriverManager.regi

32、sterDriver(newcom.mysql.cj.jdbc.Driver()方法也可以完成注册,但这种方式会使数据库驱动被注册两次。因为在Driver类的源码中,已经在静态代码块中完成了数据库驱动的注册。为了避免数据库驱动被重复注册,只需要在程序中使用Class.forName()方法加载驱动类即可。8.3.3 Statement 对象的增删查改(2)、释放资源由于数据库资源非常宝贵,数据库允许的并发访问连接数量有限,因此,当数据库资源使用完毕后,一定要记得释放资源。在释放资源的时候,要抛出异常或者使用trycatch语句处理异常,如果处理异常的话,为了保证资源的释放,应该将释放资源的操作

33、放在finally代码块中。8.3.3 Statement 对象的增删查改(3)、获取数据库连接获取数据库连接。在新版本中获取数据库连接时需要设置时区为北京时间(serverTimezone=GMT%2B8),因为安装数据库时默认为美国时间。如果不设置时区为北京时间,系统会报MySQL设置时区与当前计算机系统时区不符的错误。8.3.3 Statement 对象的增删查改此外,MySQL高版本需要指明是否进行SSL连接,否则会出现警告信息。警告信息具体如下所示:8.3.3 Statement 对象的增删查改遇到这种情况,只需要在mysql连接字符串url中加入useSSL=true或者false

34、即可,具体示例如下所示。8.3.3 Statement 对象的增删查改PreparedStatement对象可以对SQL语句进行预编译,预编译的信息会存储在该对象中。当相同的SQL语句再次执行时,程序会使用PreparedStatement对象中的数据,而不需要对SQL语句再次编译去查询数据库,这样就大大提高了数据的访问效率。为了使大家快速了解PreparedStatement对象,接下来通过案例来演示PreparedStaement对象的使用。8.3.4 PreparedStatement 对象的增删查改本小节中,使用第一步的已经搭建好的数据库环境和第二步已经创建好的项目环境和导入的数据库驱

35、动。现在我们来编写JDBC程序,完成数据库的增删查看操作。首先,编写案例5,完成数据库的添加操作,往user表中,添加一条数据:8.3.4 PreparedStatement 对象的增删查改8.3.4 PreparedStatement 对象的增删查改上述代码中获取的执行SQL语句对象,此时获取的不再是Statement对象而是其子对象PreparedStatement对象,在代码的第19行,定义的SQL语句中,在进行参数指定时,没有必要把数据固定了,先使用占位符?来进行表示,然后调用PreparedStatement对象的setXxx()方法,给SQL语句的参数赋值,最后通过调用execut

36、eUpdate()方法执行SQL语句。8.3.4 PreparedStatement 对象的增删查改运行结果如下图所示:8.3.4 PreparedStatement 对象的增删查改由上图的运行结果可以看出,受影响的SQL语句只有一条,并且users表中已经成功添加liming这条数据。接下来我们通过PreparedStatement对象来对数据库进行更改操作。我们只需要修改上述代码的SQL语句和占位符相关的代码。8.3.4 PreparedStatement 对象的增删查改8.3.4 PreparedStatement 对象的增删查改运行结果如下图所示:8.3.4 PreparedState

37、ment 对象的增删查改由上图的运行结果可以看出,受影响的SQL语句只有一条,并且users表中已经成功修改id为5的数据。接下来我们通过案例7来演示数据库的删除操作,仍然只需要修改SQL语句和占位符相关的语句。8.3.4 PreparedStatement 对象的增删查改8.3.4 PreparedStatement 对象的增删查改上述代码中,对于加载驱动异常,即ClassNotFoundException,我们并没有抛出,使用了trycatch语句进行处理,这里要注意的是,对于资源的释放要放在finally模块。8.3.4 PreparedStatement 对象的增删查改运行结果如下图所

38、示:8.3.4 PreparedStatement 对象的增删查改由上图的运行结果可以看出,受影响的SQL语句只有一条,并且users表中已经删除id为5的这条数据。最后,我们通过案例8来完成数据库的查询操作。8.3.4 PreparedStatement 对象的增删查改8.3.4 PreparedStatement 对象的增删查改运行结果如下图所示:注意,当执行查询语句时,我们使用的不再是PreparedStatement对象的executeUpdate()方法而是PreparedStatement对象的executeQuery()方法。8.3.4 PreparedStatement 对象的增删查改8.4 本章小结本章主要讲解了JDBC的基本知识,包括什么是JDBC、JDBC的常用API、JDBC的使用,以及如何在项目中使用JDBC实现对数据的增删改查等知识。通过本章的学习,读者可以了解到什么是JDBC,熟悉JDBC的常用API,掌握如何使用JDBC操作数据库等。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 教育专区 > 大学资料

本站为文档C TO C交易模式,本站只提供存储空间、用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。本站仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知得利文库网,我们立即给予删除!客服QQ:136780468 微信:18945177775 电话:18904686070

工信部备案号:黑ICP备15003705号-8 |  经营许可证:黑B2-20190332号 |   黑公网安备:91230400333293403D

© 2020-2023 www.deliwenku.com 得利文库. All Rights Reserved 黑龙江转换宝科技有限公司 

黑龙江省互联网违法和不良信息举报
举报电话:0468-3380021 邮箱:hgswwxb@163.com