概念及快速入门
Java DataBase Connectivity(JDBC),用Java连接并操作数据库
- 本质:官方(sun公司)定义的一套操作所有关系型数据库的规则,就是接口,各大数据库厂商去实现这套接口,提供数据库驱动jar包,我们可以使用这套接口(JDBC)编程,真正执行的代码是驱动jar包中的实现类
快速入门步骤
导入mysql版本相对应的jar包
- 复制jar包到项目的libs目录下
- 右键libs-->
Add As Library
- 注册驱动
- 获取数据库连接对象 Connection
- 定义sql语句
- 获取执行sql语句的对象 Statement
- 执行sql,接受返回结果
- 处理结果
- 释放资源
注意点
- 不同的mysql版本一定需要对应不同的JDBC,可以去官网查询
尤其需要注意:MySQL 8.0以上版本的数据库连接有所不同
MySQL 8.0 以上版本驱动包版本 mysql-connector-java-8.X.jar
MySQL 版本和 mysql-connector-java 版本对应关系如下,MySQL官方也是推荐使用 mysql-connector-java-8.X.jar 去连接 MySQL 8.0 的版本
Connector/J version Driver Type JDBC version MySQL Server version Status 5.1 4 3.0, 4.0, 4.1, 4.2 5.6, 5.7, 8.0* General availability 8.0 4 4.2 5.6, 5.7, 8.0 General availability. Recommended version com.mysql.jdbc.Driver 更换为 com.mysql.cj.jdbc.Driver
//5.0几版本 com.mysql.jdbc.Driver //8.0几版本 com.mysql.cj.jdbc.Driver
MySQL 8.0 以上版本不需要建立 SSL 连接的,需要显式关闭。
MySQL 5.7 之前版本,安全性做的并不够好,比如安装时生成的root空密码账号、存在任何用户都能连接上的 test 库等,导致数据库存在较大的安全隐患。从5.7版本开始MySQL官方对这些问题逐步进行了修复,到了 MySQL 8.0 以上版本已经不需要使用 SSL 进行连接加密了。但是高版本仍然保留了这个接口,所以需要在连接的时候手动写明是否需要进行 SSL 连接,这里我们手动关闭 SSL 连接加密就OK。
useSSL=false
最后还需要设置 CST。也就是设置时区
serverTimezone=UTC
代码实现
public static void main(String[] args) throws Exception { //导入相对应的驱动jar包 //注册驱动,这里我使用的mysql8.0以后的版本 Class.forName("com.mysql.cj.jdbc.Driver"); //获取数据库的连接对象,如果是5.0几版本的mysql,只需要"jdbc:mysql://127.0.0.1:3306/testmysql"即可 Connection conn = DriverManager.getConnection( "jdbc:mysql://127.0.0.1:3306/testmysql?useSSL=false&serverTimezone=UTC", "root", "zxasqw12"); //定义一个sql语句 String sql = "update salgrade set LOSAL = 700 where GRADE = 1"; //获取执行sql的对象Statement Statement stmt = conn.createStatement(); //执行sql int count = stmt.executeUpdate(sql); //处理结果 System.out.println(count); //释放资源 stmt.close(); conn.close(); }
各个类详解
DriverManager
驱动管理对象
功能
注册驱动:告诉程序该使用哪一个数据库驱动jar
DriverManager下面有一个方法
static void registerDriver(Driver driver)
:注册与给定的驱动程序DriverManager
但为什么我们写注册驱动代码的时候还需要写
Class.forName("com.mysql.jdbc.Driver");
?我们可以查看JDBC源码,在com.mysql.jdbc.Driver
类中存在静态代码块static { try { //往DriverManager中注册自身驱动 java.sql.DriverManager.registerDriver(new Driver()); } catch (SQLException E) { throw new RuntimeException("Can't register driver!"); } }
- 注意在MySQL5之后的驱动jar包其实可以省略注册驱动的步骤的,这是因为在你相对于的jar包下
META-INF-->services-->java.sql.Driver
中,有这一行代码
com.mysql.cj.jdbc.Driver
- 所以你没有写注册驱动的代码,它也会自动帮你注册驱动,但为了让其他看代码的人更容易理解,所以还是手动加上注册驱动的代码
- 注意在MySQL5之后的驱动jar包其实可以省略注册驱动的步骤的,这是因为在你相对于的jar包下
获取数据库连接
- 方法
public static Connection getConnection(String url,String user, String password)
参数
url:指定连接的路径
- 语法
"jdbc:mysql://ip地址(域名):端口号/数据库名称"
- 例子
"jdbc:mysql://127.0.0.1:3306/testmysql"
- 细节:如果连接的是本机mysql服务器,并且mysql服务器默认端口是3306,则url可以简写为:
jdbc:mysql:///数据库名称
- user:用户名
- password:密码
Connection
数据库连接对象
功能:
获取执行sql的对象
Statement createStatement()
PreparedStatement prepareStatement(String sql)
管理事务
- 开启事务
//调用该方法设置参数为false,即开启事务 void setAutoCommit(boolean autoCommit)
- 提交事务
void commit()
- 回滚事务
void rollback()
Statement
执行sql的对象
执行sql
可以执行任意的sql语句,
了解即可
boolean execute(String sql)
主要执行DML(insert,update,delete)语句,也可以但是很少执行DDL(create,alter,drop)语句,这里的返回值很总要,返回的是sql语句影响的行数,可以通过返回值了解到sql语句是否执行成功
int executeUpdate(String sql)
例子
- 添加一条记录到表
/** * account表,添加一条insert语句记录 */ public class Demo02 { public static void main(String[] args) { Statement stmt = null; Connection conn = null; try { //注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //定义sql String sql = "insert into salgrade values(6,5000,8888)"; //获取执行sql对象 conn = DriverManager.getConnection( "jdbc:mysql:///testmysql?useSSL=false&serverTimezone=UTC", "root", "zxasqw12"); //执行sql的对象 Statement stmt = conn.createStatement(); //执行sql,返回影响的行数 int count = stmt.executeUpdate(sql); //处理结果 System.out.println(count); if (count > 0) { System.out.println("添加成功"); } else { System.out.println("添加失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); } finally { //释放资源 //因为stmt与conn在try里面定义,相当于一个局部变量,所以直接释放会报错,需要在外面定义 //并且因为coon有可能报错,如果报错直接跳进catch,仍然为null,所以需要判断是否为null,避免空指针异常 if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
- 修改表记录
/** * 修该表的记录 */ public class Demo03 { public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { //注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //定义sql String sql = "update salgrade set LOSAL = 6000 where GRADE = 6"; //获取连接对象 conn = DriverManager.getConnection( "jdbc:mysql:///testmysql?useSSL=false&serverTimezone=UTC", "root", "zxasqw12"); //获取执行sql对象 stmt = conn.createStatement(); //执行sql int count = stmt.executeUpdate(sql); //处理结果 System.out.println(count); if (count > 0) { System.out.println("修改成功"); } else { System.out.println("修改失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); } finally { //释放资源 if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
- 删除表中的记录
/** * 删除表中的记录 */ public class Demo04 { public static void main(String[] args) { Connection conn = null; Statement stmt = null; try { //注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //定义sql String sql = "delete from salgrade where GRADE = 6"; //获取连接对象 conn = DriverManager.getConnection( "jdbc:mysql:///testmysql?useSSL=false&serverTimezone=UTC", "root", "zxasqw12"); //获取执行sql对象 stmt = conn.createStatement(); //执行sql int count = stmt.executeUpdate(sql); //处理结果 System.out.println(count); if (count > 0) { System.out.println("删除成功"); } else { System.out.println("删除失败"); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException throwables) { throwables.printStackTrace(); } finally { //释放资源 if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } } }
执行DQL(select)语句
ResultSet executeQuery(String sql)
ResultSet
结果集对象,封装查询结果
- 游标向下移动一行,判断当前行是否有数据,如果没有数据,则返回false
boolean next()
- 获取参数
//get***(参数):获取数据
//***:代表数据类型,如:int getInt(),String getString()
int getInt(int columnIndex)
long getLong(int columnIndex)
//参数:
//1.int:代表列的编号,就像数组一样,只不过是从1开始的,如:getString(1)
//2.String:代表列名称,如:getDouble("grade")
boolean getBoolean(String columnLabel)
int getInt(String columnLabel)
- 注意:我们可以使用遍历,直接一遍遍历完全部,因为当没有数据的时候,就会返回false
/**
* 遍历表中的记录
*/
public class Demo06 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try {
//注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//定义sql
String sql = "select * from salgrade";
//获取连接对象
conn = DriverManager.getConnection(
"jdbc:mysql:///testmysql?useSSL=false&serverTimezone=UTC", "root", "zxasqw12");
//获取执行sql对象
stmt = conn.createStatement();
//执行sql
rs = stmt.executeQuery(sql);
//处理结果
while (rs.next()) {
//判断是否有数据
int grade = rs.getInt(1);
int losal = rs.getInt("LOSAL");
int hisal = rs.getInt(3);
System.out.println(grade + "---" + losal + "---" + hisal);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException throwables) {
throwables.printStackTrace();
} finally {
//释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
练习
定义一个方法,查询EMP表的数据将其封装为对象,然后装载集合并返回
- 定义Emp类
- 实现方法
public List<Emp> findAll()
- 实现
psvm
方法
Emp类
public class Emp { private int EMPNO; private String ENAME; private String JOB; private int MGR; private Date HIREDATE; private double SAL; private double COMM; private int DEPTNO; public int getEMPNO() { return EMPNO; } public void setEMPNO(int EMPNO) { this.EMPNO = EMPNO; } public String getENAME() { return ENAME; } public void setENAME(String ENAME) { this.ENAME = ENAME; } public String getJOB() { return JOB; } public void setJOB(String JOB) { this.JOB = JOB; } public int getMGR() { return MGR; } public void setMGR(int MGR) { this.MGR = MGR; } public Date getHIREDATE() { return HIREDATE; } public void setHIREDATE(Date HIREDATE) { this.HIREDATE = HIREDATE; } public double getSAL() { return SAL; } public void setSAL(double SAL) { this.SAL = SAL; } public double getCOMM() { return COMM; } public void setCOMM(double COMM) { this.COMM = COMM; } public int getDEPTNO() { return DEPTNO; } public void setDEPTNO(int DEPTNO) { this.DEPTNO = DEPTNO; } @Override public String toString() { return "Emp{" + "EMPNO=" + EMPNO + ", ENAME=" + ENAME + ", JOB=" + JOB + ", MGR=" + MGR + ", HIREDATE=" + HIREDATE + ", SAL=" + SAL + ", COMM=" + COMM + ", DEPTNO=" + DEPTNO + '}'; } }
psvm与findALL
public static void main(String[] args) { List<Emp> list = new Demo08().findAll(); System.out.println(list); System.out.println(list.size()); } /** * 查询所有emp对象 */ public List<Emp> findAll() { ResultSet rs = null; Statement stmt = null; Connection conn = null; List<Emp> list = null; try { //1.注册驱动 Class.forName("com.mysql.cj.jdbc.Driver"); //2.获取连接 conn = DriverManager.getConnection( "jdbc:mysql:///testmysql?useSSL=false&serverTimezone=UTC", "root", "zxasqw12"); //3.定义sql String sql = "select * from emp"; //4.获取执行sql的对象 stmt = conn.createStatement(); //5.执行sql rs = stmt.executeQuery(sql); //6.遍历结果集,封装对象,装载集合 Emp emp = null; list = new ArrayList<Emp>(); while (rs.next()) { //获取数据 int empno = rs.getInt("EMPNO"); String ename = rs.getString("ENAME"); String job = rs.getString("JOB"); int mgr = rs.getInt("MGR"); Date hiredate = rs.getDate("HIREDATE"); double sal = rs.getDouble("SAL"); double comm = rs.getDouble("COMM"); int deptno = rs.getInt("DEPTNO"); //创建EMP对象,并赋值 emp = new Emp(); emp.setEMPNO(empno); emp.setENAME((ename)); emp.setJOB(job); emp.setMGR(mgr); emp.setHIREDATE(hiredate); emp.setSAL(sal); emp.setCOMM(comm); emp.setDEPTNO(deptno); //装载集合 list.add(emp); } } catch (ClassNotFoundException e) { e.printStackTrace(); } catch (SQLException e) { e.printStackTrace(); } finally { if (rs != null) { try { rs.close(); } catch (SQLException e) { e.printStackTrace(); } } if (stmt != null) { try { stmt.close(); } catch (SQLException e) { e.printStackTrace(); } } if (conn != null) { try { conn.close(); } catch (SQLException e) { e.printStackTrace(); } } } return list; }