Java零基础教学文档第三篇:JDBC

今日新篇章
【JDBC】
【主要内容】

  1. JDBC概述

  2. 使用JDBC完成添加操作

  3. 使用JDBC完成更新和删除

  4. DBUtils的简单封装

  5. 使用JDBC完成查询

  6. 使用JDBC完成分页查询

  7. 常用接口详解

  8. JDBC批处理

  9. SQL注入问题

  10. 事务处理解决转账问题

  11. 连接池

  12. 使用反射对DBUtils再次的封装

  13. BaseDAO的封装

【学习目标】

1. JDBC概述

1.1 什么是JDBC

JDBC(Java DataBase Connectivity)就是Java数据库连接,说白了就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。

1.2 JDBC的原理

早期SUN公司的天才们想编写一套可以连接天下所有数据库的API,但是当他们刚刚开始时就发现这是不可完成的任务,因为各个厂商的数据库服务器差异太大了。后来SUN开始与数据库厂商们讨论,最终得出的结论是,由SUN提供一套访问数据库的规范(就是一组接口),并提供连接数据库的协议标准,然后各个数据库厂商会遵循SUN的规范提供一套访问自己公司的数据库服务器的API出现。SUN提供的规范命名为JDBC,而各个厂商提供的,遵循了JDBC规范的,可以访问自己数据库的API被称之为驱动!

JDBC是接口,而JDBC驱动才是接口的实现,没有驱动无法完成数据库连接!每个数据库厂商都有自己的驱动,用来连接自己公司的数据库。

当然还有第三方公司专门为某一数据库提供驱动,这样的驱动往往不是开源免费的!

1.3 程序员,JDBC,JDBC驱动的关系及说明

1.3.1 JDBC API

提供者:Sun公司

内容:供程序员调用的接口与类,集成在java.sql和javax.sql包中,如

DriverManager类 作用:管理各种不同的JDBC驱动

Connection接口

Statement接口

ResultSet接口

1.3.2 JDBC 驱动

提供者:数据库厂商

作用:负责连接各种不同的数据库

1.3.3 Java程序员

JDBC对Java程序员而言是API,对实现与数据库连接的服务提供商而言是接口模型。

1.3.4 三方关系

SUN公司是规范制定者,制定了规范JDBC(连接数据库规范)

数据库厂商微软、甲骨文等分别提供实现JDBC接口的驱动jar包

程序员学习JDBC规范来应用这些jar包里的类。

1.4 总结

简单地说,JDBC 可做三件事:与数据库建立连接、发送 操作数据库的语句并处理结果。

DriverManager :依据数据库的不同,管理JDBC驱动

Connection :负责连接数据库并担任传送数据的任务

Statement :由 Connection 产生、负责发送执行SQL语句

ResultSet:负责保存Statement执行后所产生的查询结果

2. JDBC操作数据库的步骤

2.1 总体步骤

  1. 加载一个Driver驱动

  2. 创建数据库连接(Connection)

  3. 创建SQL命令发送器Statement

  4. 创建SQL

  5. 通过Statement发送SQL命令并得到结果

  6. 处理SQL结果(select语句)

  7. 关闭数据库资源

ResultSet

Statement

Connection

2.2 详细步骤

2.2.1 加载驱动

加载JDBC驱动是通过调用方法java.lang.Class.forName(),下面列出常用的几种数据库驱动程序加载语句的形式 :

Class.forName("oracle.JDBC.driver.OracleDriver");//使用Oracle的JDBC驱动程序

Class.forName("com.microsoft.JDBC.sqlserver.SQLServerDriver");//使用SQL Server的JDBC驱动程序

Class.forName("com.ibm.db2.JDBC.app.DB2Driver");//使用DB2的JDBC驱动程序

Class.forName("com.mysql.jdbc.Driver");//使用MySql的JDBC驱动程序

2.2.2 创建数据库连接

与数据库建立连接的方法是调用DriverManager.getConnection(String url, String user, String password )方法

Connection conn=null;

String url="jdbc:mysql://localhost:3306/whpowernode?useUnicode=true&useSSL=false&charsetUnicode=UTF8";

String user="root";

String password="123456";

conn = DriverManager.getConnection(url, user, password);

2.2.3 创建Statement并发送命令

Statement对象用于将 SQL 语句发送到数据库中,或者理解为执行sql语句

有三种 Statement对象:

Statement:用于执行不带参数的简单SQL语句;

PreparedStatement(从 Statement 继承):用于执行带或不带参数的预编译SQL语句;

