S2/JAVA/08-JDBC

JDBC API主要做3件事:与数据库建立连接、发送SQL语句、处理结果。

DriverManager类:依据数据库的不同,管理相应的JDBC驱动。

Connection接口:负责连接数据库并担任传送数据的任务。

Statement接口:由Connection产生,负责执行SQL语句。

ResultSet接口:负责保存和处理Statement执行后所产生的查询结果。

PreparedStatement接口:Statement的子接口,也有Connection产生,同样负责执行SQL语句。与Statement接口相比,具有高安全性、高性能、高可读性和高可维护性的优点。

 

JDBC访问数据库的步骤。

1)加载JDBC驱动。

使用Class.forName()方法将给定的JDBC驱动类加载到Java虚拟机中。若系统中不存在给定的类,则会引发异常,异常类型为ClassNotFoundException。代码示例:

Class.forName("JDBC驱动类的名称");

2)与数据库建立连接

DriverManager类是JDBC的管理层,作用于用户和驱动程序之间。DriverManager类跟踪可用的驱动程序,并在数据库和相应的驱动程序之间建立连接。当调用getConnection()方法时,DriverManager类首先从已加载的驱动程序列表中找到一个可以接收该数据库URL的驱动程序,然后请求该驱动程序使用相关的URL、用户名和密码连接到数据库中,于是就建立了与数据库的连接,创建连接对象并返回引用。代码示例:

Connection con=DriverManager.getConnection(数据连接字符串,数据库用户名,密码);

3)发送SQL语句,并得到返回结果。

一旦建立连接,就使用该连接创建Statement接口的对象,并将SQL语句传递给他所连接的数据库。如果是查询操作,将返回类型为ResultSet的结果集,它包含执行SQL查询的结果。如果是其他操作,将根据调用方法的不同返回布尔值或操作影响的记录数目。代码示例:

Statement stmt=con.createStatement();

ResultSet rs=stmt.executeQuery("SELECT id,name FROM master");

4)处理返回结果

主要是针对查询操作的结果集,通过循环取出结果集中每条记录并做出相应处理。处理结果的代码示例:

While(re.next()){

int id=rs.getInt("id");

String name=rs.getString("name");

System.out.println(id+"  "+name);

}

 

两种常用的驱动方式:第一种是JDBC-ODBC桥连方式,适用与个人开发与测试,他通过ODBC与数据库进行连接。第二种是纯Java驱动方式,他直接通数据库进行连接,在生产型开发中,推荐使用纯Java驱动方式。

 

使用JDBC-ODBC桥连方式连接数据库,JDBC驱动类是“sun.jdbc.odbc.JdbcOdbcDriver”,数据库连接字符串将以“jdbc:odbc”开始,后面跟随数据源名称。因此,假设我们已经配置了一个叫“conn_epet”ODBC数据源,数据库连接字符串就是“jdbc:odbc:conn_epet”,假定登录数据库系统的用户名为“sa”,口令为“sa”。具体实现代码如示例1所示。

 

我们使用纯Java驱动方式进行数据库连接,首先需要下载数据库厂商提供的驱动程序jar包,并将jar包引入工程中。。接下来就可以进行编程,与数据库建立连接。此处假定在SQL Server2008中已经建立了名称为“epet”的数据库,数据库用户名为“sa”,密码为“sa”,驱动程序包为sqljdbc2008.jar

 

获取Connection对象后就可以进行各种数据库操作了,此时需要使用Connection对象创建Statement对象。Statement对象用于将SQL语句发送到数据库中,或者理解为执行SQL语句。Statement接口中包含很多基本数据库操作方法,以下为执行SQL命令的3个方法。

ResultSet executeQuery(String sql):可以执行SQL查询并获取ResultSet对象。

int executeUpdate(String sql):可以执行插入、删除、更新的操作。返回值是执行该操作所影响的行数。

boolean execute(String sql):可以执行任意SQL语句,若结果为ResultSet对象,则返回true;若其为更新计数或者不存在任何结果,则返回false

 

使用Statement添加狗狗信息到数据库,只要创建Statement对象然后调用execute(String sql)方法或者executeUpdate(String sql)方法即可。这里关键是SQL语句的拼接,可以直接利用“+”运算符进行拼接,也可以利用StringBuffer类的append()方法进行拼接。拼接时要非常小心,尤其是引号、逗号和括号的拼接,避免出错。

如:insert into dog (name,health,love,strain) values ('name',health,love,'strain')                   这里namestrain是字符串,healthloveint型。

具体代码如下:

//2、建立连接

conn=DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=epet","sa","bdqn");

//3、插入狗狗信息到数据库

stmt=conn.createStatement();

StringBuffer sbSql=new StringBuffer("insert into dog (name,health,love,strain) values ('");

sbSql.append(name+"',");

sbSql.append(health+",");

sbSql.append(love+",'");

sbSql.append(strain+"')");

stmt.execute(sbSql.toString());

 

StringBuffer的使用。

Java定义了StringStringBuffer两个类来封装对字符串的各种操作。String类的字符串是常量,它们的值在创建之后不能更改。而StringBuffer类似于String的字符串缓冲区,通过某些方法调用可以改变该字符串的长度和内容,用于存放内容可以改变的字符串。如果StringBuffer生成了最终想要的字符串,可以用过toString()方法转换为一个String对象。

Java为字符串提供了字符串连接运算符“+”,可以把非字符串数据转换为字符串并连接成新的字符串。类似“+”运算符的功能也可以通过Stringbuffer类的append()方法实现。

例如:

int health=90,love=20;

String sql="select * from epet where health>"+health+" and love>"+love;

等效于

int health=90,love=20;

