一. JDBC概述
JDBC是Java Database Connectivity的缩写,意为Java数据库连接。是Java提供的一种数据库访问规则、规范, 由于数据库种类较多,并且java语言使用比较广泛,sun公司就提供了一种规范,让其他的数据库提供商去实现底层的访问规则。 Java程序只要使用sun公司提供的标准接口去操作数据库即可。
二. JDBC主要API
-
DriverManager (管理驱动:注册驱动、获取连接对象)
-
Connection (代表到数据库的连接,获取执行对象、管理事务、释放资源)
-
Statement、PreparedStatement (执行对象,可以执行CRUD语句、释放资源)
-
ResultSet (查询结果集对象,封装了查询结果、释放资源)
三. JDBC CRUD操作
1. JDBC操作数据库一般流程
我们在使用JDBC操作数据库时的流程是固定的:
-
加载驱动类(只需加载一次,新版本JDK可以省略)
-
获取连接对象
Connection
-
获取执行语句对象
Statement
或PreparedStatement
,执行SQL语句 -
使用
ResultSet
对象接收数据库查询结果(一般只有查询语句需要) -
将
ResultSet
中的结果封装成对应的JavaBean
类型对象 -
释放资源、关闭连接
2、操作步骤
1、下载依赖
2、在项目中引入jar包,并添加到依赖库
3、创建类,测试连接
public static void main(String[] args) throws ClassNotFoundException, SQLException {
// 1、加载驱动 (jdk8可省略)
//mysql8 com.mysql.cj.jdbc.Driver
//mysql5 com.mysql.jdbc.Driver
Class.forName("com.mysql.cj.jdbc.Driver");
// 2、建立连接
String url = "jdbc:mysql://localhost:3306/db9?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
Connection connection =
DriverManager.getConnection(url,"root","123456");
// 3、获取Statement或者PreparedStatement对象
Statement statement = connection.createStatement();
// 4、执行sql
int num = statement.executeUpdate("delete from student where sno='110' ");
// 5、获取结果集(查询)
System.out.println(num);
// 6、关闭资源并释放连接
statement.close();
connection.close();
}
}
4、实现增删改查
1)确定数据表
2)创建javabean类(和表结构对应的)
类名===表名
属性名===字段名
属性类型===字段类型
/*
javabean类
*/
public class Dept {
private int deptId;
private String deptName;
private String loc;
//省略...
}
3)写接口
package com.hl.dao;
import com.hl.pojo.Dept;
import java.util.List;
/*
部门接口
*/
public interface DeptDao {
// 新增一个部门
public int addDept(Dept dept);
// 修改部门(根据主键,修改非主键字段)
public int updateDept(Dept dept);
// 删除一个部门(根据主键删除)
public int deleteDept(int deptId);
// 查询所有部门
public List<Dept> selectAllDept();
// 根据部门名称模糊查询
public List<Dept> selectDeptByName(String deptName);
}
4)写接口实现类
package com.hl.dao;
import com.hl.pojo.Dept;
import com.hl.util.JdbcUtil;
import java.sql.*;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
public class DeptDaoImpl implements DeptDao{
@Override
public int addDept(Dept dept) {
int num = 0;
Connection connection = null;
Statement statement = null;
try {
//1、加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2、建立连接
String url = "jdbc:mysql://localhost:3306/yan9";
connection = DriverManager.getConnection(url,"root","123456");
//3、创建Statement或者PreparedStatment对象
statement = connection.createStatement();
//4、执行sql 字符串拼接 不建议使用(1拼接太复杂 2容易造成sql注入攻击)
String sql = "insert into dept(dept_name,loc) " +
"values ('"+dept.getDeptName()+"','"+dept.getLoc()+"')";
num = statement.executeUpdate(sql);
} catch (Exception e) {
e.printStackTrace();
}finally {
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
return num;
}
@Override
public int updateDept(Dept dept) {
return 0;
}
@Override
public int deleteDept(int deptId) {
return 0;
}
@Override
public List<Dept> selectAllDept() {
return Collections.emptyList();
}
// @Override
// public List<Dept> selectDeptByName(String deptName) {
// List<Dept> list = new ArrayList<>();
// Connection connection = null;
// Statement statement = null;
// ResultSet rs = null;
// try{
// //打开连接
// connection = JdbcUtil.open();
// //补全
// statement = connection.createStatement();
// String sql = "select * from dept where dept_name = '"+deptName+"'";
// //执行sql
// rs = statement.executeQuery(sql);
// while(rs.next()){
// Dept dept = new Dept();
// dept.setDeptId(rs.getInt("dept_id"));
// dept.setDeptName(rs.getString("dept_name"));
// dept.setLoc(rs.getString("loc"));
// list.add(dept);
// }
// }catch (Exception e){
// e.printStackTrace();
// }finally {
// //关闭连接
// JdbcUtil.close(rs,statement,connection);
// }
//
// return list;
// }
@Override
public List<Dept> selectDeptByName(String deptName) {
List<Dept> list = new ArrayList<>();
Connection connection = null;
PreparedStatement statement = null;
ResultSet rs = null;
try{
//打开连接
connection = JdbcUtil.open();
//补全
String sql = "select * from dept where dept_name = ?";
statement = connection.prepareStatement(sql);
//给?号占位符赋值
// statement.setString(1,"dept");
statement.setString(1,deptName);
//执行sql
rs = statement.executeQuery();
while(rs.next()){
Dept dept = new Dept();
dept.setDeptId(rs.getInt("dept_id"));
dept.setDeptName(rs.getString("dept_name"));
dept.setLoc(rs.getString("loc"));
list.add(dept);
}
}catch (Exception e){
e.printStackTrace();
}finally {
//关闭连接
JdbcUtil.close(rs,statement,connection);
}
return list;
}
}
5)测试
package com.hl.test;
import com.hl.dao.DeptDao;
import com.hl.dao.DeptDaoImpl;
import com.hl.pojo.Dept;
import java.util.List;
public class DeptDaoTest {
public static void main(String[] args) {
DeptDao dao = new DeptDaoImpl();
// Dept dept = new Dept(0,"财务部","郑州");
// int num = dao.addDept(dept);
// System.out.println(num>0 ? "新增成功" : "新增失败");
// List<Dept> list = dao.selectDeptByName("财务部' or '1'='1");
// sql注入攻击(字符串拼接)
// "select * from dept where dept_name = '"+deptName+"'";
// select * from dept where dept_name = '财务部' or '1'='1';
// List<Dept> list = dao.selectDeptByName("财务部' or '1'='1");
List<Dept> list = dao.selectDeptByName("财务部");
System.out.println(list);
}
}
Mysql 5.x和Mysql 8.x的区别
在使用JDBC操作数据库时,会发现虽然能操作成功,但是总是会出现如下的提示信息
这个提示信息的含义是现在我们使用的Mysql驱动是com.mysql.jdbc.Driver,但是新的Mysql驱动为com.mysql.cj.jdbc.Driver。为什么会出现这种提示信息呢?主要是因为我们现在使用的数据库为Mysql 8.x,而Mysql在Mysql 8.x上做出了很多更新,使得我们在使用Mysql 8.x的时候跟使用Mysql 5.x版本是有一些区别的。
-
Mysql 5.x和Mysql 8.x使用的驱动不同
//Mysql 5.x驱动加载 Class.forName("com.mysql.jdbc.Driver"); //Mysql 8.x驱动加载 Class.forName("com.mysql.cj.jdbc.Driver");
-
Mysql 5.x和Mysql 8.x使用的数据库连接不同
//Mysql 5.x数据库访问地址 private static final String URL="jdbc:mysql://localhost:3306/db9"; //Mysql 8.x数据库访问地址 private static final String URL="jdbc:mysql://localhost:3306/db9?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=Asia/Shanghai";
jdbc重要知识点
jdbc连接数据库的基本步骤(掌握**)
Statement和PreparedStatement的区别 (掌握***)
Statement接口用来执行一段SQL语句并返回结果,不支持参数占位符写法。Statement执行 ,其实是拼接sql语句的。 先拼接sql语句,然后再一起执行。如果传入的参数是一段可执行的SQL,也会被执行,有SQL注入的风险。
PreparedStatement接口继承自Statement接口,相比较以前的statement, 预先处理给定的sql语句,对其执行语法检查。 在sql语句里面使用 ? 占位符来替代后续要传递进来的变量。 后面进来的变量值,只会被看成参数值,不会产生任何的关键字的效果。
Statement支持表名、列名动态传入,如果表名、列名不固定,不能使用PreparedStatement。