JDBC 为java开发者使用数据库提供了统一的编程接口,由一组java类和接口组成。是java程序与数据库系统通信的标准API。sun公司不知道各个与数据库连接的程序代码,就自己提供一套api,凡是数据库想与JAVA连接的,数据库厂商自己实现JDBC接口,那么数据库厂商的JDBC实现,我们就叫数据库的数据库驱动,常见的数据库驱动有mysql实现的和oracle实现的。
要是用JDBC连接数据库
- 加载数据驱动(JDBC接口的实现)装在特定厂商的数据库驱动
- 连接数据库
- SQL语句
- 结果集
Driver接口
对于java开发人员,只需要使用Driver接口就可以了。导入mysql-connection-jar包,安装驱动
Class.forName("com.mysql.jdbc.Driver");
DriverManager接口
是JDBC的管理层,作用于用户和驱动程序,跟踪驱动程序,在数据库和驱动程序之间进行连接
package xidian.lili.JDBC;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.SQLException;
/**
* 测试跟数据库连接
*/
public class Demo01 {
public static void main(String[] args) {
//加载数据库驱动
try {
Class.forName("com.mysql.jdbc.Driver");
//建立连接 (连接对象中含有Socket对象,是一个远程连接,比较耗时,是Connection连接对象管理的要点
真正的开发中为了效率,都会用连接池来管理连接对象
long start=System.currentTimeMillis();Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/tsetjdbc",
"root", "123456");
System.out.println(con);
long end=System.currentTimeMillis();
System.out.println("连接耗时:"+(end-start)+"毫秒");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
}
执行SQL语句的接口
Statement接口
三种Statement类
- Statementt类 发送简单的SQL语句,不带参数,有SQL注入问题
常用的Statement方法:
execute():返回Boolean类型的值,执行SQL语句
executeQuery():执行select语句,返回ResultSet(也是接口)结果集
executeUpdate():运行updata/delete/insert,返回更新的行数
package xidian.lili.JDBC;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 测试Statement执行SQL语句
*/
public class Demo02 {
public static void main(String[] args) {
Connection con=null;
Statement stmt=null;
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/tsetjdbc",
"root", "123456");
stmt=con.createStatement();
//String sql1="insert into t_user (username,regtime,pwd) values ('小花',now(),4756);";
//单独设置SQL语句的参数
String name="赵六";
//采用拼接字符串形式
String sql1="insert into t_user (username,regtime,pwd) values ('"+name+"',now(),4756);";
stmt.execute(sql1);
String sql2="delete from t_user where username='小二';";
stmt.execute(sql2);
//那么就会有SQL注入问题 比如在删除语句
String del_id="7 or 1=1";
String sql3="delete from t_user where id="+del_id;
/**
* 表中的内容全部被删除
* 上述的SQL语句相当于delete from t_user where id=7 or 1=1 where后面永远为真 删除操作执行
*/
stmt.execute(sql3);
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally{ //关闭连接
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
2. PreparedStatement 类
package xidian.lili.JDBC;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 测试PreparedStatement执行SQL语句
*/
public class Demo03 {
public static void main(String[] args) {
Connection con=null;
PreparedStatement stmt=null;
Class.forName("com.mysql.jdbc.Driver");
Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/tsetjdbc",
"root", "123456");
//没有参数的SQL语句也可以
String sql1="insert into t_user (username,regtime,pwd) values ('小花',now(),4756);";PreparedStatement stmt=con.prepareStatement(sql1);
stmt.execute();//或者stmt.execute(sql1);/
//有参数的,用占位符号?
String sql2="insert into t_user (username,regtime,pwd) values (?,?,?)";PreparedStatement stmt1=con.prepareStatement(sql2);
stmt1.setString(1, "lili");
stmt1.setDate(2, new java.sql.Date(System.currentTimeMillis()));
//或者不管参数类型
stmt1.setString(3, "1234");
//stmt1.execute(sql2);//带参数 参加参数后要用下面的语句执行SQL语句
stmt1.execute();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally{
if(stmt1!=null){
try {
stmt1.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
ResultSet接口
查询SQL语句,返回ResultSet结果集,利用游标原理进行查看
package xidian.lili.JDBC;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 测试ResultSet结果集接口
*/
public class Demo04 {
public static void main(String[] args) {
PreparedStatement stmt=null;
Connection con=null;
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/tsetjdbc",
"root", "123456");
//查询SQL语句
String sql1="select username,regtime,pwd from t_user where id>7;";
stmt=con.prepareStatement(sql1);
ResultSet rs=stmt.executeQuery();
//游标原理
while(rs.next()){
System.out.println(rs.getString(1)+"--"+rs.getDate(2)+"---"+rs.getString(3));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally{
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
Batch批处理
当一次要执行多条SQL语句,用Batch批处理操作,这时候建议使用Statement执行SQL语句,PreparedStatement语句预编译内存空间有限,当数据多大会出错。利用事务来处理批操作
package xidian.lili.JDBC;
import java.sql.Connection;
import java.sql.Date;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 测试Batch批处理
*/
public class Demo05 {
public static void main(String[] args) {
Statement stmt=null;
Connection con=null;
try {
Class.forName("com.mysql.jdbc.Driver");
con=DriverManager.getConnection("jdbc:mysql://localhost:3306/tsetjdbc",
"root", "123456");
stmt=con.createStatement();
//连接的自动提交事务设置为false
con.setAutoCommit(false);
//插入2000条数据
for(int i=0;i<2000;i++){
stmt.addBatch("insert into t_user(username,regtime,pwd) values ('wang"+i+"',now(),66666);");
}
stmt.executeBatch();
//提交事务
con.commit();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}finally{
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(con!=null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}