String sql=new StringBuffer()

.append("select  *  from epet where health>")

.append(health)

.append("  and  love>")

.append(love)

.toString();

 

Result可以理解为有查询结果组成的一个二维表,每行代表一条记录,每列代表一个字段;并且存在一个光标,光标所指行为当前行,只能对结果集的当前行数据进行操作;光标初始位置是第一行之前(而不是指向第一行)。通过ResultSetnext()方法可以是光标向下移动一行,然后通过一系列getXxx()方法实现对当前行各列数据的操作。

若执行next()后光标指向结果集的某一行,则返回true;否则返回false。若光标已指向结果集最后一行,再次调用next()方法,会指向最后一行的后面,此时返回false

getXxx()方法提供了获取当前行中某列值的途径,列号或列名可用于标识要从中获取数据的列(Xxx代表基本数据类型名,如IntFloat等,也可以是String)。例如,如果结果集中第一列的列名为id,存储类型为整型,那么可以使用两种方法获取存储在该列中的值,如“int id=rs.getInt(1);”或者“int id=rs.getInt("id");”。采用列名来标识列可读性强,建议多采用这种方式。

 

ResultSet接口常用方法及作用

方法名称

作用

boolean next()

将光标从当前位置向下移动一行

boolean previous()

将光标从当前位置向上移动一行

void close()

关闭Result对象

int getInt(int columnIndex)

int的形式获取结果集当前行指定列号的值

Int getInt(String co) getInt(String columnLabel)

int的形式获取结果集当前行指定列名的值

float getFloat(int columnIndex)

float的形式获取结果集当前行指定列号的值

float getFloat(String columnLabel)

float的形式获取结果集当前行指定列名的值

String getString(int columnIndex)

String的形式获取结果集当前行指定列号的值

String getString(String columnLabel)

String的形式获取结果集当前行指定列名的值

int getRow()

得到光标当前所指行的行号

boolean absolute(int row)

光标移动到row指定的行

 

注意:

作为一种好的编程风格,应该在不需要ResultSet对象、Statement对象和Connection对象显式的关闭它们。语法形式为:public void close() throws SQLException

要按先ResultSet结果集,后Statement,最后Connection的顺序关闭资源,因为ResultSet是通过Statement执行SQL命令得到的,而Statement是需要在创建连接后才可以使用的,所以三者之间存在相互依存的关系,关闭时也必须按照依存关系进行。

用户如果不关闭ResultSet,当Statement关闭、重新执行或用于从多结果序列中获取下一个结果时,该ResultSet将被自动关闭。

 

PerparedStatement接口继承自Statement接口,PerparedStatement比普通的Statement对象使用起来更加灵活,更有效率。

 

使用PreparedStatement操作数据库的基本步骤有3步。

1、创建PreparedStatement对象。

通过Connection接口的preparedStatement(String sql)方法来创建PreparedStatement对象,SQL语句可具有一个或多个输入参数。这些输入参数的值在SQL语句创建时未被指定,而是为每个输入参数保留一个问号()作为占位符。

以下的代码段(其中conConnection对象)将创建包含带有3个输入参数的SQL语句的PreparedStatement对象。

PreparedStatement pstmt=con.preparedStatement("update dog set health=?,love=? where id=?");

2、设置每个输入参数的值。

通过调用setXxx()方法来完成,其中,Xxx是与该参数相应的类型。例如,若参数是String类型,则使用的方法就是setString()setXxx()方法的第一个参数是要设置的序数位置(从1开始计数),第二个参数是设置给该参数的值。例如,以下代码将第一个参数设为整型值80,第二个参数设为整型值15,第三个参数设为整形1

pstmt.setInt(1,80);

pstmt.setInt(2,15);

pstmt.setInt(3,1);

3、执行SQL语句。

在设置了各个输入参数的值后,就可以调用PreparedStatement接口的3个执行方法之一来执行SQL语句。

ResultSet executeQuery():可以执行SQL查询并获取到ResultSet对象。

int executeUpdate():可以执行插入、删除和更新的操作,返回值是执行该操作所影响的行数。

boolean execute():可以执行任意SQL语句,若结果为ResultSet对象,则返回true;若其为更新计数或者不存在任何结果,则返回false

注意这3个方法和Statement接口中3个方法名字相同、作用相同,但是不需要SQL语句做参数,SQL语句已经在创建对象PreparedStatement时指定了。例如:pstmt.executeUpdate();

创建PreparedStatement对象时会对SQL语句进行预编译,所以执行速度要快于Statement对象。因此,如果在程序中存在需要多次执行SQL语句时,应使用PreparedStatement对象来执行数据库操作,以提高效率。

 

PreparedStatementStatement好在哪里?

1、提高了代码的可读性和可维护性。

虽然使用PreparedStatement来代替Statement会多几行代码,但避免了繁琐麻烦又容易出错的SQL语句拼接,提高了代码的可读性和可维护性。

2、提高了SQL语句执行的性能。

创建Statement对象时不使用SQL语句做参数,不会解析和编译SQL语句,每次调用方法执行SQL语句时都要进行SQL语句解析和编译操作,即操作相同仅仅是数据不同。

创建PreparedStatement对象时使用SQL语句做参数,会解析和编译该SQL语句。也可以使用带占位符的SQL语句做参数,在通过setXxx()方法给占位符赋值后执行SQL语句时无需再解析和编译SQL语句,直接执行即可。多次执行相同操作可以大大提高性能。

3、提高了安全性。

PreparedStatement使用预编译语句,传入的任何数据都不会和已经预编译的SQL语句进行拼接,避免了SQL注入攻击。

转载于:https://www.cnblogs.com/water5832/p/5562378.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值