看倦了头顶上绚丽的烟花,低头来品味下妙趣横生的JDBC编程吧

愿君一阅

    • 操作数据库
    • JDBC概述
    • JDBC使用
      • 找到数据库驱动包,添加到项目中
      • 创建数据源
      • 与数据库建立连接(网络通信)
      • 创建SQL语句
      • 执行SQL语句(网络通信)
        • 遍历这个临时表
      • 释放资源
    • 实操
      • 查询
      • 更改
        • 修改
        • 删除
        • 添加
    • 封装操作

操作数据库

编程语言:C 、C++、JAVA、Python等
数据库:MySQL、Oracle、SQL Server等
各种编程语言都能操作数据库

不同的数据库,对应不同的编程语言提供的不同的数据库驱动包(API(一组类或方法)),调用这些API就能操作数据库

JDBC概述

JDBC是Java标准库提供的API,把各种不同的数据库的接口统一起来,这组API可操作任意的数据库
看JBDC如何访问数据库
看倦了头顶上绚丽的烟花,低头来品味下妙趣横生的JDBC编程吧_第1张图片

JDBC使用

找到数据库驱动包,添加到项目中

可在官网、GitHub、中央仓库中寻找第三方库
中央仓库
看倦了头顶上绚丽的烟花,低头来品味下妙趣横生的JDBC编程吧_第2张图片

  • 找到驱动包,根据MySQL的版本下载相应的版本(子版本之间差别很小,如5.7版本的MySQL可以下载5.1或5.0任一版本驱动包)
  • 下载mysql-connector-java-5.1.49.jar 。文件后缀名是.jar的是jar包,Java程序打包部署的一种常见格式,本质上是把.class文件以压缩包的形式打包在一起,绝大部分第三方库都是通过jar包的形式发布的
    看倦了头顶上绚丽的烟花,低头来品味下妙趣横生的JDBC编程吧_第3张图片
  • 在项目中创建文件夹lib,将驱动包mysql-connector-java-5.1.49.jar复制到lib文件夹中

看倦了头顶上绚丽的烟花,低头来品味下妙趣横生的JDBC编程吧_第4张图片

  • 右击lib目录,点击Add as Library,点击ok
    看倦了头顶上绚丽的烟花,低头来品味下妙趣横生的JDBC编程吧_第5张图片

创建数据源

创建数据库源,把数据库的位置信息写入
IP地址、端口号(可通过workbench查找)、数据库名通过一个URL语句写入
URL语句的格式是固定的 "jdbc:mysql://IP地址:端口号/数据库名"
还要写入用户名、密码等
characterEncoding说明字符编码,useSSL说明是否加密

        //1.创建一个 数据源
        DataSource dataSource = new MysqlDataSource();
        // 1)数据库的ip,端口,数据库名通过一个URL来表示,需要调用setUrl()实现,setUrl()是MysqlDataSource的方法
        ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
        // 2)设置登录数据库的用户名
        ((MysqlDataSource) dataSource).setUser("root");
        //MySQL支持自己创建用户,安装好MySQL数据库,就有一个用户,“root”,即管理员,拥有最高的权限
        // 3)设置登录数据库的密码
        ((MysqlDataSource) dataSource).setPassword("cuige2001");

不使用转型的写法

MysqlDataSource dataSource = new MysqlDataSource();

使用转型写法的好处:
DataSource 是Java标准库提供的API,是通用的,支持各种数据库;MysqlDataSource是数据库JDBC驱动程序提供的API,专门针对MySQL数据库;
转型写法中,数据源dataSource都是DataSource类型,和具体的数据库无关,如果以后切换数据库,只要改动MysqlDataSource,其他代码无需改动!!

与数据库建立连接(网络通信)

Connection connection = dataSource.getConnection();
//连接失败时会抛出异常(受查异常),导致连接失败的原因很多 ip地址、端口号、用户名、密码错误、数据库权限受阻等等

容易抛出异常SQLException,要么用try catch()包裹,要么抛给上层调用者
Connection在标准库中有,在MySQL驱动中也有,此处使用的是标准库中的Connection(java.sql.Connection)

创建SQL语句

Scanner scanner = new Scanner(System.in);
System.out.println("请输入id:");
int id = scanner.nextInt();
System.out.println("请输入城市:");
String name = scanner.next();

//静态拼接
String sql = "insert into shandong values(1,'济南')";
//动态拼接
String sql = "insert into shandong values("+ id + ",'"+ name + "')";
String sql = "insert into shandong values(?,?)";

PreparedStatement statement = connection.prepareStatement(sql);
statement.setInt(1, id);
statement.setString(2, name);

动态拼接应该用第三种方法,?表示占位符,如果sql语句中有?,一定要记得后面用setXXX()方法填充
PreparedStatement使用的是标准库中的API
setInt() 或 setString() 对输入的内容有严格的校验,有疑似SQL语句的内容就能识别出来;使用前两种,如果是 sql 中有类似于drop database XXX的信息,数据库执行就完犊子了

