JDBC概述
JDBC(Java DataBase Connection) 是用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,由一组用Java语言编写的类和接口组成,是JAVA访问数据库的基石,如Hibernate,Mybatis其实都是对JDBC的封装。JDBC为访问不同数据库提供了一种统一的途径。
JDBC的使用
配置驱动
-
JDBC是用于连接数据库的,所以要先去并配置连接数据库的驱动:mysql-connector-java-x.x.x.jar,下载地址(5.1.47版本):
https://dev.mysql.com/get/Downloads/Connector-J/mysql-connector-java-5.1.47.zip
解压后,找到里面的mysql-connector-java-5.1.47.jar文件,然后在IDEA新建一个名为lib的Directory,将jar包拷贝进去,右键,Add as Library即可。
-
在将驱动加载好,并能成功连上数据库后,开始使用JDBC。
操作步骤
- 加载注册驱动
- 连接数据库
- 创建语句对象
- 执行sql语句
- 释放资源
import org.junit.Test;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
public class JDBCTest {
@Test
public void test1() throws Exception{
String sql = "select * from users";
//1.加载注册驱动
Class.forName("com.mysql.jdbc.Driver");
//2.连接数据库
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbcstudy","root","455426482");
//3:创建语句对象
Statement st=conn.createStatement();
//4:执行SQL语句
ResultSet resultSet =st.executeQuery(sql);
while (resultSet.next()){
System.out.println(resultSet.getObject("id"));
System.out.println(resultSet.getObject("name"));
System.out.println(resultSet.getObject("password"));
System.out.println(resultSet.getObject("email"));
System.out.println(resultSet.getObject("birthday"));
}
//5:释放资源
resultSet.close();
st.close();
conn.close();
}
}
- 通过上面代码,加载注册驱动只有一句代码
Class.forName("com.mysql.jdbc.Driver")
,计算机时如何通过这一句代码注册驱动的呢?
通过源码:
- 在编译这句代码时,计算机会将"com.mysql.jdbc.Driver"加载进JVM中;
- 当一份字节码加载进JVM中,JVM就会找到mysql-connector-java-x.x.x.jar包下的Driver类,从而new 一个Driver对象。
- 获取连接中,通过
DriverManager.getConnection(url,username,password)
来获取连接对象,其中URL为:数据库的地址;Username为:数据库的账号;password为:数据库的密码。Connection对象是获取语句对象的关键。
建立工具类并对异常的处理
由于在开发中JDBC会经常使用,我们不可能每执行一次SQL就写一次JDBC,为了减少重复的操作也就是加载驱动和连接数据库,我们可以写一个工具类和一个配置文件,在这个工具类中使用类加载器将配置文件的信息加载进来;而且由于之前为了演示我们将异常在方法中抛了出去,而真正开发中我们需要对异常经行处理,而释放资源是必须要做的,所以我们需要将每一步都放进finally中:
driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/数据库名
username = 用户名
password = 数据库密码
package util;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;
public class JDBCUtils {
static Properties p = new Properties();
static {//在静态代码块中可以一建立JDBCUtils对象就加载进JVM
try {
//加载配置文件
InputStream is = JDBCUtils.class.getClassLoader().
getResourceAsStream("db.properties");
p.load(is);
Class.forName(p.getProperty("driver"));
} catch (Exception e) {
e.printStackTrace();
}
}
//获取连接对象
public static Connection getConn(){
try {
return DriverManager.getConnection(p.getProperty("url"),
p.getProperty("username"),
p.getProperty("password"));
}catch (Exception e){
}
return null;
}
//释放资源
public static void close(ResultSet resultSet,PreparedStatement preparedStatement,Connection connection){
try {
if (resultSet!=null){
resultSet.close();
}
}catch (Exception e){
}finally {
try {
if (preparedStatement!=null){
preparedStatement.close();
}
}catch (Exception e){
}finally {
try {
if (connection!=null){
connection.close();
}
}catch (Exception e){
}
}
}
}
}
预编译语句对象preparedStatement
在使用Statement语句对象时,执行sql操作都是使用字符串,但这种方式不安全,黑客可以用拼接字符串的方式将sql语句连接起来,并且可以返回结果(见:https://blog.youkuaiyun.com/mqingo/article/details/84558356 );而且相较于Statement语句对象,preparedStatement语句对象更加灵活,可以使用占位符将关键字代替,并在后面单独设置占位符的值,更加安全灵活。
import org.junit.Test;
import util.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JDBCUtilsTest {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
@Test
public void test1(){
try {
//因为JDBCUtils中将加载数据库驱动放在了静态代码块中执行,所以使用JDBCUtils不用再去加载数据库驱动
//1.获取数据库连接对象
connection = JDBCUtils.getConn();
String sql = "insert into users(id,name,password,email,birthday) values(?,?,?,?,?);";
//2.获取预编译语句对象
preparedStatement = connection.prepareStatement(sql);
//3.设置占位符参数
preparedStatement.setInt(1,7);
preparedStatement.setString(2,"igor");
preparedStatement.setString(3,"12345");
preparedStatement.setString(4,"igor@gmail");
preparedStatement.setString(5,"1995-05-13");
//4.执行SQL
preparedStatement.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}finally {
//4.释放资源
JDBCUtils.close(null,preparedStatement,connection);
}
}
}