1、JDBC概述
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口(大部分)和类组成。
数据库驱动:JDBC连接数据库需要驱动,驱动是两个设备要进行通信,必须满足一定通信数据格式,数据格式由设备提供商规定,设备提供商为设备提供驱动软件,通过软件可以与该设备进行通信。如mysql的驱动mysql-connector-java-5.1.37-bin.jar
实际上,数据库驱动指的是由厂商提供的实现了JDBC规范的Java程序的集合
JDBC中最常用的有一个核心类和三个核心接口:
DriverManager类:用于实现数据库连接,具体为实现注册驱动和创建数据库连接对象
Connection接口:用于表示与数据库的连接对象,从DriverManager对象获取
Statement接口:用于表示SQL语句的对象,从Connection对象获取
ResultSet接口:用于表示查询操作的结果集,当对Statement对象执行查询操作时,会返回该接口的对象
2、JDBC原生实现连接数据库并执行增删改查的操作步骤如下:
a、使用DriverManager类注册Mysql驱动
此操作由DriverManager.registerDriver(new com.mysql.jdbc.Driver());实现,但是实际上,com.mysql.jdbc.Driver类中的静态代码块中包含如下语句:java.sql.DriverManager.registerDriver(new Driver);,这段代码说明只要这个com.mysql.jdbc.Driver类被用到,DriverManager类就会自动被注册为mysql驱动,故只需要加载该类即可:Class.forName("com.mysql.jdbc.Driver");
b、调用DriverManager类中的静态方法public static Connection getConnection(String url,String user, String password) throws SQLException()来获取连接对象,这个方法的实参分别代表的是指定需要连接的数据库的地址,该数据库的用户名,该数据库的密码。
c、获取到连接对象后,通过Connection接口的createStatement()方法来获取Statement对象,此处不关心实现类,Statement对象可用于执行SQL语句
d、使用Statement对象执行executeQuery(String sql);或者executeUpdate(String sql);方法来进行增删改查操作
e、如果d步骤中执行的操作为查询,那么该方法的返回值是ResutSet对象,获取到该对象后,使用该对象调用next()方法,该方法的返回值为布尔类型,再在循环中调用get方法获取对应的值即可。如果d步骤执行的操作为增删改,那么返回值为int类型的数据,代表实际影响到的行数
f、操作完成后需要关闭Connection、Statement、ResultSet资源
上述操作中的a、b、f步骤可以被抽取到工具类中,同时,获取数据库连接的三要素,和实际加载的jdbc驱动的的类名,这四个参数可以放入properties文件中,实现配置化。该工具类只需要提供获取数据库的连接返回数据连接,并提供关闭资源的方法即可。工具类代码和调用的测试类代码如下:
package jdbc.practice_01;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
/**
* JDBC连接数据库和关闭资源工具类
* @author limeng
*
*/
public class JDBCUtils {
private static String drivername;
private static String url;
private static String user;
private static String password;
/**
* 通过静态代码块,初始化数据库连接配置数据,并且注册数据库驱动
*/
static {
try {
Properties pr = new Properties();
//通过读取Properties文件给属性赋值,即每次使用该工具类都会读取最新配置进行连接
pr.load(new FileInputStream(new File("jdbc_config.properties")));
drivername = pr.getProperty("drivername");
url = pr.getProperty("url");
user = pr.getProperty("user");
password = pr.getProperty("password");
Class.forName(drivername);
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
throw new RuntimeException("获取数据库连接异常,请检查配置数据");
}
}
/**
* 获取数据库连接对象
* @return
*/
public static Connection getConnection() {
Connection con = null;
try {
con = DriverManager.getConnection(url, user, password);
} catch (SQLException e) {
e.printStackTrace();
throw new RuntimeException("获取数据库连接异常,请检查配置数据");
}
return con;
}
/**
* 关闭JDBC相关资源
* @param con
* @param sta
* @param rs
*/
public static void closeResource(Connection con,Statement sta,ResultSet rs) {
try {
if(con!=null) {
con.close();
}
if(sta!=null) {
sta.close();
}
if(rs!=null) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
package jdbc.practice_01;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 通过JDBC工具类进行增删改查操作
* @author Limeng
*
*/
public class JDBCDemoByUtils {
private static String sqlStatement;
public static void main(String[] args) throws Exception {
//通过工具类获取数据库连接对象
Connection con = JDBCUtils.getConnection();
//通过连接创建数据库执行对象
Statement sta = con.createStatement();
//为查询的结果集准备接收对象
ResultSet rs = null;
//查询
sqlStatement = "SELECT * FROM DEPT";
qry(sta,sqlStatement,rs);
//增加
sqlStatement = "INSERT INTO DEPT VALUES('50','TEST','CHINA')";
System.out.println("插入执行结果:"+update(sta,sqlStatement));
//更新
sqlStatement = "UPDATE DEPT SET loc='SHAOXING' WHERE DEPTNO = '50'";
System.out.println("更新执行结果:"+update(sta,sqlStatement));
//删除
sqlStatement = "DELETE FROM DEPT WHERE DEPTNO = '50'";
System.out.println("删除执行结果:"+update(sta,sqlStatement));
JDBCUtils.closeResource(con, sta, rs);
}
/**
* 查询
* @param sta
* @param sql
* @param rs
* @throws SQLException
*/
private static void qry(Statement sta,String sql,ResultSet rs) throws SQLException {
rs = sta.executeQuery(sql);
while(rs.next()) {
System.out.println(rs.getObject("deptno"));
}
}
/**
* 增删改
* @param sta
* @param sql
* @return
* @throws SQLException
*/
private static int update(Statement sta,String sql) throws SQLException {
return sta.executeUpdate(sql);
}
}
3、PreparedStatement预处理对象
该接口为Statement的子接口,用于表示预编译的SQL语句的对象,SQL语句已预编译并存储在
PreparedStatement
对象中。 然后可以使用该对象多次有效地执行此语句。
接口特点:
性能高
会把sql语句先编译
能过滤掉用户输入的关键字。
使用该接口的具体步骤如下:
a、通过Connection接口实现类对象获取到预处理接口实现类的对象(用接口接收,不关心实现类),此处获取预处理对象是需要提供已经使用占位符处理后的SQL语句
b、调用Set方法对占位符的实际数值进行设置,其中占位符的下标由1开始,并非0(看代码)
c、调用方法
int executeUpdate(); --执行insert update delete语句.
ResultSet executeQuery(); --执行select语句.
boolean execute(); --执行select返回true 执行其他的语句返回false.、
下面的PreparedStatementPra类通过预处理对象实现增删改查操作:
package jdbc.practice_01;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
/**
* 通过JDBC工具类和PreparedStatement实现增删改查(PreparedStatement类为Statement的子类)
* @author limeng
*
*/
public class PreparedStatementPra {
private static String sqlStatement;
public static void main(String[] args) throws SQLException {
//通过工具类获取数据库连接对象
Connection con = JDBCUtils.getConnection();
//通过连接创建数据库执行对象
PreparedStatement ps = null;
//为查询的结果集准备接收对象
ResultSet rs = null;
//查询
sqlStatement = "SELECT * FROM DEPT WHERE DEPTNO = ?";
ps = con.prepareStatement(sqlStatement);
ps.setObject(1, "10");
qry(ps,rs);
//增加
sqlStatement = "INSERT INTO DEPT VALUES(?,?,?)";
ps = con.prepareStatement(sqlStatement);
ps.setObject(1, "50");
ps.setObject(2, "TEST");
ps.setObject(3, "SHAOXING");
System.out.println("插入执行结果:"+update(ps,sqlStatement));
//更新
sqlStatement = "UPDATE DEPT SET loc=? WHERE DEPTNO = ?";
ps = con.prepareStatement(sqlStatement);
ps.setObject(1, "SHAOXING");
ps.setObject(2, "50");
System.out.println("更新执行结果:"+update(ps,sqlStatement));
//删除
sqlStatement = "DELETE FROM DEPT WHERE DEPTNO = ?";
ps = con.prepareStatement(sqlStatement);
ps.setObject(1, "50");
System.out.println("删除执行结果:"+update(ps,sqlStatement));
JDBCUtils.closeResource(con, ps, rs);
}
/**
* 查询
* @param sta
* @param sql
* @param rs
* @throws SQLException
*/
private static void qry(PreparedStatement sta,ResultSet rs) throws SQLException {
rs = sta.executeQuery();
while(rs.next()) {
System.out.println(rs.getObject("deptno"));
}
}
/**
* 增删改
* @param sta
* @param sql
* @return
* @throws SQLException
*/
private static int update(PreparedStatement sta,String sql) throws SQLException {
return sta.executeUpdate();
}
}