搞懂JDBC操作数据库
一、JDBC基础
JDBC 规范定义接口,具体的实现由各大数据库厂商来实现。
概述:JDBC 是 Java 访问数据库的标准规范,真正怎么操作数据库还需要具体的实现类,也就是数据库驱动。每个数据库厂商根据自家数据库的通信格式编写好自己数据库的驱动。所以我们只需要会调用
JDBC 接口中的方法即可,数据库驱动由数据库厂商提供。
1、jar包
使用cmd命令查看自己版本号选择自己的版本号,选择对应的jar版本
上图表示的是:版本号为5.7.19,MySQL的分发版本号,表明安装的是MySQL 5.7.19版本。
另外,for Win64 (x86_64)
表示您正在运行的操作系统是Windows 64位版本,并且MySQL是为该操作系统编译的。
需要使用的jar包根据数据库版本的不同,下载对应的jar包。我们这里需要使用的是mysql-connector-java-5.1.30.jar
2、JDBC核心API
3、导jar包步骤
创建一个普通的java项目,然后在根目录下创建一个libs包,导入我们的数据库jar包,然后把lib设置为library
4、注册驱动(JDBC4.0之后,就可以不用这个步骤)
方式1: DriverManager 是 Java 的一个类,它负责管理数据库驱动程序。registerDriver() 方法用于注册一个特定的数据库驱动程序,new com.mysql.jdbc.Driver() 创建了 MySQL 数据库的驱动程序对象。
//注册驱动,方法1
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
方式2: 反射机制对类加载
//注册驱动,方法2
Class.forName("com.mysql.jdbc.Driver");
方式3:将对象实例分配给 Driver 类型的变量 driver ,创建了一个可用于操作数据库连接的对象
//注册驱动,方法3
Driver driver=new com.mysql.jdbc.Driver();
5、DriverManager类
作用:管理和注册驱动;创建数据库的连接
5.1、方法
5.2、JDBC连接数据库的四个参数
二、连接数据库
1、获取连接对象
1.1 使用用户名、密码、URL 得到连接对象
使用到的数据库名为:yjg_db03
public class demo1 {
public static void main(String[] args) throws SQLException {
String url = "jdbc:mysql://localhost:3306/yjg_db03?characterEncoding=utf8";
// 使用用户名,密码,url得到连接对象
Connection con = DriverManager.getConnection(url,"root","yjg");
System.out.println(con);
}
}
执行结果
1.2 使用属性文件和 url 得到连接对象
使用到的数据库名为:yjg_db03
public class demo2 {
public static void main(String[] args) throws SQLException {
//url连接字符串
String url = "jdbc:mysql://localhost:3306/yjg_db03?characterEncoding=utf8";
//属性对象
Properties info = new Properties();
//把用户名和密码放在* *info* 对象中
info.setProperty("user","root");
info.setProperty("password","yjg");
//获取连接
Connection con = DriverManager.getConnection(url,info);
System.out.println(con);
}
}
执行结果
Connection接口:具体的实现类由数据库的厂商实现,代表一个连接对象
2、Connection 方法
3、Statement接口
代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所生成结果的对象。
①Statement 中的方法
②释放资源
由于连接数据库,进行操作之后,无论是否发生异常,我们都要执行释放资源这个步骤,那么,这个释放资源的操作,就可以放在finally代码块中。
4、JDBC具体操作
4.1、步骤
①注册和加载驱动(可以省略)
②获取连接
③Connection 获取 Statement 对象
④使用 Statement 对象执行 SQL 语句
⑤返回结果集 // DQL使用
⑥释放资源
4.2、DML操作
①创建一张表,并插入数据
CREATE TABLE IF NOT EXISTS employee(
id int(11) auto_increment PRIMARY key,
name VARCHAR(22),
age int(4),
money int(20)
);
INSERT into employee VALUES(null,"张三",20,3650);
INSERT into employee VALUES(null,"李四",30,4502);
INSERT into employee VALUES(null,"王五",30,3650);
INSERT into employee VALUES(null,"麻子",50,8885);
INSERT into employee VALUES(null,"小红",20,4445);
查询数据
②通过java代码向表中插入一条大黑牛的记录
使用到的数据库名为:yjg_db03,employee表在其里面
public class demo3 {
public static void main(String[] args) {
new demo3().insertDemo();
}
public void insertDemo() {
//创建连接对象
Connection con = null;
//创建Statement对象
Statement st = null;
try {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
con = DriverManager.getConnection
("jdbc:mysql://localhost:3306/yjg_db03? characterEncoding = utf8", "root", "yjg");
//通过连接对象得到语句对象
st = con.createStatement();
//创建SQL语句
String sql = "INSERT into employee VALUES(null,\"大黑牛\",66,6666);";
//删除操作
//String sql = "DELETE from employee where id<3;";
//用于执行 SQL 更新语句的方法
st.executeUpdate(sql);
System.out.println("操作成功!");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
if (st != null) {
try {
st.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
查询结果
4.3、DQL操作
①ResultSet接口:封装数据库查询的结果集,对结果集进行遍历,取出每一条记录。
使用到的数据库名为:yjg_db03,employee表在其里面
public class demo4 {
public static void main(String[] args) {
new demo4().insertDemo();
}
public void insertDemo() {
//创建连接对象
Connection con = null;
//创建Statement对象
Statement st = null;
try {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取连接对象
con = DriverManager.getConnection
("jdbc:mysql://localhost:3306/yjg_db03? characterEncoding=utf8", "root", "yjg");
//通过连接对象得到语句对象
st = con.createStatement();
//创建SQL语句
String sql = "SELECT * from employee;";
ResultSet rs = st.executeQuery(sql);
//rs相当于一个指向器,最开始指向的是外部而不是第一个数据
//所以需要一开始调用next方法
while (rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
int money = rs.getInt("money");
System.out.println("编号:" + id + ", 姓名:" + name + ", 年龄:" +
age + ", 工资:" + money);
}
System.out.println("操作成功!");
//关闭流
rs.close();
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
if (st != null) {
try {
st.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
执行结果
ResultSet 接口中的注意事项:
① 如果光标在第一行之前,使用 rs.getXX()获取列值,报错:Before start of result set
② 如果光标在最后一行之后,使用 rs.getXX()获取列值,报错:After end of result set
③ 使用完毕以后要关闭结果集 ResultSet,再关闭 Statement,再关闭 Connection
三、PreparedStatement
1、PreparedStatement是什么
是 Statement 接口的子接口,继承于父接口中所有的方法,它是一个预编译的 SQL 语
句。
2、PreparedStatement 与Statement 的比较
①Statement 在进行输入插入的时候,都会发送一条SQL语句给数据库,数据库先编译SQL语句,然后
执行,返回结果,如果有一万条插入的SQL语句,那么数据库就需要先编译一万次,这样就会导致效率
低下;PreparedStatement在进行数据插入的时候,会先发送SQL语句预编译,PreparedStatement就
会引用预编译的结果,如果多次插入的内容相同的话,就只需要预编译一次,只是每一次执行SQL语句
的时候参数不一样。这样就提高了效率。
②PreparedStatement可以有效的防止 SQL 注入的问题,安全性更高。
3、PreparedStatement使用步骤
①编写 SQL 语句,未知内容使用?占位:“SELECT * FROM user WHERE name=? AND password=?”;
②获得 PreparedStatement 对象;
③设置实际参数:setXxx(占位符的位置, 真实的值);
④执行参数化 SQL 语句;
⑤关闭资源
4、PreparedStatement 的常用方法
1.创建配置文件
这里我们使用配置文件来连接数据库
jdbc.properties的内容
使用到的数据库名为:yjg_db03,employee表在其里面
Driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/yjg_db03?useUnicode=true&characterEncoding=UTF-8
user = root
password = yjg
# 初始化连接
initialSize=10
# 最大连接数量
maxActive=50
# 最大空闲连接
maxIdle=20
# 最小空闲连接
minIdle=5
# 超时等待时间以毫秒为单位
maxWait=60000
使用PreparedStatement操作
public class demo5 {
public static void main(String[] args) throws ClassNotFoundException {
new demo5().insertDemo();
}
public void insertDemo() throws ClassNotFoundException {
//ResourceBundle.getBundle("config/jdbc") 是一个用于获取 Java 属性资源文件的方法。
// 在这个方法中,config/jdbc 是一个属性文件的路径,表示要获取的资源文件。
ResourceBundle rb=ResourceBundle.getBundle("config/jdbc");
//注册驱动
Class.forName(rb.getString("Driver"));
//创建连接对象
Connection con = null;
//创建PreparedStatement对象
PreparedStatement pr = null;
try {
//注册驱动
Class.forName("com.mysql.jdbc.Driver");
//获取数据库连接对象
con= DriverManager.
getConnection(rb.getString("url"),rb.getString("user"),rb.getString("password"));
//通过数据库连接对象创建数据库语句操作对象
pr=con.prepareStatement( "select * from employee where id<?;");
//将位置为1的参数,设置为5
pr.setInt(1,5);
//获取结果集
ResultSet rs = pr.executeQuery();
//rs相当于一个指向器,最开始指向的是外部而不是第一个数据
//所以需要一开始调用next方法
while (rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name");
int age = rs.getInt("age");
int money = rs.getInt("money");
System.out.println("编号:" + id + ", 姓名:" + name + ", 年龄:" +
age + ", 工资:" + money);
}
System.out.println("操作成功!");
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
if (pr != null) {
try {
pr.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (con != null) {
try {
con.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
}
执行结果