CallableStatement(从PreparedStatement 继承):用于执行数据库存储过程的调用。

2.2.4 处理ResultSet结果

ResultSet对象是executeQuery()方法的返回值,它被称为结果集,它代表符合SQL语句条件的所有行,并且它通过一套getXXX方法(这些get方法可以访问当前行中的不同列)提供了对这些行中数据的访问。

ResultSet里的数据一行一行排列,每行有多个字段,且有一个记录指针,指针所指的数据行叫做当前数据行,我们只能来操作当前的数据行。我们如果想要取得某一条记录,就要使用ResultSet的next()方法 ,如果我们想要得到ResultSet里的所有记录,就应该使用while循环。

ResultSet对象自动维护指向当前数据行的游标。每调用一次next()方法,游标向下移动一行。

初始状态下记录指针指向第一条记录的前面,通过next()方法指向第一条记录。循环完毕后指向最后一条记录的后面。

2.2.5 关闭数据库资源

作为一种好的编程风格,应在不需要Statement对象和Connection对象时显式地关闭它们。关闭Statement对象和Connection对象的语法形式为:

public void close() throws SQLException

用户不必关闭ResultSet。当它的 Statement 关闭、重新执行或用于从多结果序列中获取下一个结果时,该ResultSet将被自动关闭。

注意:要按先ResultSet结果集,后Statement,最后Connection的顺序关闭资源,因为Statement和ResultSet是需要连接是才可以使用的,所以在使用结束之后有可能其他的Statement还需要连接,所以不能先关闭Connection。

3. 准备工作

3.1 创建数据并创建student表

3.2 创建项目

3.3 创建lib目录并引入MYSQL驱动包

3.4 把lib包引入项目环境

4. 使用JDBC完成添加操作

4.1 步骤

Ø 加载MySQL的JDBC驱动

Ø 建立数据的连接

Ø 创建SQL命令的发送器

Ø 编写SQL

Ø 使用SQL命令发送器发送SQL命令并得到结果

Ø 处理结果

Ø 关闭数据库资源

4.2 代码

package com.bjpowernode.jdbc;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

public class Test01Add {

// 驱动器路径

private static final String DRIVER = "com.mysql.jdbc.Driver";

//连接数据库地址

private static final String URL = "jdbc:mysql://localhost:3306/whpowernode?useUnicode=true&useSSL=false&characterEncoding=UTF8";

//数据库用户名

private static final String USER_NAME = "root";

//数据库密码

private static final String USER_PASSWORD = "123456";

public static void main(String[] args) throws ClassNotFoundException, SQLException {

// 加载JDBC访问Oracle的驱动

Class.forName(DRIVER);

// 建立和数据库的连接

Connection conn = DriverManager.getConnection(URL, USER_NAME, USER_PASSWORD);

// 创建SQL命令发送器

Statement stmt = conn.createStatement();

// 使用SQL命令发送器发送SQL命令并得到结果

String sql = "insert into student values(1,'小刚',32,'男','湖北省武汉市')";

int n = stmt.executeUpdate(sql);

// 处理结果

if (n > 0) {

System.out.println("添加成功");

} else {

System.out.println("添加失败");

}

// 关闭数据库资源

stmt.close();

conn.close();

}

}

4.3 URL详解

4.3.1 为什么要定义URL

Java和MySQL是厂商的,Java程序和MySQL数据库此时不在同一个进程下,此时Java程序需要向MySQL发送请求。

4.3.2 如何发送请求呢?

jdbc:mysql://localhost:3306/whpowernode?useUnicode=true&useSSL=false&characterEncoding=UTF-8

使用URL的方式发送

jdbc 主协议

mysql 子协议

localhost MySQL服务器的地址,如果服务器就是我自己的主机,那么定义localhost就可以了

3306 MySQL服务器的端口号

whpowernode MySQL数据库服务器的数据库名称

useUnicode=true Java和MySQL交互使用Unicode编码

useSSL=false Java和MySQL交互不使用安全层协议

characterEncoding=UTF-8 Java和MySQL交互的编码方式为UTF-8 【如果不设置会有乱码的】

4.4 查看数据库

4.4.1 一个URL由哪些部分组成

Ø 协议://服务器主机:端口/服务器路径?查询参数

Ø 协议 jdbc:mysql:

Ø 服务器主机 localhost

Ø 端口 3306

Ø 服务器路径 whpowernode

Ø 参数useUnicode=true&useSSL=false&characterEncoding=UTF8

5. 使用JDBC完成更新和删除

