Java与数据库的连接_第1页
Java与数据库的连接_第2页
Java与数据库的连接_第3页
Java与数据库的连接_第4页
Java与数据库的连接_第5页
已阅读5页,还剩74页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

JDBC简介数据库的应用目前已经非常普遍,在应用程序的开发过程中,经常会涉及到访问数据库。Java语言为访问数据库提供了方便的技术。Java使用JDBC(JavaDatabaseConnectivity)技术进行数据库的访问。Java应用程序通过JDBCAPI和JDBC驱动程序管理器进行通信。第1页/共79页JDBC的诞生从ODBC到JDBCODBC(OpenDataBaseConnectivity),是一种用来在关系数据库以及非关系数据库管理系统中存取数据,用C语言实现的标准应用程序接口。其主要结构:应用程序接口、驱动程序管理器、数据库驱动程序和数据源。第2页/共79页JDBC的诞生以前由于没有一个Java语言的数据库API,编程人员不得不在Java程序中加入C语言的ODBC函数调用,从而使Java的很多优秀特性无法充分发挥

ODBC具有不易使用,非面向对象等缺点为了充分发挥java语言的特性,迎合数据库开发的需求,sun开发了一套java语言的数据库应用程序开发接口和类,即JDBC。它在Java程序中实现数据库操作功能并简化操作过程。第3页/共79页

JDBC为数据库及其工具的开发人员提供了一个标准的API,使他们能够用纯JavaAPI编写数据库应用程序

JDBC支持基本SQL语句,提供多样化的数据库连接方式,为各种不同的数据库提供统一的操作界面

第4页/共79页JDBC连接数据库的方法通过专用网络协议创建的驱动程序与数据库直接通信。直接使用数据库厂商提供的、用专用网络协议创建的驱动程序各大厂商都为数据库提供了这种JDBC驱动,这种方式最简单实用。应用程序JDBCAPI驱动程序数据源第5页/共79页

通过JDBC-ODBC桥与ODBC数据库通信Sun公司发行了一个用于访问ODBC数据源的驱动程序,称为JDBC-ODBC桥接器。该桥接器用jdbcodbc.class和一个用于访问ODBC驱动程序的本地库来实现的。对于Windows平台,该本地库是一个DLL动态链接库JDBCODBC.DLL其优点是使JDBC目前有能力访问几乎所有的数据库。应用程序数据源JDBCAPIJDBC-ODBCODBCAPIODBC层第6页/共79页

通过部分专用的驱动程序与数据库通信将JDBC数据库调用直接翻译为厂商专用的API,执行更有效,更快捷。应用程序JDBCAPI驱动程序数据源专用API第7页/共79页JDBCAPIJDBCAPI所有的类和接口都集中在java.sql和javax.sql这两个包中驱动管理器连接语句结果集(1)登记并加载JDBC驱动程序(2)建立与SQL数据库的连接(3)传送一个SQL查询(4)获得结果第8页/共79页JDBCAPI的使用方法

注册数据库的驱动程序隐式加载作为初始化的一部分,DriverManager类会尝试加载在“jdbc.drivers”系统属性中引用的驱动程序类。这允许用户自定义由他们的应用程序使用的JDBCDriver。例如jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.taste.ourDriver

publicstaticvoidregisterDriver(Driver

driver)throwsSQLException

向DriverManager注册给定驱动程序第9页/共79页

一旦DriverManager类被初始化,将不再检查jdbc.drivers属性表需要持久的预设环境publicinterfaceDriver

每个驱动程序类必须实现的接口

JavaSQL框架允许多个数据库驱动程序每个驱动程序都应该提供一个实现Driver接口的类

DriverManager会试着加载尽可能多的它可以找到的驱动程序,然后,对于任何给定连接请求,它会让每个驱动程序依次试着连接到目标URL

DriverManager.registerDriver(newcom.microsoft.jdbc.sqlserver.SQLServerDriver());第10页/共79页DriverManagerDriverManager类是JDBC的管理层,作用于用户和驱动程序之间。它跟踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接。

publicstaticDrivergetDriver(String

url)throwsSQLException

