一、JDBC简介
1.JDBC的概述
JDBC(Java Data Base Connectivity java数据库连接)是java连接数据库的一套API,它主要由接口和少量的类构成的。它是java标准库的一部分,由java.sql包和javax.sql包组成。
2.JDBC宏观理解
应用程序 JDBC API 数据库驱动 数据库 之间的关系
(1)应用程序就是我们所写的java的程序
(2)jdbc提供一些接口和少量的类 连接数据库 接口是没有方法体的那么是怎么连接数据库的呢?
(3)就是通过Driver ,这些Driver是数据库驱动,他们是对应的生产厂家所提供的。例如mysql Driver它就是数据库生产厂家所提供的。这些数据库驱动实现了这些接口,所以实现了数据库连接。
二、JDBC连接数据库
1.JDBC连接数据库基本步骤
(1)注册连接(只需要做一次即可)
(2)建立连接(Connection)
(3)创建语句(Statement)
(4)执行语句
(5)处理执行结果(ResultSet)
(6)释放资源
首先第一步就是在网上下载一个mysql的数据库驱动jar包,然后新建一个java工程 新建一个文件命名为lib 把下载的jar包(即数据库驱动)拷贝到lib下
如图
光是拷贝到这里还不够,需要将该JAR包加入到项目的build path变量中。在jar包上鼠标右键build path->addto build path ..
这样准备工作就做完了
2.编写一个简单的JDBC程序
jdbc1 是一个简单的jdbc程序 不太完善 异常直接throws了 没有处理 缺点是如果前面抛出异常,后面不执行的话就不能释放资源
jdbc2 是1 的完善 用了try catch处理异常 不管怎样都会关闭(这里需要注意关闭的三个都用finally包起来了)
直接放一个finally里面的话 万一第一个出错 后面两个就关闭不了了。(还有只要关闭了connection那两个也会关闭)
jdbc3 是较为规范的程序 将连接和关闭提取到了一个工具类中 简化了代码 方便调用
为什么要及时关闭释放资源
数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果Connection不能及时正确的关闭将导致系统宕机。Connection的使用原则是尽量晚创建,尽量早的释放。
package com.shulian.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Base {
public static void main(String[] args) throws ClassNotFoundException,SQLException {
//jdbc1();
//jdbc2();
jdbc3();
}
public static void jdbc1() throws SQLException, ClassNotFoundException {
// 注册驱动 有三种方式
// DriverManager.registerDriver(new com.mysql.jdbc.Driver());
// System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
Class.forName("com.mysql.jdbc.Driver");
// 建立连接
Connection conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/mydatabase", "root", "123456");
// 创建语句
Statement st = conn.createStatement();
// 执行sql语句
ResultSet rs = st.executeQuery("select * from my_student");
// 输出结果
while (rs.next()) {
System.out.println(rs.getObject(1) + "\t" + rs.getObject(2) + "\t"
+ rs.getObject(3) + "\t" + rs.getObject(4));
}
// 关闭连接
rs.close();
st.close();
conn.close();
}
public static void jdbc2() {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
// 一个规范的jdbc
String url = "jdbc:mysql://localhost:3306/mydatabase";
String user = "root";
String passworld = "123456";
String sql = "select * from my_student";
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = DriverManager.getConnection(url);
st = conn.createStatement();
rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getObject(1) + "\t" + rs.getObject(2)
+ "\t" + rs.getObject(3) + "\t" + rs.getObject(4));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} finally {
try {
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
public static void jdbc3() throws SQLException {
Statement st = null;
ResultSet rs = null;
Connection conn = JdbcTool.lianjie();
try {
String sql = "select * from my_student";
st = conn.createStatement();
rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getObject(1) + "\t" + rs.getObject(2)
+ "\t" + rs.getObject(3) + "\t" + rs.getObject(4));
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
JdbcTool.free(conn,st,rs);
}
}
}
jdbc3提取出来的工具类
package com.shulian.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
* 写成final的 工具类 无需被继承
* 不需要实例 将构造方法私有化 对外的话有两种方法1.使用单例 2.提供一个public方法供外界访问
*/
public final class JdbcTool {
private JdbcTool() {
}
private static String url = "jdbc:mysql://localhost:3306/mydatabase";
private static String user = "root";
private static String passworld = "123456";
static {
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e1) {
e1.printStackTrace();
}
}
public static Connection lianjie() throws SQLException {
Connection conn = DriverManager.getConnection(url,user,passworld);
return conn;
}
public static void free(Connection conn, Statement st, ResultSet rs) {
try {
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} finally {
try {
if (st != null) {
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
} finally {
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
}
3.JDBC程序小结
首先要把驱动导入到工程里面去
DriverManager 它是驱动管理工具 管理着所有的驱动
第一步 注册驱动
注册驱动有三种方式 区别
第一种DriverManager.registerDriver(new com.mysql.jdbc.Driver());
会产生两个驱动 而且他会对具体的驱动类产生依赖
对具体的驱动产生依赖就是必须要导入驱动才可以(就是jar包)下面两个不导入的话编译不会报错
为什么会产生两个驱动 原因是自己new了一个 它默认的底层的也创造了一个
第二种System.setProperty("jdbc.drivers", "com.mysql.jdbc.Driver");
可以一次性注册多个驱动 中间用冒号区分 不会产生多余的驱动 也不会对具体的驱动类产生依赖
Class.forName("com.mysql.jdbc.Driver");
第三种 class的方式注册 推荐使用这种
1. 它不会产生多余的注册驱动
2. 不会对具体的驱动类产生依赖
第二步 建立连接 涉及三个变量url user passeorld
建立连接的话 通过DriverManager的getconnection方法
他会拿着url去驱动管理器里面 挨着问驱动能不能建立连接 直到可以建立连接
如果都不能够建立连接的话就会抛出异常
第三步 创建语句
第四步 执行语句
第五步 关闭连接
4.基本CRUD增删改查操作 这个也用到了上面的工具类
package com.shulian.jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
/*
* 基本的增删改查
*/
public class CRUD {
public static void main(String[] args) {
//create();
// update();
// delete();
read();
}
public static void create(){
Connection conn = null;
Statement st = null;
String sql = "insert into my_student(id,name,age,height) values (5,'张二',33,50)";
try {
conn = JdbcTool.lianjie();
st = conn.createStatement();
int row = st.executeUpdate(sql);
System.out.println("row = "+ row);
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcTool.free(conn, st, null);
}
}
public static void delete(){
Connection conn = null;
Statement st = null;
String sql = "delete from my_student where id is null";
try {
conn = JdbcTool.lianjie();
st = conn.createStatement();
int row = st.executeUpdate(sql);
System.out.println("row = "+ row);
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcTool.free(conn, st, null);
}
}
public static void update(){
Connection conn = null;
Statement st = null;
String sql = "update my_student set age=age+10 where id=1";
try {
conn = JdbcTool.lianjie();
st = conn.createStatement();
int row = st.executeUpdate(sql);
System.out.println("row = "+ row);
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcTool.free(conn, st, null);
}
}
public static void read() {
Connection conn= null;
Statement st = null;
ResultSet rs = null;
String sql = "select id,name,age,height from my_student";
try {
conn = JdbcTool.lianjie();
st = conn.createStatement();
rs = st.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getObject(1) + "\t" + rs.getObject(2)
+ "\t" + rs.getObject(3) + "\t" + rs.getObject(4));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcTool.free(conn, st, rs);
}
}
}
小结:
增、删、改用Statement.executeUpdate来完成,返回整数(匹配的记录数),这类操作相对简单。
查询用Statement.executeQuery来完成,返回的是ResultSet对象,ResultSet中包含了查询的结果;查询相对与增、删、改要复杂一些,因为有查询结果要处理。
5.sql注入问题
package com.shulian.jdbc;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Jdbcsqlinject {
public static void main(String[] args) {
insert("'or 1 or'");
}
public static void insert(String name){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
String sql = "select * from my_student where name= '"+name+"'";
conn = JdbcTool.lianjie();
st = conn.createStatement();
rs = st.executeQuery(sql);
while(rs.next()){
System.out.println(rs.getObject(1)+"\t"+rs.getObject(2)+"\t"+rs.getObject(3)+"\t"+rs.getObject(4));
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcTool.free(conn, st, rs);
}
}
}
在SQL中包含特殊字符或SQL的关键字(如:' or 1 or ')时Statement将出现不可预料的结果(出现异常或查询的结果不正确)这样查询结果全部显示出来了