5.1 步骤

Ø 加载MySQL的JDBC驱动

Ø 建立数据的连接

Ø 创建SQL命令的发送器

Ø 编写SQL

Ø 使用SQL命令发送器发送SQL命令并得到结果

Ø 处理结果

Ø 关闭数据库资源

5.2 修改代码

package com.bjpowernode.jdbc;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

public class Test02Update {

// 驱动器路径

private static final String DRIVER = "com.mysql.jdbc.Driver";

//连接数据库地址

private static final String URL = "jdbc:mysql://localhost:3306/whpowernode?useUnicode=true&useSSL=false&characterEncoding=UTF8";

//数据库用户名

private static final String USER_NAME = "root";

//数据库密码

private static final String USER_PASSWORD = "123456";

public static void main(String[] args) throws ClassNotFoundException, SQLException {

// 加载Oracle的JDBC驱动

Class.forName(DRIVER);

// 建立数据的连接

Connection conn=DriverManager.getConnection(URL, USER_NAME, USER_PASSWORD);

// 创建SQL命令的发送器

Statement stat=conn.createStatement();

// 编写SQL

String sql="update student set name='小明',age=23,sex='女',address='武汉' where id=1";

// 使用SQL命令发送器发送SQL命令并得到结果

int res=stat.executeUpdate(sql);

// 处理结果

if(res>0){

System.out.println("修改成功");

}

else{

System.out.println("处理失败");

}

// 关闭数据库资源

stat.close();

conn.close();

}

}

5.3 删除代码

package com.bjpowernode.jdbc;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

public class Test03Delete {

// 驱动器路径

private static final String DRIVER = "com.mysql.jdbc.Driver";

//连接数据库地址

private static final String URL = "jdbc:mysql://localhost:3306/whpowernode?useUnicode=true&useSSL=false&characterEncoding=UTF8";

//数据库用户名

private static final String USER_NAME = "root";

//数据库密码

private static final String USER_PASSWORD = "123456";

public static void main(String[] args) throws ClassNotFoundException, SQLException {

// 加载Oracle的JDBC驱动

Class.forName(DRIVER);

// 建立数据的连接

Connection conn=DriverManager.getConnection(URL, USER_NAME, USER_PASSWORD);

// 创建SQL命令的发送器

Statement stat=conn.createStatement();

// 编写SQL

String sql="delete from student where id=1";

// 使用SQL命令发送器发送SQL命令并得到结果

int res=stat.executeUpdate(sql);

// 处理结果

if(res>0){

System.out.println("删除成功");

}

else{

System.out.println("删除失败");

}

// 关闭数据库资源

stat.close();

conn.close();

}

}

6. DBUtils的简单封装

6.1 为什么要封装

从我们上面的代码大家可以看到,每一次写我们创建一个连接,创建一个发送SQL的对象,最后还要关闭,那么我们可以考虑把这重复的代码提取出来!

6.2 创建DBUtils封装代码

package com.bjpowernode.utils;

import java.io.Closeable;

import java.io.IOException;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

public class DBUtils {

// 驱动器路径

private static final String DRIVER = "com.mysql.jdbc.Driver";

// 连接数据库地址

private static final String URL = "jdbc:mysql://localhost:3306/whpowernode?useUnicode=true&useSSL=false&characterEncoding=UTF8";

// 数据库用户名

private static final String USER_NAME = "root";

// 数据库密码

private static final String USER_PASSWORD = "123456";

/**
 * 静态加载驱动程序
 */
static {
    try {
        Class.forName(DRIVER);
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    }
}
/**
 * @return 连接对象
 */
public static Connection getConn() {
    try {
        return  DriverManager.getConnection(URL, USER_NAME, USER_PASSWORD);
    } catch (SQLException e) {
        e.printStackTrace();
        System.out.println("创建连接对象异常");
    }
    return null;
}

/**
 * 关闭资源
 */
public static void close(AutoCloseable closeable) {
    try {
        if (closeable != null) {
            closeable.close();
        }
    } catch (Exception e) {
        e.printStackTrace();
    }
}

}

6.3 创建上面的工具类对象前面的代码进行改造

package com.bjpowernode.jdbc;

import com.bjpowernode.utils.DBUtils;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

public class Test01Add {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

Connection conn = DBUtils.getConn();

// 创建SQL命令发送器

Statement stmt = conn.createStatement();

// 使用SQL命令发送器发送SQL命令并得到结果

String sql = "insert into student values(1,'小刚',32,'男','湖北省武汉市')";

int n = stmt.executeUpdate(sql);

// 处理结果

if (n > 0) {

System.out.println("添加成功");

} else {

System.out.println("添加失败");

}

// 关闭数据库资源

DBUtils.close(stmt);

DBUtils.close(conn);

}

}

