1.简介
JDBC接口:sun公司提供数据库的统一连接规范,在JDK中(java.sql,javax.sql中)
数据库驱动(Connector) :JDBC接口的具体实现,是个数据库管理系统的厂商实现的
2.基本概念
java Application | Java应用程序 |
---|---|
JDBC API | JDBC提供的API |
JDBC DriverManager (管理驱动的注册) | 管理注册驱动 |
驱动的JDBC驱动 (各大厂商的数据库驱动) | 厂商数据库驱动 |
数据库管理系统 | 厂商数据库管理系统 |
3.开发步骤
1.注册数据库驱动:让JDBC连接的是哪个数据库驱动
2.获取连接
3.发送SQL命令
4.获取响应数据并处理
5.释放资源
二.Java 连接MySQL
1.注册驱动
/** 原生DriverManager方式注册
参数:java.sql.Driver 传递的是com.mysql.jdbc.Driver
(public class Driver extends NonRegisteringDriver implements java.sql.Driver)
**/
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// 加载Driver类的方式:
/*加载Driver时,会执行Driver的静态代码块,而他的静态代码块中是包含对 DriverManager.
registerDriver(new com.mysql.jdbc.Driver());的执行的。
但是他相对于原生的形式更加灵活(不同的数据库切换只需将驱动类的完全类限定名写在配置文件中即可)。*/
Class.forName("com.mysql.jdbc.Driver");
2.获取连接
//方式1
//协议:jdbc: 子协议:mysql:
Connection cnn= DriverManager
.getConnection("jdbc:mysql://localhost:3306/mktest?user=root&password=miku&useSSL=true");
//方式2
Properties props=new Properties();
props.setProperty("user", "root");
props.setProperty("password", "miku");
Connection cnn3= DriverManager
.getConnection("jdbc:mysql://localhost:3306/mktest?useSSL=true",props);
//方式3 useSSL=true 即设置SSL/TLS 校验,密文传输
String url="jdbc:mysql://localhost:3306/mktest?useSSL=true";
// url: jdbc:mysql://IP:端口/DB?参数
DriverManager.getConnection(url,"root","miku");
3.创建Statement执行SQL
1) 获得Statement对象
Statement stmt=cnn.createStatement(); //创建实例对象
2) 执行SQL脚本命令
① 查询:
ResultSet rs = stmt.executeQuery("select * from mktest.emp");
② 删除:
stmt.execute("delete from mketst.emp where empno=7788");
③ 更新:
stmt.execute("update mketst.emp set ename='Slime' where empno=7788");
④ 添加:
stmt.execute("insert into mktest.stu(sid,username,age) values(7,'kom',24)");
4.查询结果集ResultSet
结果集对象是一个存储当前游标所指向的记录的数据,通过next()移动游标(注意:游标最开始指向的是第一条记录的前面),然后可以通过getter方法(getInt,getBoolean,getString,getBigDecimal等)获得对应列的字段值。
ResultSet rs = stmt.executeQuery(sql.toString());
while(rs.next()){
System.out.println(rs.getInt("empno")+"\t"+
rs.getString("ename")+"\t"+
rs.getString("job")+"\t"+
rs.getInt("mgr")+"\t"+
rs.getDate("hiredate")+"\t"+
rs.getBigDecimal("sal")+"\t"+
rs.getBigDecimal("comm")+"\t"+
rs.getInt("deptno"));
}
5.资源的释放
//先用先关闭
rs.close();
stmt.close();
cnn.close();
6.示例
1) 查询
package com.mycat.web;
import com.mysql.jdbc.Driver;
import java.sql.*;
public class JdbcDemo2 {
public static void main(String[] args){
Connection cnn=null;
Statement stmt=null;
ResultSet rs = null;
try{
//注册MySQL驱动
DriverManager.registerDriver(new Driver());
//获得数据库连接
cnn = DriverManager
.getConnection("jdbc:mysql://localhost:3306/mktest?useSSL=true", "root", "miku");
//创建Statement对象
stmt=cnn.createStatement();
StringBuilder sql=new StringBuilder("select * from mktest.emp where 1=1 ");
sql.append("and empno > 7745");
//执行SQL获得查询结果集
rs = stmt.executeQuery(sql.toString());
while(rs.next()){
System.out.println(rs.getInt("empno")+"\t"+
rs.getString("ename")+"\t"+
rs.getString("job")+"\t"+
rs.getInt("mgr")+"\t"+
rs.getDate("hiredate")+"\t"+
rs.getBigDecimal("sal")+"\t"+
rs.getBigDecimal("comm")+"\t"+
rs.getInt("deptno"));
}
} 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(cnn!=null){
try {
cnn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
2) 删除
package com.mycat.web;
import com.mysql.jdbc.Driver;
import java.sql.*;
public class JdbcDemo3 {
public static void main(String[] args){
Connection cnn=null;
Statement stmt=null;
try{
//通过加载类的形式执行Driver代码块的代码,从而达到注册驱动的目的
Class.forName("com.mysql.jdbc.Driver");
//获得数据库连接
cnn = DriverManager
.getConnection("jdbc:mysql://localhost:3306/mktest?useSSL=true", "root", "miku");
//数据库
stmt=cnn.createStatement();
StringBuilder sql=new StringBuilder("delete from mktest.emp where empno=7789 ");
stmt.execute(sql.toString());
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(cnn!=null){
try {
cnn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
三.Statement的子接口PreparedStatement
1.Statement引发的SQL注入
String sql="select * from mktest.user where username='' or 1=1 or password='' ";
用户名输入:' or 1=1 and '
密码输入: 随便写
SQl注入:
原因:SQL的拼接导致规则被修改。
Statement是发送静态的SQL的(确定的)
2.PreparedStatement
好处:执行SQL前可以对SQL进行预编译(通过?作为占位符进行预编译)。
package com.mycat.web;
import java.sql.*;
public class JdbcDemo3 {
public static void main(String[] args) {
Connection cnn=null;
PreparedStatement ps = null;
ResultSet rs = null;
try{
Class.forName("com.mysql.jdbc.Driver");
cnn = DriverManager
.getConnection("jdbc:mysql://localhost:3306/mktest?useSSL=true", "root", "miku");
String sql="select * from mktest where empno=?";
ps=cnn.prepareStatement(sql);
ps.setInt(1, 7788);
rs = ps.executeQuery();
while(rs.next()){
System.out.println(rs.getInt("empno")+"\t"+rs.getString("ename")+"\t"+
rs.getString("job")+"\t"+rs.getInt("mgr")+"\t"+rs.getDate("hiredate")+"\t"+rs.getBigDecimal("sal")+"\t"+rs.getBigDecimal("comm")+"\t"+rs.getInt("deptno"));
}
} catch (ClassNotFoundException | 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(cnn!=null){
try {
cnn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}