Java学习笔记_从零到Web全栈:JDBC篇

前言

爷要全栈(全干工程师)
前置知识是Java基础和Mysql数据库,这两个可以参考我的保姆级入门教程:
MySQL数据库学习笔记:0基础入门到入坑,2小时极速上手
Java学习笔记_从零到Web全栈:Java基础篇

概念:什么是JDBC

JDBC,Java数据库连接(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数据库的应用程序接口,提供了诸如查询和更新数据库中数据的方法。我们通常说的JDBC是面向关系型数据库的。
(以上文字来自百度百科)

准备工作

至少得会Java和Mysql吧,
如果知识储备不够的话,可以看看我放在开头的两篇博客
创建一个数据库

准备一个数据库

create database jdbc_learner charset set gbk;

Java学习笔记_从零到Web全栈:JDBC篇_第1张图片
当然,用可视化工具进行鼠标操作那也行
然后建立一张表

USE jdbc_learner;

CREATE TABLE USER( 
	id INT PRIMARY KEY AUTO_INCREMENT, 
	username VARCHAR(20), 
	`password` VARCHAR(20), 
	nickname VARCHAR(20), age INT 
); 

INSERT INTO `user` VALUES(NULL, '张小丽', '123', '大力'  ,23);
INSERT INTO `USER` VALUES(NULL, '李华'  , '456', '李英语',23);

不过还是可视化操作吧…一行一行弄太麻烦了
在这里插入图片描述

导入数据库驱动

先建立一个普通项目
然后建立一个目录叫做lib
Java学习笔记_从零到Web全栈:JDBC篇_第2张图片
然后把下好的mysql-connector放进去,注意版本要对应上
如果不知道mysql版本,那么可以通过这条语句查询

select version();

在这里插入图片描述
然后
Java学习笔记_从零到Web全栈:JDBC篇_第3张图片
这样就算安装完毕了

IDEA连接数据库

这个是可选的,不一定需要这么做
不过也就几步,配置之后方便一点
Java学习笔记_从零到Web全栈:JDBC篇_第4张图片
然后右边就弹出来一个窗口
Java学习笔记_从零到Web全栈:JDBC篇_第5张图片
点击加号,然后选择数据源,打开MySQL

如果没有其他要求的话,配置这两项就行
Java学习笔记_从零到Web全栈:JDBC篇_第6张图片
然后点这里进行设置
在这里插入图片描述
选择我们需要显示的数据库

Java学习笔记_从零到Web全栈:JDBC篇_第7张图片

如果一切正常那么应该可以选择转跳到查询控制台
Java学习笔记_从零到Web全栈:JDBC篇_第8张图片
这里可以切换数据库和表
在这里插入图片描述

随便来点SQL看看
Java学习笔记_从零到Web全栈:JDBC篇_第9张图片
能跑,这就很好

IDEA修改数据库

和上节内容一样,这节也不是必要的,不过配置了之后比较方便,就可以不再使用外部的可视化工具了
双击一张表进入界面
在这里插入图片描述

这里唯一需要注意的就是,每次修改数据后,要先提交再刷新才会生效
Java学习笔记_从零到Web全栈:JDBC篇_第10张图片

接下来我们就可以正式开始了

开始使用JDBC

先直接上一套代码,后面再解释

package JDBC_Learner;

import java.sql.*;

public class HelloJDBC {
     
    public static void main(String args[]) throws ClassNotFoundException, SQLException {
     
        //1.加载驱动
        //mysql8以下为 com.mysql.jdbc.Driver
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.用户信息和url
        //?后面那个是为了支持中文和安全连接,要背下来
        String url = "jdbc:mysql://localhost:3306/jdbc_learner?useSSL=false&serverTimezone=UTC";
        //3.连接成功,数据库对象
        //实例化一个数据库对象
        Connection connection = DriverManager.getConnection(url, "root", "root");
        //4.创建 执行SQL的对象
        Statement statement = connection.createStatement();
        //5.执行SQL
        String sql = "SELECT * FROM `user`";
        ResultSet resultSet = statement.executeQuery(sql);//执行结果的集合
		//因为是链表形式的,所以这么遍历
        while(resultSet.next()){
     
            System.out.println(resultSet.getObject("id"));
            System.out.println(resultSet.getObject("username"));
            System.out.println(resultSet.getObject("password"));
            System.out.println(resultSet.getObject("nickname"));
            System.out.println(resultSet.getObject("age"));
        }
        //6.释放连接
        resultSet.close();
        statement.close();
        connection.close();
    }

}

看了以上代码,估计大家还是懵逼
接下来我们会分几个部分解释以上代码

1.加载驱动

这一部分是个固定写法,就是注册mysql驱动
(实际上JDBC5.0之后就不再需要注册了,但是我还是写上)

        //1.加载驱动
        //mysql8以下为 com.mysql.jdbc.Driver
        Class.forName("com.mysql.cj.jdbc.Driver");

2.链接数据库

格式是:“(协议,默认为jdbc:mysql): //(ip地址):(mysql的端口号) /(数据库名称)?(参数1)&(参数2)&(参数3)

String url = "jdbc:mysql://localhost:3306/jdbc_learner?useSSL=false&serverTimezone=UTC";

3.获取数据库对象

url就是2中那个字符串
其后两个参数分别是数据库的用户名和密码
这个对象将会代表数据库,可以进行提交、事务回滚等等操作

//实例化一个数据库对象
        Connection connection = DriverManager.getConnection(url, "root", "root");

4.获取执行类对象

这个对象可以用来执行SQL语句(本质上是向数据库发送SQL并执行)

        //4.创建 执行SQL的对象
        Statement statement = connection.createStatement();

具体的方式如下

这些方法的参数都是一条SQL语句,具体效果见其后注释

        statement.executeQuery("");     //查询----返回一个结果集
        statement.executeUpdate("");    //更新、插入、删除----返回受影响的行数
        statement.execute("");          //任何SQL----返回布尔值,代表是否执行成功

execute执行任何sql语句,但是只返回一个布尔值代表是否成功,所以对于查询等操作来说,还是得用executeQuery来做
查询到的结果需要用一个ResultSet类型(结果集)的变量来接收,并且其底层是一个链表,遍历则需要这么做(看上去是迭代器?):

        while(resultSet.next()){
     
            System.out.println(resultSet.getObject("id"));
            System.out.println(resultSet.getObject("username"));
            System.out.println(resultSet.getObject("password"));
            System.out.println(resultSet.getObject("nickname"));
            System.out.println(resultSet.getObject("age"));
        }

5.获得返回的结果集

这就是上面提到的结果集,常用于接收查询的内容

        String sql = "SELECT * FROM `user`";
        ResultSet resultSet = statement.executeQuery(sql);//执行结果的集合

6.断开链接,释放资源

这个没啥好说的,就是断开

        //6.释放连接
        resultSet.close();
        statement.close();
        connection.close();

更安全的操作

statement这样直接运行整段SQL的操作使得SQL注入攻击变得容易
所以我们建议使用preparedStatement
还是直接先上代码

package JDBC_Learner;

import java.sql.*;

public class SafeSQL{
     
  public static void main(String args[]){
     
      try{
     
          //启动引擎
          Class.forName("com.mysql.cj.jdbc.Driver");
          //数据库地址
          String url = "jdbc:mysql://localhost:3306/jdbc_learner?useSSL=false&serverTimezone=UTC";
          //数据库对象
          Connection connection =  DriverManager.getConnection(url,"root","root");

			//sql命令,这种写法的value用?当占位符
			//分别对应每个参数
          String sql = "insert into user(id, username, `password`, nickname, age) values(?,?,?,?,?)";
		//!!!本次讲解的内容:更安全的SQL执行对象
		//注意,右边那个是prepare,左边是prepared!
          PreparedStatement pst = connection.prepareStatement(sql);
		//下面是插入数据,第一个参数是对应value中?的下标,从1开始
          //id是自增的还是要管
		  pst.setInt(1,6);
          //username
          pst.setString(2, "Serio");
          //password
          pst.setString(3,"1024");
          //nickname
          pst.setString(4,"碳苯");
          //age
          pst.setInt(5,23);

          //执行,这里不用写sql语句
          //返回值是影响的行数,如果大于0说明执行成功
          if(pst.executeUpdate() > 0){
     
              System.out.println("执行成功");
          }

//对了,之前忘说了,上述很多代码如果不用异常抛出/捕获的话是会报错的
      }catch(SQLException e){
     
          System.out.println("哎呀,SQL出现蜜汁错误了");
          System.out.println(e);
      }catch(ClassNotFoundException e){
     
          System.out.println("不是吧,Class没有找到诶");
          System.out.println(e);
      }
  }
}

接下来我们挑出重要的部分说

//sql命令,这种写法的value用?当占位符
//分别对应每个参数
String sql = "insert into user(id, username, `password`, nickname, age) values(?,?,?,?,?)";
//!!!本次讲解的内容:更安全的SQL执行对象
//注意,右边那个是prepare,左边是prepared!
PreparedStatement pst = connection.prepareStatement(sql);

?作为占位符,第一个?对应id,第二个对应username…以此类推
并且?的下标是从1开始的

至于下面那行代码,可以类比之前提到的SQL执行对象(statement)
注意左边是prepared~,也就是预处理过的;右边是prepare ~,是预处理

后面是插入值

          //id是自增的但是还是要管
		  pst.setInt(1,7);
          //username
          pst.setString(2, "Serio");
          //password
          pst.setString(3,"1024");
          //nickname
          pst.setString(4,"碳苯");
          //age
          pst.setInt(5,23);

第一个参数是?的下标,第二个是值

其他的依次填需要的内容就行
有了这个操作,前后端交互就只有亿墙之隔了,这个后面JavaWeb篇再说

JDBC开启事务

package JDBC_Learner;

import java.sql.*;

public class Transaction {
     
    public static void main(String[] args){
     
        //放在外面。看了后面就知道了
        Connection connection = null;
        try{
     
            //注册mysql驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //创建数据库对象
            String url = "jdbc:mysql://localhost:3306/jdbc_learner?useSSL=false&serverTimezone=UTC";
            connection = DriverManager.getConnection(url,"root", "root");

            //关闭自动提交(默认开启事务
            connection.setAutoCommit(false);

            String sql1 = "UPDATE user set age = age - 100 where username = ?";
            String sql2 = "UPDATE user set age = age + 100 where username = ?";
            PreparedStatement pst1 = connection.prepareStatement(sql1);
            PreparedStatement pst2 = connection.prepareStatement(sql2);
            pst1.setString(1,"李华");
            pst2.setString(1,"微优易");
            pst1.executeUpdate();
            pst2.executeUpdate();

            //事务结束,提交
            pst1.close();
            pst1.close();

            connection.commit();
        }catch(ClassNotFoundException e){
     
            System.out.println("没有找到这个类诶");
            System.out.println(e);
        }catch(SQLException e){
     
            System.out.println("不是吧,SQL都出错了");
            try {
     
                connection.rollback();
            } catch (SQLException throwables) {
     
                System.out.println("不得了了,回滚出问题了!");
            }
            System.out.println(e);
        }
    }
}

这里主要说一下事务的开启和关闭

这个字面意思是关闭自动提交,这个时候就会默认开启事务

//关闭自动提交(默认开启事务
connection.setAutoCommit(false);

整个事件结束后手动提交
就和return一样,提交之后的代码不会再执行

connection.commit();

另外说一下异常捕获这里
为了让catch作用域内也能使用connection对象,所以一开始我们把它放到全局并初始化为null
回滚是事务发生异常的时候进行的,所以放到catch里面
但是直接放到catch里面,又会报错说“没有处理的SQL异常”
所以需要在catch里面再套一层try—catch

catch(SQLException e){
     
            System.out.println("不是吧,SQL都出错了");
            try {
     
            //回滚
                connection.rollback();
            } catch (SQLException throwables) {
     
                System.out.println("不得了了,回滚出问题了!");
            }
            System.out.println(e);
        }

后记

JDBC基础大概就这么多了,增删改查没给大家全部演示,因为我觉得这是SQL的内容,JDBC只要掌握语法就好了。毕竟后面学了框架那些估计也要用得少了。
总的来说,我觉得我这篇写的挺水的…自己倒是看得懂…就不太清楚读者的感受了…欢迎补充和批评指正!
后面看看情况更新JavaWeb篇吧。

你可能感兴趣的:(后端,java,jdbc,mysql)