Statement和PreparedStatement的区别:

  • Statement 用于执行不带参数(没有?占位符)的简单SQL语句(Statement的没有setXXX方法)
  • PreparedStatement 用于执行带或不带参数的简单SQL语句,SQL语句会预编译在数据库系统,执行速度快于Statement对象

执行SQL语句(网络通信)

int ret = statement.executeUpdate();

ResultSet resultset = statement.executeQuery();

executeUpdate()表示数据发生变更,包括insert,update,delete等,返回的值是影响的行数
executeQuery()表示查询,返回的是一个结果集(相当于一个临时表)

遍历这个临时表

while(resultset.next()){
    int id = resultset.getInt("id");
    String name = resultset.getString("name");
    System.out.println("id: " + id + ", name: " + name);
}

释放资源

关闭结果集,命令,连接
先开后闭,关闭的顺序与申请的顺序相反
客户端和服务器之间都会分配一部分资源来维系这个连接(记录对端的ip,port),每维持一个连接,都会消耗一部分硬件资源

resultSet.close();
statement.close();
connection.close();

实操

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

查询

public static void testSelect() throws SQLException {
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("cuige2001");

        Connection connection = dataSource.getConnection();

        String sql = "select * from shandong";
        PreparedStatement statement = connection.prepareStatement(sql);

        //resultset就相当于一张临时表,在有些语言/库中ResultSet也叫光标(cursor) 如Python中
        ResultSet resultset = statement.executeQuery();

        while(resultset.next()){
            int id = resultset.getInt("id");
            String name = resultset.getString("name");
            System.out.println("id: " + id + ", name: " + name);
        }

        resultset.close();
        statement.close();
        connection.close();
    }

更改

修改

public static void testUpdate() throws SQLException {
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("cuige2001");

        Connection connection = dataSource.getConnection();

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入修改的名称");
        String name = scanner.next();
        System.out.println("请输入id");
        int id = scanner.nextInt();

        String sql = "Update shandong set name = ? where id = ?";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setInt(2,id);
        statement.setString(1,name);

        int ret = statement.executeUpdate();
        System.out.println(ret);

        statement.close();
        connection.close();
    }

删除

public static void testDelete() throws SQLException {
        //1.创建数据源,把数据库的位置信息设置进去
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("cuige2001");
        //2.与数据库建立连接
        Connection connection = dataSource.getConnection();
        //3.构造SQL语句
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入需要删除城市的id");
        int id = scanner.nextInt();
        String sql = "delete from shandong where id = ?";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setInt(1,id);
        //4.执行SQL语句
        int ret = statement.executeUpdate();
        System.out.println(ret);
        //5.回收资源
        statement.close();
        connection.close();
    }

添加

public static void testInsert() throws SQLException {
        //1.创建一个 数据源
        DataSource dataSource = new MysqlDataSource();       
        ((MysqlDataSource) dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java100?characterEncoding=utf8&useSSL=false"); 
        ((MysqlDataSource) dataSource).setUser("root");      
        ((MysqlDataSource) dataSource).setPassword("cuige2001");

        //2.连接数据库,进行网络通信
        Connection connection = dataSource.getConnection();

        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入id:");
        int id = scanner.nextInt();
        System.out.println("请输入城市:");
        String name = scanner.next();

        //3.创建SQL语句,插入数据
        String sql = "insert into shandong values(?,?)";
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setInt(1, id);
        statement.setString(2, name);

        //4.执行SQL语句,进行网络通信
        int ret = statement.executeUpdate();
        System.out.println(ret);

        //5.关闭连接,回收一部分资源
        statement.close();
        connection.close();
    }

封装操作

实际操作中可以通过封装实现与数据库的网络通信

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;


public class DBUtil {
    private static String url = "jdbc:mysql://127.0.0.1:3306/bookmanage?characterEncoding=utf8&useSSL=false";
    private static String user = "root";
    private static String password = "cuige2001";

    //一个程序中只要有一个连接即可,有一个DataSource实例即可!
    //保证 某个类在程序中只有 “唯一的实例”(可以有多种不同的实例,每种实例只有一个啊),叫做"单例模式",也是一种设计模式
    private static DataSource dataSource = new MysqlDataSource();

    //静态代码块,"类加载"的时候执行
    static{
        ((MysqlDataSource)dataSource).setUrl(url);
        ((MysqlDataSource)dataSource).setUser(user);
        ((MysqlDataSource)dataSource).setPassword(password);
    }

    //建立连接
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();
    }

    public static void close(Connection connection, Statement statement, ResultSet resultSet) {

// TODO 用一层 try catch() 包裹是不行的 !!! 如果 resultSet发生异常的话,statement和connection的资源不会回收哦
//        try{
//            if(resultSet != null){
//                resultSet.close();
//            }
//            if(statement != null){
//                statement.close();
//            }
//            if(connection != null){
//                connection.close();
//            }
//        }catch(SQLException e){
//            e.printStackTrace();
//        }


        if(resultSet != null){
            try {
                resultSet.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(statement != null){
            try {
                statement.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection != null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

看倦了头顶上绚丽的烟花,低头来品味下妙趣横生的JDBC编程吧_第6张图片

你可能感兴趣的:(MySQL,数据库,java,mysql,jdbc)