目录
1:JDBC是什么?
2:怎么使用jdbc
3:JDBC事务处理Statement
4:JDBC事务处理PreparedStatement
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序.
有了JDBC,向各种关系数据发送SQL语句就是一件很容易的事。换言之,有了JDBC API,就不必为访问Sybase数据库专门写一个程序,为访问Oracle数据库又专门写一个程序,或为访问Informix数据库又编写另一个程序等等,程序员只需用JDBC API写一个程序就够了,它可向相应数据库发送SQL调用。同时,将Java语言和JDBC结合起来使程序员不必为不同的平台编写不同的应用程序,只须写一遍程序就可以让它在任何平台上运行,这也是Java语言“编写一次,处处运行”的优势。
Java数据库连接体系结构是用于Java应用程序连接数据库的标准方法。JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。作为API,JDBC为程序开发提供标准的接口,并为数据库厂商及第三方中间件厂商实现与数据库的连接提供了标准方法。JDBC使用已有的SQL标准并支持与其它数据库连接标准,如ODBC之间的桥接。JDBC实现了所有这些面向标准的目标并且具有简单、严格类型定义且高性能实现的接口。
Java 具有坚固、安全、易于使用、易于理解和可从网络上自动下载等特性,是编写数据库应用程序的杰出语言。所需要的只是 Java应用程序与各种不同数据库之间进行对话的方法。而 JDBC 正是作为此种用途的机制。
JDBC 扩展了 Java 的功能。例如,用 Java 和 JDBC API 可以发布含有 applet 的网页,而该 applet 使用的信息可能来自远程数据库。企业也可以用 JDBC 通过 Intranet 将所有职员连到一个或多个内部数据库中(即使这些职员所用的计算机有 Windows、 Macintosh 和UNIX 等各种不同的操作系统)。随着越来越多的程序员开始使用Java 编程语言,对从 Java 中便捷地访问数据库的要求也在日益增加。
MIS管理员们都喜欢 Java 和 JDBC 的结合,因为它使信息传播变得容易和经济。企业可继续使用它们安装好的数据库,并能便捷地存取信息,即使这些信息是储存在不同数据库管理系统上。新程序的开发期很短。安装和版本控制将大为简化。程序员可只编写一遍应用程序或只更新一次,然后将它放到服务器上,随后任何人就都可得到最新版本的应用程序。对于商务上的销售信息服务, Java 和JDBC 可为外部客户提供获取信息更新的更好方法。
详情见代码:
package com.jdbc.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import com.mysql.jdbc.Driver;
public class test1 {
public static void main(String[] args) throws ClassNotFoundException {
//数据库驱动类
String driver = "com.mysql.jdbc.Driver";
String url="jdbc:mysql://localhost:3306/dd?serverTimezone=GMT";
String username="root";
String password="123";
Connection con=null;
Statement state=null;
ResultSet rs=null;
try {
//加载mysql驱动
//DriverManager.registerDriver(new Driver());
//第一步:加载驱动类 驱动类里面有静态方法 类加载器加载即可
Class.forName(driver); //classLoader,加载对应驱动
//第二步:获得连接connection
con=DriverManager.getConnection(url, username, password);
//第三部:得到statement对象
state=con.createStatement();
String sql="select * from jdbcuser";
//第四部:执行sql
rs=state.executeQuery(sql);
//第五部:解析返回值(可以有可无)
//第六步:释放连接
while(rs.next()) {
int uid=rs.getInt("uid"); //数据库int类型
String username1=rs.getString("username");//数据库String类型 长度10
String password1=rs.getString("password");//数据库String类型 长度10
String name=rs.getString("name");//数据库String类型 长度10
System.out.println(uid+"---"+username1+"---"+password1+"---"+name);
}
//释放连接
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}finally {
try {
rs.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
state.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
con.close();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
Statement根据jdk的api可知connection可以创建
1:CallableStatement a= conn.prepareCall(sql);
CallableStatement :CallableStatement主要是调用数据库中的存储过程。在使用CallableStatement时可以接收存储过程的返回值。
2:PreparedStatement p=conn.prepareStatement(sql);
PreparedStatement可以使用占位符,是预编译的,支持动态传递参数。预处理语句将被预先编译好,这条预编译的sql查询语句能在将来的查询中重用,这样一来,它比Statement对象生成的查询速度更快。
3: Statement s=conn.createStatement();
Statement 常用方法是:
boolean execute(String sql) 新增,修改,删除
ResultSet executeQuery(String sql) 查询
int executeUpdate(String sql) 如 新增,修改,删除
Statement 对象。不支持预编译,在对数据库只执行一次性存取的时侯,用 Statement 对象进行处理。PreparedStatement 对象的开销比Statement大,对于一次性操作并不会带来额外的好处。可以避免sql注入。
package com.jdbc.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class test3 {
public static void main(String[] args) {
// TODO Auto-generated method stub
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/qqq?serverTimezone=GMT";
String username = "root";
String password = "123";
Connection conn = null;
Statement stat=null;
ResultSet rs=null;
try {
//执行sql
String sql2="insert into jdbcuser values (DEFAULT,'出差3','555','出差')";
String sql3="insert into jdbcuser values (DEFAULT,'得到3','666','得到')";
String sql1="insert into jdbcuser values (DEFAULT,'啊啊3','444','张三132123132132131321231231231231323')";
//加载驱动类 驱动类里面有静态方法 类加载器加载即可
Class.forName(driver); //classLoader,加载对应驱动
conn = DriverManager.getConnection(url, username, password);
//设置事务手动提交
conn.setAutoCommit(false);
stat=conn.createStatement();
String a[]= {sql3,sql2,sql1};
for(int i=0;i
在上边的代码中由于jdbcuser表中的name值长度是varchar(10),当事务打开的时候。可以看到插入的三条sql第三条name长度超长,执行出错,导致这个事务里面的三条sql均执行失败。
package com.jdbc.test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class PreparedBatchtest {
public static void main(String[] args) {
// TODO Auto-generated method stub
long start= System.currentTimeMillis();
String driver = "com.mysql.jdbc.Driver";
String url = "jdbc:mysql://localhost:3306/huyiju?serverTimezone=GMT&useUnicode=true&characterEncoding=UTF-8";
String username = "root";
String password = "123456";
Connection conn = null;
PreparedStatement stat=null;
ResultSet rs=null;
try {
//执行sql
//'tom', '[email protected]', 'F', null
String sql="insert into person (username,email,gender,dept_id) values (?,?,?,?)";
//加载驱动类 驱动类里面有静态方法 类加载器加载即可
Class.forName(driver); //classLoader,加载对应驱动
conn = DriverManager.getConnection(url, username, password);
//设置事务手动提交
conn.setAutoCommit(false);
stat=conn.prepareStatement(sql);
for(int i=0;i<100;i++) {
stat.setString(1, "hello"+i+1);
stat.setString(2, "word"+i+1);
stat.setString(3, "F");
stat.setInt(4, 1);
stat.addBatch();
}
//提交事务
stat.executeBatch();
conn.commit();
} catch (Exception e) {
try {
//异常回滚
conn.rollback();
} catch (SQLException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
e.printStackTrace();
} finally {
try {
if(rs!=null) {
rs.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(stat!=null) {
stat.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
if(conn!=null) {
conn.close();
}
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
long end= System.currentTimeMillis();
System.out.println(end-start);
//总耗时:13766 第一次
//总耗时:16336 第一次
//总耗时:16245 第一次
}
}
PreparedStatement的批量处理比Statement更快