试图查找能理解给定URL的驱动程序。

publicstaticEnumeration<Driver>getDrivers()

检索带有当前调用方可以访问的所有当前已加载JDBC驱动程序的Enumeration

publicstaticvoidregisterDriver(Driver

driver)throwsSQLException

向DriverManager注册给定驱动程序。在加载驱动程序时由驱动程序自动调用第11页/共79页

显式加载

publicstaticClass<?>forName(String

className)throwsClassNotFoundException

java.lang.Class<T>

使用与当前applet或应用程序相同的类加载器显式加载驱动程序Class.forName(“com.mysql.jdbc.Driver”);Class.forName(“acme.db.Driver”);如果将acme.db.Driver编写为加载时创建实例,并调用以该实例为参数的DriverManager.registerDriver,则它在DriverManager的驱动程序列表中,并可用于创建连接第12页/共79页将驱动程序添加到Java.lang.System的属性jdbc.drivers中是一个由DriverManager类加载的驱动程序类名的列表,由冒号分隔

jdbc.drivers=foo.bah.Driver:wombat.sql.Driver:bad.test.ourDriver;初始化DriverManager类时,它搜索系统属性jdbc.drivers,如果用户已输入了一个或多个驱动程序,则DriverManager类将试图加载它们。一旦DriverManager类被初始化,将不再检查jdbc.drivers属性表第13页/共79页

建立数据库连接

publicstaticConnectiongetConnection(String

url)throwsSQLException

试图建立到给定数据库URL的连接。DriverManager试图从已注册的驱动程序集中选择一个适当的驱动程序。假定构造数据库连接时不需要用户名、口令或其他数据库属性

DriverManager将检查每个驱动程序,轮流在每个驱动程序上调用方法Driver.connect,查看它是否可以建立连接。

DriverManager将使用它所找到的第一个可以成功连接到给定URL的驱动程序第14页/共79页

publicstaticConnectiongetConnection(String

url,Properties

info)throwsSQLExceptioninfo包含连接数据库所需的所有属性项;通常至少应该包括"user"和"password"属性

publicstaticConnectiongetConnection(String

url,String

user,String

password)throwsSQLException

