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;

在这里插入图片描述
当然,用可视化工具进行鼠标操作那也行
然后建立一张表

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
在这里插入图片描述
然后把下好的mysql-connector放进去,注意版本要对应上
如果不知道mysql版本,那么可以通过这条语句查询

select version();

在这里插入图片描述
然后
在这里插入图片描述
这样就算安装完毕了

IDEA连接数据库

这个是可选的,不一定需要这么做
不过也就几步,配置之后方便一点
在这里插入图片描述
然后右边就弹出来一个窗口
在这里插入图片描述
点击加号,然后选择数据源,打开MySQL

如果没有其他要求的话,配置这两项就行
在这里插入图片描述
然后点这里进行设置
在这里插入图片描述
选择我们需要显示的数据库

在这里插入图片描述

如果一切正常那么应该可以选择转跳到查询控制台
在这里插入图片描述
这里可以切换数据库和表
在这里插入图片描述

随便来点SQL看看
在这里插入图片描述
能跑,这就很好

IDEA修改数据库

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

这里唯一需要注意的就是,每次修改数据后,要先提交再刷新才会生效
在这里插入图片描述

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

开始使用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篇吧。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

碳苯

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值