JDBC基础
JDBC是SUN公司(Oracle甲骨文公司)提供的一套用于数据库操作的接口API,Java程序员只需要面向这套接口编程即可,不同的数据库厂商,需要针对这套接口,提供不同实现。不同的实现集合,即为不同数据库的驱动,JDBC规范定义接口具体实现由各大数据库厂商来现实。
JDBC(Java Database Connectivity)是一个独立于特定数据库管理系统(DBMS)、通用的SQL数据库存取和操作的公共接口(一组API),定义了用来访问数据库的标准Java类库,使用这个类库可以以一种标准的方法,方便的访问数据库资源
JDBC是Java方法数据库的标准解决方案,真正怎么操作数据库还需要具体的实现类,也就是数据库驱动。每个数据库厂商根据自家数据库的通信方式编写好自己数据的实现类,也就是驱动,所以我们只需要会调用JDBC接口中的方法即可,数据驱动由数据库厂商提供。
JDBC开发用到的包
包 | 说明 |
---|---|
java.sql | 所有JDBC访问数据库相关的接口和类 |
javax.sql | 数据库的扩展包,提供数据库额外的功能, |
数据库的驱动 | 由各大厂商提供,需要额外下载,是对JDBC接口的实现类 |
JDBC的核心API
接口 | 说明 |
---|---|
DriverManager类 | 管理和注册数据库驱动,得到数据库连接对象 |
Connection | 一个连接对象,可用于创建Statement和PreparedStatement对象 |
Statement | 一个SQL语句对象,用于将SQL语句发送给数据库服务器 |
PreparedStatement | 一个SQL语句对象,是Statement的子接口 |
ResultSet | 用于封装数据库查询结果集,返回给客户端Java程序 |
加载注册驱动
加载和注册驱动的方法:Class.forName(数据库驱动实现类).
数据库驱动由mysql厂商提供,它的驱动类是com.mysql.cj.jdbc,Driver
(从JDBC4开始加载注册驱动这一步可以省略)
DriverManager类
- 作用:
- 管理和注册驱动
- 创建数据库连接对象,并返回一个连接对象Connection
- 我们先使用这个方法:
- public static Connection getConnection(String url,String user, String password));通过指定参数,返回一个数据库连接对象Connection
参数说明:
参数 | 说明 |
---|---|
username 用户名 | 登录数据库的用户名 |
password 密码 | 登录数据库的密码 |
url 连接字符串 | 不同的数据库URL是不同的,MySQL写法:jdbc:mysql://localhost:3306/数据库名?参数 |
URL格式说明:
JDBC URL用于表示一个被注册的驱动程序,驱动程序管理器通过这个URL选择正确的驱动程序,从而建立和数据库之间的连接。主要由三部分组成:jdbc:<子协议>:<子名称>
- 子协议:用于标识一个数据库驱动程序(数据库管理系统的名称,如mysql)
- 子名称:一种标识数据库的方法,子名称可以根据不同的子协议而变化,使用子名称就是为定位数据库提供足够的信息
MySQL的连接URL编写方式:
jdbc:mysql://主机名称:mysql服务的端口号/数据库的名称?参数=值···
- 为了保证JDBC程序和服务器端的字符集一致,我们可以通过传递参数设置服务器端的字符集
- useUnicode=true&characterEncoding=utf8
- 在JDBC6之后还需要在URL中设置时区
- serverTimezone=MGT
Connection接口
- 代表一个数据库连接对象,(具体实现是由数据库厂商实现)
- 我们使用它获得一个SQL语句对象
- Statement createStatement();创建一个SQL语句对象
- PreparedStatement prepareStatement(String sql);指定预编译的SQL语句,SQL语句中使用占位符?表示参数,创建一个SQL语句对象
Statement接口
- 代表一条SQL语句对象,用于发送SQL语句给服务器,用于执行静态SQL语句并返回它所生成结果的对象
- 方法:
- int executeUpdate(String sql);用于发送DML语句,进行增删改操作,返回的结果是SQL语句影响的表中行数
- ResultSet executeQuery(String sql);用于发送DQL语句,执行查询操作时使用,返回值是查询到的结果集
ResultSet类
- 结果集。用来存储查询结果的对象
- 使用executeQuery查询数据库后,返回的是一个二维的结果集,所以我们需要遍历这个结果集,来得到每一行的数据
- boolean next();将光标从当前位置向后移动,也就是读取下一行
- int getInt(String columnLabel);根据指定的列名(columnLabel)获得此行的指定数据
- int getInt(int columnIndex);根据指定的列的序号(columnIndex)获得此行的指定数据
- 和上面两个方法一样以此类推(getXxx)double getDoubleget···
释放资源
使用后,我们要记得释放资源
- ResultSet结果集、Statement对象、Connection对象
- 先开的后关、最后开的最先关闭(ResultSet->Statement->Connection)
- 放在finally代码块中,或者使用try()自动关闭
示例:使用JDBC在MySQL数据库中查询学生表数据
(根据本章的学习完成的最基本的简单写法)
public static void findAll() throws ClassNotFoundException {
//1、加载注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//2、准备连接数据库的信息
String username = "root";
String password = "root";
String url = "jdbc:mysql://localhost:3306/my_db01?useUnicode=true&characterEncoding=utf-8&serverTimezone=GMT";
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
//3、获得数据库连接对象
connection = DriverManager.getConnection(url,username,password);
//4、获得执行SQL语句对象
statement = connection.createStatement();
//5、准备sql语句
String sql = "select * from students";
//6、执行sql语句
resultSet = statement.executeQuery(sql);
//使用while循环一行行读取结果集中的数据
while (resultSet.next()){
//读取此行中列名为stuId的数据
int stuId = resultSet.getInt("stuId");
String stuName = resultSet.getString("stuName");
int stuAge = resultSet.getInt(3);
Date birthday = resultSet.getDate("birthday");
System.out.println(stuId+"\t"+stuName+"\t"+stuAge+"\t"+birthday);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally{
//7、关闭连接
if (resultSet!=null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (statement!=null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
if (connection!=null) {
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
}
封装数据库工具类
(根据上面的代码,简单封装一个工具类,用于了解数据库工具类的基本封装过程)
jdbc.properties配置文件,用来放一些基本配置信息
user=root
password=root
url=jdbc:mysql://localhost:3306/my_db01?useUnicode=true&characterEncoding=utf8&serverTimezone=GMT%2B8
driver=com.mysql.cj.jdbc.Driver
工具类
public class DbUtils2 {
private static String user;
private static String password;
private static String url;
static{
//获取src目录下的jdbc.properties文件
InputStream is = Thread.currentThread().getContextClassLoader().getResourceAsStream("jdbc.properties");
Properties p = new Properties();
try {
p.load(is);
Class.forName(p.getProperty("driver"));
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
user = p.getProperty("user");
password = p.getProperty("password");
url = p.getProperty("url");
}
//得到资源
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
public static Statement getStatement(Connection connection) throws SQLException {
return connection.createStatement();
}
//关闭资源
public static void close(Connection connection){
if (connection!=null){
try {
connection.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(Statement statement){
if (statement!=null) {
try {
statement.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(ResultSet resultSet){
if (resultSet!=null) {
try {
resultSet.close();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
}
public static void close(Connection connection,Statement statement){
close(statement);
close(connection);
}
public static void close(Connection connection,Statement statement,ResultSet resultSet){
close(connection,statement);
close(resultSet);
}
}
经过了简单的封装我们就可以更方便的获得资源和关闭资源!
使用自定义工具类,改进JDBC代码来完成Student的增删改查
(记得自己创建好数据库和表,并准备好和表相对应的JavaBean)
import com.bdit.com.bdit.utils.DbUtils2;
import com.bdit.model.Student;
import java.sql.*;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
public class JdbcTest3 {
public static void main(String[] args) {
//增加
Timestamp timestamp = Timestamp.valueOf(LocalDateTime.now());
Student student = new Student(1004,"小明",100,timestamp,"坏蛋");
if (insert(student)){
System.out.println("===============添加成功==============");
}else{
System.out.println("===============添加失败==============");
}
//删除
if (delete(1004)) {
System.out.println("===============删除成功==============");
} else {
System.out.println("===============删除失败==============");
}
//修改
Student student2 = new Student(1111,"zhangsan",10,timestamp,"坏ren");
if (update(1001,student2)){
System.out.println("===============修改成功==============");
}else {
System.out.println("===============修改失败==============");
}
//查询
System.out.println(findById(1001));
System.out.println(findAll());
}
/**
* 添加数据
* @param student 需要添加的student对象
* @return 成功
*/
public static boolean insert(Student student){
Connection connection = null;
Statement statement = null;
int n =0;
try {
connection = DbUtils2.getConnection();
statement = DbUtils2.getStatement(connection);
String sql = "insert into students(stuId,stuName,stuAge,birchday,des)values("+student.getStuId()+",'"+student.getStuName()+"',"+student.getStuAge()+",'"+ student.getBirchday()+"','"+student.getDes()+"')";
n = statement.executeUpdate(sql);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally{
DbUtils2.close(connection,statement);
}
if (n!=0){
return true;
}
return false;
}
/**
* 根据id删除行
* @param id 需要删除的行
* @return 成功
*/
public static boolean delete(Integer id){
Connection connection = null;
Statement statement = null;
int n =0;
try {
connection = DbUtils2.getConnection();
statement = DbUtils2.getStatement(connection);
String sql = "delete from students where stuId="+id;
n = statement.executeUpdate(sql);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally{
DbUtils2.close(connection,statement);
}
if (n!=0){
return true;
}
return false;
}
/**
* 修改数据
* @param id 需要修改数据的行 id
* @param student 修改后的值
* @return 成功
*/
public static boolean update(Integer id,Student student){
Connection connection = null;
Statement statement = null;
int n =0;
try {
connection = DbUtils2.getConnection();
statement = DbUtils2.getStatement(connection);
String sql = "update students set stuName='"+student.getStuName()+"',stuAge="+student.getStuAge()+",birchday='"+ student.getBirchday()+"',des='"+student.getDes()+"' where stuId="+id;
n = statement.executeUpdate(sql);
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally{
DbUtils2.close(connection,statement);
}
if (n!=0){
return true;
}
return false;
}
/**
* 根据id查询数据
* @param id 唯一id
* @return student对象
*/
public static Student findById(Integer id){
Student student = null;
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = DbUtils2.getConnection();
statement = DbUtils2.getStatement(connection);
String sql = "select * from students where stuId="+id;
resultSet = statement.executeQuery(sql);
if (resultSet.next()){
student = new Student();
student.setStuId(resultSet.getInt("stuId"));
student.setStuName(resultSet.getString("stuName"));
student.setStuAge(resultSet.getInt("stuAge"));
student.setBirchday(resultSet.getTimestamp("birthday"));
student.setDes(resultSet.getString("des"));
}else {
System.out.println("**************未查询到指定内容***************");
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DbUtils2.close(connection,statement,resultSet);
}
return student;
}
/**
* 查询所有
* @return 所有数据的集合
*/
public static List<Student> findAll(){
List<Student> list = new ArrayList<>();
Student student = null;
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
connection = DbUtils2.getConnection();
statement = DbUtils2.getStatement(connection);
String sql = "select * from students ";
resultSet = statement.executeQuery(sql);
while (resultSet.next()){
student = new Student();
student.setStuId(resultSet.getInt("stuId"));
student.setStuName(resultSet.getString("stuName"));
student.setStuAge(resultSet.getInt("stuAge"));
student.setBirchday(resultSet.getTimestamp("birthday"));
student.setDes(resultSet.getString("des"));
list.add(student);
}
} catch (SQLException throwables) {
throwables.printStackTrace();
}finally {
DbUtils2.close(connection,statement,resultSet);
}
return list;
}
}
(第一章的学习,首先了解和简单使用JDBC!一定要熟悉这几个步骤,后面继续学习也是基于这些基本操作的。)