指定了连接的用户名和密码Connectioncon=DriverManager.getConnection(“jdbc:mysql://localhost/UpdateDB”,”root”,””);第15页/共79页Connection对象用于连接数据库和Java应用程序打开连接的方法

Connectionconnect(String

url,Properties

info)throwsSQLException

java.sql.Driver

试图创建一个到给定URL的数据库连接。

DriverManager.getConnection

提供应用程序与数据库的静态连接单一应用程序可以:拥有与单个数据库的一个或多个连接拥有与许多不同数据库的连接publicinterfaceConnection第16页/共79页JDBCURLJDBCURL提供了一种标识数据库的方法,可以使用相应的驱动程序识别该数据库,并与之建立连接。第17页/共79页

标准语法:jdbc:<subprotocol>:<subname>jdbc协议:JDBCURL中的协议总是jdbc。子协议:驱动程序名或连接机制的名称。如果要用网络命名服务,则命名服务可以作为子协议。Jdbc:dcenaming:accounts驱动程序编程员可保留某个名称以将之用作JDBCURL的子协议名子名称:数据库的唯一标识符。如果数据库是通过Internet来访问的,则遵循命名规定//主机名:端口/数据库名

例jdbc:odbc:goodsjdbc:dcenaming:accountsjdbc:dbnet://wombat:356/fredjdbc:mysql://localhost/UpdateDB第18页/共79页odbc子协议odbc子协议用于指定ODBC风格的数据资源名称的URL,允许指定任意多的属性值。语法:Jdbc:odbc:<数据资源名>[;<属性名>=<属性值>]例:Jdbc:odbc:students;UID=tech;PWD=123Jdbc:odbc:wombat;CacheSize=20;ExtensionCase=LOWER

第19页/共79页如何与数据库建立连接?第20页/共79页获取和安装JDBC以mysql为例:首先,下载mysql,并安装。/打开命令行界面下载mysql-connector-java-5.1.5.tar.zip解压,并进行相应的配置。第21页/共79页

配置方法:进入…\Java\jre1.6.0_02\lib目录将mysql-connector-java-5.1.5-bin.jar拷贝到该目录下。配置classpath,追加%JAVA_HOME%\jre1.6.0_02\lib\mysql-connector-java-5.1.5-bin.jar;配置的目的是让java应用程序找到连接mysql的驱动第22页/共79页第23页/共79页如何向数据库递交查询和更新请求并获得返回的结果?第24页/共79页Statement对象用于执行SQL语句并获取数据库的返回结果

StatementcreateStatement()throwsSQLException

java.sql.Connection

常用方法

booleanexecute(String

sql)throwsSQLException

执行给定的SQL语句,该语句可能返回多个结果。如果结果是ResultSet对象则返回true;结果是更新计数或执行的语句是DDL命令则返回false

ResultSetexecuteQuery(String

sql)throwsSQLException执行给定的SQL语句,该语句返回单个ResultSet对象。publicinterfaceStatement第25页/共79页

intexecuteUpdate(String

sql)throwsSQLException

执行给定SQL语句,该语句可能为INSERT、UPDATE或DELETE语句,或者不返回任何内容的SQL语句(如SQLDDL语句)。返回INSERT、UPDATE或DELETE语句的行计数;或者0,表示不返回任何内容的SQL语句执行语句的所有方法都将关闭所调用的Statement对象的当前打开结果集(如果存在)。这意味着在重新执行Statement对象之前,需要完成对当前ResultSet对象的处理。使用方法execute()仅在语句能返回多个ResultSet对象、多个更新计数或ResultSet对象与更新计数的组合时使用第26页/共79页

ResultSetgetResultSet()throwsSQLException

以ResultSet对象的形式检索当前结果。每个结果只应调用一次此方法。当SQL语句的结果不是结果集时,将返回null。

booleangetMoreResults()throwsSQLException

移动到此Statement对象的下一个结果,如果其为ResultSet对象,则返回true,并隐式关闭利用方法getResultSet获取的所有当前ResultSet对象。

intgetUpdateCount()throwsSQLException

以更新计数的形式检索当前结果;如果结果为ResultSet对象或没有更多结果,则返回-1。每个结果只应调用一次此方法。第27页/共79页

intgetMaxFieldSize()throwsSQLException

检索可以为此Statement对象所生成ResultSet对象中的字符和二进制列值返回的最大字节数。如果超过了该限制,则安静地丢弃多出的数据。

intgetMaxRows()throwsSQLException

检索由此Statement对象生成的ResultSet对象可以包含的最大行数。如果超过了此限制,则安静地撤消多出的行。

intgetQueryTimeout()throwsSQLException

检索驱动程序等待Statement对象执行的秒数。如果超过该限制,则抛出SQLException。第28页/共79页

关闭Statement对象

Statement对象将由Java垃圾收集程序自动关闭显式关闭将立即释放DBMS资源,有助于避免潜在的内存问题。第29页/共79页如何处理查询结果?第30页/共79页ResultSet表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。

ResultSet对象具有指向其当前数据行的指针。最初,指针被置于第一行之前。next方法将指针移动到下一行。

ResultSet接口提供用于从当前行检索列值的获取方法(getBoolean、getLong等)可以使用列的索引编号或列的名称检索值

StringgetString(int

columnIndex)throwsSQLException

StringgetString(String

columnName)throwsSQLException

列名不区分大小写publicinterfaceResultSet第31页/共79页对于获取方法getXXX(),JDBC驱动程序尝试将基础数据转换为在获取方法中指定的Java类型,并返回适当的Java值。用户不必关闭ResultSet;当产生它的Statement关闭、重新执行或用于从多结果序列中获取下一个结果时,该ResultSet将被Statement自动关闭。

Statementstmt=conn.createStatement();

ResultSetr=stmt.executeQuery("SELECTa,b,cFROMTable1“);

while(r.next()){

//打印当前行的值。

Inti=r.getInt("a“);

Strings=r.getString("b“);

Floatf=r.getFloat("c“);

System.out.println("ROW="+i+""+s+""+f);

}第32页/共79页获取MyDB数据库中的表属性,包括列的最大字节数,表的最大行数,驱动程序等待SQL操作执行的秒数

在MyDB中创建一个teacher表,包括的字段及类型为:id(int),name(varchar(10)),sex(char(2)),age(int)

以id为主键将teachers.txt的内容插入teacher表中第33页/共79页

在teacher表上创建一个仅包括name和age列的视图teacher_view

查询teacher和teacher_view的内容第34页/共79页第35页/共79页如何获取结果集中任意位置处的记录?第36页/共79页

游标控制

booleannext()throwsSQLException

将指针从当前位置下移一行。ResultSet指针最初位于第一行之前

booleanprevious()throwsSQLException

将指针移动到此ResultSet对象的上一行

booleanfirst()throwsSQLException

将指针移动到此ResultSet对象的第一行。

booleanlast()throwsSQLException

将指针移动到此ResultSet对象的最后一行。

voidbeforeFirst()throwsSQLException

将指针移动到此ResultSet对象的开头,正好位于第一行之前。第37页/共79页

voidafterLast()throwsSQLException

将指针移动到此ResultSet对象的末尾,正好位于最后一行之后。

booleanabsolute(int

row)throwsSQLException

将指针移动到此ResultSet对象的给定行编号。

booleanrelative(int

rows)throwsSQLException

按相对行数(或正或负)移动指针在ResultSet对象或其父辈Statement对象关闭之前,光标一直保持有效。第38页/共79页

输出teacher表的所有内容(包括列名和记录)在teacher表上执行查询,并将结果填充到结果集中输出结果集第一行记录输出结果集第四行记录输出结果集最后一行记录输出结果集当前位置的前两行对应记录输出结果集当前位置的前一行对应记录第39页/共79页第40页/共79页如何向结果集及数据库中插入、删除、更改记录?第41页/共79页可更新的ResultSet创建可更新的结果集:createStatement方法第二参数需要是CONCUR_UPDATABLEUpdatableResultSet不能保证获得可更新的结果集,需要驱动程序的支持。

intgetConcurrency()throwsSQLException

检索此ResultSet对象的并发模式。并发类型ResultSet.CONCUR_READ_ONLY或ResultSet.CONCUR_UPDATABLE第42页/共79页

插入新行可更新的ResultSet对象具有一个与其关联的特殊行,该行用作构建要插入的行的暂存区域

(stagingarea)。

voidinsertRow()throwsSQLException

将插入行的内容插入到此ResultSet对象和数据库中。rs.moveToInsertRow();//movescursortotheinsertrowrs.updateString(1,"AINSWORTH");//updatesthefirstcolumnoftheinsertrowtobeAINSWORTHrs.updateInt(2,35);//updatesthesecondcolumntobe35rs.updateBoolean(3,true);//updatesthethirdcolumntotruers.insertRow();rs.moveToCurrentRow();第43页/共79页更新当前行中的列值

voidupdateRow()throwsSQLException

用此ResultSet对象的当前行的新内容更新底层数据库。删除行将游标移动到想删除的行,调用方法deleteRow().注:不同的JDBC以不同的方式处理删除操作(将删除行移走,使其在结果集中不可见;或者在被删除行的原来位置插入一个空行)。rs.absolute(5);//movesthecursortothefifthrowofrsrs.updateString("NAME","AINSWORTH");//updatestheNAMEcolumnofrow5tobeAINSWORTHrs.updateRow();//updatestherowinthedatasource第44页/共79页(1)在表中插入一条新记录“7LiuJieF23”(2)删除第四条记录(3)将第二条记录的教师年龄修改为40第45页/共79页可滚动的ResultSetScrollableResultSet,支持将结果集中的游标按任意方向移动。创建可滚动的ResultSet:publicStatementcreateStatement(intrsType,intrsConcurrenty)throwsSQLException其中,rsType必须是一下三种变量之一,添加到ResultSet接口中指示其对象类型:TYPE_FORWARD_ONLY:创建不可滚动的结果集,默认TYPE_SCROLL_INSENSITIVE:创建可滚动的ResultSet对象,结果集打开时不反映变化TYPE_SCROLL_SENSITIVE:创建可滚动的ResultSet对象,结果集打开时反映变化第46页/共79页

rsConcurrenty必须是ResultSet常量中的一个,用于指定结果集是只读的还是可更新的:CONCUR_READ_ONLY默认CONCUR_UPDATABLE检查ResultSet对象是否可滚动:ResultSet.getType()例如:if(rs.getType()==ResultSet.TYPE_FORWARS_ONLY)System.out.println(“FORWARD_ONLY”):elseSystem.out.println(“SCROLLABLE”);第47页/共79页如果多次重复执行同一条SQL语句,只是语句中参数的取值不同,如何避免对该SQL语句进行重复编译?第48页/共79页PreparedStatement

SQL语句被预编译并且存储在PreparedStatement对象中。然后可以使用此对象高效地多次执行该语句。用来设置IN参数值的setter方法(setShort、setString等等)必须指定与输入参数的已定义SQL类型兼容的类型。获取PreparedStatement对象的方法

PreparedStatementprepareStatement(String

sql)throwsSQLException

创建一个PreparedStatement对象来将参数化的SQL语句发送到数据库。SQL语句可能包含一个或多个'?'IN参数占位符的SQL语句publicinterfacePreparedStatementextendsStatement第49页/共79页PreparedStatement可以作为IN参数的变量包含占位符,初始化的方法是调用该类的一系列setXXX()方法。setXXX()方法一般有两个参数:第一个参数都是int型,指示JDBCPreparedStatement对象的第几个参数将要被初始化。第二个参数的值就是PreparedStatemetn将要被初始化的参数取值

PreparedStatement接口有自己的executeQuery、executeUpdate和execute方法,但并不需要SQL语句作为参数提供给这些方法,因为它们已经包含预编译SQL语句第50页/共79页例:将mysql的myDB数据库中teacher表的ChenHong

的年龄修改为30,LiMing的年龄修改为20第51页/共79页如何执行带输入和输出参数的存储过程?第52页/共79页CallableStatement

用于执行SQL存储过程的接口该对象包含了对存储过程的调用,但不包含存储过程本身(存储过程是存储在数据库中的)获取CallableStatement对象

CallableStatementprepareCall(String

sql)throwsSQLExceptionsql可能包含一个或多个'?'参数占位符的SQL语句。publicinterfaceCallableStatementextendsPreparedStatement第53页/共79页IN参数值是使用从PreparedStatement

中继承的set方法设置的。在执行存储过程之前,必须注册所有OUT参数的类型;它们的值是在执行后通过此类提供的get方法检索的。

voidregisterOutParameter(int

parameterIndex,int

sqlType)throwsSQLException

按顺序位置parameterIndex将OUT参数注册为JDBC类型sqlType。

sqlType是由

java.sql.Types

定义的SQL类型代码。

voidregisterOutParameter(String

parameterName,int

sqlType)throwsSQLException

将名为parameterName的OUT参数注册为JDBC类型sqlType。第54页/共79页例:执行存储过程,对mysql中的myDB数据库中的teacher表,通过教师id能得到教师姓名第55页/共79页

对非常大的行值使用流

ResultSet可以获取任意大的LONGVARBINARY或LONGVARCHAR数据。方法getBytes和getString将数据返回为大的块(最大为Statement.getMaxFieldSize的返回值)。但是,以较小的固定块获取非常大的数据可能会更方便

InputStreamgetBinaryStream(int

columnIndex)throwsSQLException

以未解释字节的流的形式获取此ResultSet对象的当前行中指定列的值。第56页/共79页

InputStreamgetAsciiStream(int

columnIndex)throwsSQLException

以单字节ASCII字符流的形式获取此ResultSet对象的当前行中指定列的值。

InputStreamgetUnicodeStream(int

columnIndex)throwsSQLException

以双字节Unicode字符流的形式获取此ResultSet对象的当前行中指定列的值。第57页/共79页JDBC/ODBC桥连接Access的硬件设置打开控制面板,选中管理工具。打开管理工具,选中(ODBC)数据源打开数据源管理器,选择系统DNS,并单击‘添加’按钮。第58页/共79页

选中DriverdoMicrosoftAccess(*mdb)第59页/共79页

在ODBCMicrosoftAccess安装界面中,填写数据源(如Book),并选择数据库,选好后如图。单击确定,完成了设置。第60页/共79页将Access的学生表的内容输出第61页/共79页

DatabaseMetaDatagetMetaData()throwsSQLException

获取DatabaseMetaData对象,该对象包含关于Connection对象连接到的数据库的元数据。元数据包括关于数据库的表、受支持的SQL语法、存储过程、此连接的功能等信息。如何获取所连接数据库的属性?第62页/共79页DatabaseMetaData由Connection.getMetaData()方法创建,可以用于获取数据库的相关信息:例如:获取数据库中表的名字Connectioncon=DriverManager.getConnection(“jdbc:odbc:Customers”);DatabaseMetaDatadm=con.getMetaData();ResultSetrs=dm.getTables(null,null,”%”,newString[]{“Table”});ResultSetgetTables(String

catalog,String

schemaPattern,String

tableNamePattern,String[]

types)throwsSQLException

检索可在给定类别中使用的表的描述。仅返回与类别、模式、表名称和类型标准匹配的表描述。类别名称模式名称模式表名称模式要包括的表类型组成的列表第63页/共79页

从数据库获得的常规信息的方法:StringgetURL()throwsSQLException

检索此DBMS的URL

StringgetDriverName()

throwsSQLException

检索此JDBC驱动程序的名称StringgetUserName()throwsSQLException

检索此数据库的已知的用户名称

String

getDatabaseProductName()throwsSQLException

检索此数据库产品的名称。

第64页/共79页

String

getSQLKeywords()throwsSQLException

检索此数据库的还“不”是SQL92关键字的所有SQL关键字的逗号分隔列表。

booleannullsAreSortedHigh()throwsSQLException

检索NULL值是否被高排序。

booleannullsAreSortedLow()throwsSQLException

检索NULL值是否被低排序第65页/共79页

检索信息的方法:

booleansupportsBatchUpdates()throwsSQLException

检索此数据库是否支持批量更新

booleansupportsStoredProcedures()throwsSQLException

检索此数据库是否支持使用存储过程转义语法的存储过程调用

booleansupportsFullOuterJoins()throwsSQLException

检索此数据库是否支持完全嵌套的外连接。

booleansupportsPositionedDelete()throwsSQLException

检索此数据库是否支持位置的DELETE语句。第66页/共79页检索SQL对象及属性:ResultSetgetSchemas()throwsSQLException

检索可在此数据库中使用的模式名称。模式列为:TABLE_SCHEM,TABLE_CATALOGResultSet

getCatalogs()throwsSQLException

检索可在此数据库中使用的类别名称。类别列为:TABLE_CAT

ResultSetgetTables(String

catalog,String

schemaPattern,String

tableNamePattern,String[]

types)throwsSQLExceptioncatalog类别名称

schemaPattern模式名称的模式

tableNamePattern表名称模式

type要包括的表类型组成的列表第67页/共79页

表描述的列为:TABLE_CAT表类别TABLE_SCHEM表模式

,TABLE_NAME表名称TABLE_TYPE表类型REMARKS,表的解释性注释TYPE_CAT,类型类别TYPE_SCHEM,类型模式TYPE_NAME,类型名称SELF_REFERENCING_COL_NAME,有类型表的指定”identifier”列的名称REF_GENERATION

指定在SELF_REFERENCING_COL_NAME中创建值的方式第68页/共79页

ResultSetgetProcedures(String

catalog,String

schemaPattern,String

procedureNamePattern)throwsSQLException

检索可在给定类别中使用的存储过程的描述。过程描述的列为:PROCEDURE_CAT,PROCEDURE_SCHEM

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论