7. 使用JDBC完成查询

7.1 循环向student表里面插入20条数

package com.bjpowernode.jdbc;

import com.bjpowernode.utils.DBUtils;

import java.sql.Connection;

import java.sql.SQLException;

import java.sql.Statement;

import java.util.Random;

public class Test01Add20 {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

Connection conn = DBUtils.getConn();

// 创建SQL命令发送器

Statement stmt = conn.createStatement();

// 使用SQL命令发送器发送SQL命令并得到结果

Random random=new Random();

for (int i = 1; i <=20 ; i++) {

Integer id=i;

String name="小明"+i;

int age=random.nextInt(100);

String sex=random.nextBoolean()?"男":"女";

String address="武汉"+i;

        String sql = "insert into student values("+i+",'"+name+"',"+age+",'"+sex+"','"+address+"')";
        int n = stmt.executeUpdate(sql);
        // 处理结果
        if (n > 0) {
            System.out.println("添加成功");
        } else {
            System.out.println("添加失败");
        }
    }
    // 关闭数据库资源
    DBUtils.close(stmt);
    DBUtils.close(conn);
}

}

7.2 查询

package com.bjpowernode.jdbc;

import com.bjpowernode.utils.DBUtils;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class Test04Query {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

Connection conn = DBUtils.getConn();

// 创建SQL命令发送器

Statement stmt = conn.createStatement();

// 编写SQL

String sql="select * from student";

// 使用SQL命令发送器发送SQL命令并得到结果

ResultSet rs=stmt.executeQuery(sql);

// 处理结果

while(rs.next()){

int id=rs.getInt(1);

String name=rs.getString(2);

int age=rs.getInt(3);

String sex=rs.getString(4);

String address=rs.getString(5);

System.out.println(id+" "+name+" "+age+" "+sex+" "+address);

}

// 关闭数据库资源

DBUtils.close(rs);

DBUtils.close(stmt);

DBUtils.close(conn);

}

}

8. 使用JDBC完成分页查询

package com.bjpowernode.jdbc;

import com.bjpowernode.utils.DBUtils;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

public class Test05QueryForPage {

public static void main(String[] args) throws ClassNotFoundException, SQLException {

Connection conn = DBUtils.getConn();

// 创建SQL命令发送器

Statement stmt = conn.createStatement();

int pageNum=2; //页码

int pageSize=5;//每页显示的条数

// 编写SQL

String sql="select * from student limit "+(pageNum-1)*pageSize+","+pageSize;

// 使用SQL命令发送器发送SQL命令并得到结果

ResultSet rs=stmt.executeQuery(sql);

// 处理结果

while(rs.next()){

int id=rs.getInt(1);

String name=rs.getString(2);

int age=rs.getInt(3);

String sex=rs.getString(4);

String address=rs.getString(5);

System.out.println(id+" "+name+" "+age+" "+sex+" "+address);

}

// 关闭数据库资源

DBUtils.close(rs);

DBUtils.close(stmt);

DBUtils.close(conn);

}

}

相关推荐
cdut_suye3 分钟前
Linux工具使用指南:从apt管理、gcc编译到makefile构建与gdb调试
java·linux·运维·服务器·c++·人工智能·python
苹果醋315 分钟前
2020重新出发,MySql基础,MySql表数据操作
java·运维·spring boot·mysql·nginx
小蜗牛慢慢爬行17 分钟前
如何在 Spring Boot 微服务中设置和管理多个数据库
java·数据库·spring boot·后端·微服务·架构·hibernate
azhou的代码园20 分钟前
基于JAVA+SpringBoot+Vue的制造装备物联及生产管理ERP系统
java·spring boot·制造
hanbarger20 分钟前
nosql,Redis,minio,elasticsearch
数据库·redis·nosql
波音彬要多做28 分钟前
41 stack类与queue类
开发语言·数据结构·c++·学习·算法
Swift社区36 分钟前
Excel 列名称转换问题 Swift 解答
开发语言·excel·swift
一道微光40 分钟前
Mac的M2芯片运行lightgbm报错,其他python包可用,x86_x64架构运行
开发语言·python·macos
微服务 spring cloud42 分钟前
配置PostgreSQL用于集成测试的步骤
数据库·postgresql·集成测试