爷要全栈(全干工程师)
前置知识是Java基础和Mysql数据库,这两个可以参考我的保姆级入门教程:
MySQL数据库学习笔记:0基础入门到入坑,2小时极速上手
Java学习笔记_从零到Web全栈:Java基础篇
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();
这个是可选的,不一定需要这么做
不过也就几步,配置之后方便一点
然后右边就弹出来一个窗口
点击加号,然后选择数据源,打开MySQL
如果没有其他要求的话,配置这两项就行
然后点这里进行设置
选择我们需要显示的数据库
如果一切正常那么应该可以选择转跳到查询控制台
这里可以切换数据库和表
和上节内容一样,这节也不是必要的,不过配置了之后比较方便,就可以不再使用外部的可视化工具了
双击一张表进入界面
这里唯一需要注意的就是,每次修改数据后,要先提交再刷新才会生效
接下来我们就可以正式开始了
先直接上一套代码,后面再解释
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();
}
}
看了以上代码,估计大家还是懵逼
接下来我们会分几个部分解释以上代码
这一部分是个固定写法,就是注册mysql驱动
(实际上JDBC5.0之后就不再需要注册了,但是我还是写上)
//1.加载驱动
//mysql8以下为 com.mysql.jdbc.Driver
Class.forName("com.mysql.cj.jdbc.Driver");
格式是:“(协议,默认为jdbc:mysql): //(ip地址):(mysql的端口号) /(数据库名称)?(参数1)&(参数2)&(参数3)”
String url = "jdbc:mysql://localhost:3306/jdbc_learner?useSSL=false&serverTimezone=UTC";
url就是2中那个字符串
其后两个参数分别是数据库的用户名和密码
这个对象将会代表数据库,可以进行提交、事务回滚等等操作
//实例化一个数据库对象
Connection connection = DriverManager.getConnection(url, "root", "root");
这个对象可以用来执行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"));
}
这就是上面提到的结果集,常用于接收查询的内容
String sql = "SELECT * FROM `user`";
ResultSet resultSet = statement.executeQuery(sql);//执行结果的集合
这个没啥好说的,就是断开
//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篇再说
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篇吧。