Java中的JDBC编程

前言:

本篇博客将为大家介绍Java中的JDBC编程。

目录

简介

举例


简介

  1. 数据库编程的必备条件:编程语言,数据库和数据库驱动包(如:MySQL提供了Java的驱动包mysql-connector-java,需要基于Java来操作MySQL就需要这个驱动包。同理,要基于Java操作Oracle则需要Oracle的数据库驱动包ojdbc)。
  2. JDBC:Java Database Connectivity 数据库连接,是一种用于执行SQL语句的Java的API(Application Programming Interface应用程序编程接口)。它是Java中的数据库连接规范。这个包由java.sql.*,javax.sql.*包中一系列的类和接口组成,它为Java开发人员操作数据库提供了一个标准的API,可以为多种关系数据库提供统一访问。
  3. JDBC的优势有:1)Java语言访问数据库操作完全面向抽象接口编程。2)开发数据库应用不用限定在特定的厂商的API。3)程序的可移植性大大增强。

举例

步骤:

  1. 准备数据库驱动包,添加到项目的依赖中
  2. 建立数据库连接
  3. 创建操作命令
  4. 执行SQL语句
  5. 释放资源

1)准备数据库驱动包,添加到项目中:

  • 先获取到一个驱动包

如何获取到一个驱动包呢:

Maven Repository: Search/Browse/Explore (mvnrepository.com)

进入网站以后在搜索栏搜索MySQL,然后选择适合自己MySQL的版本的驱动包(MySQL是什么版本,驱动包就选择什么版本。如MySQL是5版本,驱动包就选择5版本的;MySQL是8版本,驱动包就选择8版本的)

  • 将驱动包放进一个项目中

在IDEA中创建lib目录:把驱动包引进该目录中:将lib目录标记成库:

3)建立数据库连接:

import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
import javax.sql.DataSource;

//1.创建一个DataSource,描述数据库所在源头DataSource
DataSource dataSource = new MysqlDataSource();
((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");
((MysqlDataSource)dataSource).setUser("root");
((MysqlDataSource)dataSource).setPassword("自己数据库的密码");

//和数据库建立连接:
Connection connection = dataSource.getConnection();

注意:

  • DataSource选择javax.sql包里面的(这才是JDBC的包)
  • MysqlDataSource源自驱动包
  • 在建立连接之前我们要先在MySQL中创建一张数据库,此处将其命名为Java
  • 之所以第一步进行向上转型,后面又进行向下转型是为了让MysqlDataSource这个类名不要到处扩散,以便后续要把数据库修改成别的数据库改动不会太大。
  • URL是计算机非常重要的概念,表示网络的资源位置,俗称网址。MySQL是一个客户端服务器的程序,是通过网络来进行交互的。同时,这里光给了网络只能找到MySQL服务器,还要对其进行认证(用户+密码)。root是管理员的意思。
  • jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false
    • jdbc:mysql->描述url1的作用:给jdbc操作MySQL的
    • 127.0.0.1->IP地址。用来描述网络上一个主机的地址。127.0.0.1是环回地址(loopback)。每台电脑上的环回地址都是这个,这里写环回地址就是自己把信息发给自己的意思。顺便一提,要想查看自己主机的IP地址只需要:win+r->cmd->ipconfig即可
    • 3306:端口号,使地址更加精确,具体到哪个程序。
    • java:访问MySQL服务器里的哪一个服务器。(就是我们前面创建的那个数据库的名字)
    • utf8:utf8相当于MySQL里的增删改查那篇文章的utf8mb4。值得注意的是,这里不能写utf8mb4,utf8就相当于utf8mb4
    • useSSL=false:是否要加密。此处我们选择的是未加密,因为在运行过程中,不同的计算机中环境不一样,加密可能会导致连接不上,且数据库中并无值得被攻击的东西,故选择不加密。
    • ?:表示的是访问资源时需要哪些参数,多个参数之间的分隔符是&
  • Connection是java.sql包下的
  • getConnection可能会抛异常(执行sql或者操着数据库过程一般都会出现这个问题),解决该异常只需要throw 一下即可

3)创建操作命令:

//构造sql
String sql = "insert into student values(1,'张三')";
PreparedStatement statement = connection.prepareStatement(sql);
  • 代码中的sql是不需要写分号的
  • 此处举例举的是新增,查找,修改和删除的操作也是一样的,在构造sql的时候,只要把新增换成需要的操作即可。
  • PreparedStatement statement = connection.prepareStatement(sql);是对sql语句进行预处理:解析检查sql语句,解析完毕会得到结构化数据(原来是字符串格式),在把这些格式化数据发送个数据库服务器。通过预处理,可以帮数据库省下解析的工作。

4)执行SQL语句:

//把sql发送个服务器,执行SQL
int n = statement.executeUpdate();
  • 当sql语句是删除,修改和新增操作时,使用executeUpdate()方法(返回一个整数);是查看操作时,使用executeQuery()方法(返回一个结果集)
  • n是一个整数,表示该操作会影响到的行数

5)释放资源:

//释放资源,关闭连接:先获取的后释放
statement.close();
connection.close();
  • 程序通过代码和服务器进行通讯,会消耗一定的软/硬件资源,在程序结束的时候就需要告知服务器释放这些资源(客户端也需要释放这些资源)

完整代码:

public class Demo1 {
    public static void main(String[] args) throws SQLException {
        //1.创建一个DataSource,描述数据库所在源头DataSource
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("自己的数据库密码");

        //和数据库建立连接:
        Connection connection = dataSource.getConnection();

        //构造sql
        String sql = "insert into student values(1,'张三')";
        PreparedStatement statement = connection.prepareStatement(sql);

        //把sql发送个服务器,执行SQL
        int n = statement.executeUpdate();

        //释放资源,关闭连接:先获取的后释放
        statement.close();
        connection.close();
    }
}

运行后:


对于查询操作的完整代码:

public class Demo4 {
    public static void main(String[] args) throws SQLException {
        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("自己数据库的密码");

        Connection connection = dataSource.getConnection();

        String sql = "select * from student";//Mysql中的各种select再这里都试用
        PreparedStatement statement = connection.prepareStatement(sql);

        //查询查询出来的是一个结果集,所以不能再用executeUpdate()方法了,它返回的是一个整数
        ResultSet resultSet = statement.executeQuery();//resultSet表示的是一张临时表(结果集合)
        //查询操作就是要看其返回出来的结果集,所以这里要加一个遍历结果集的操作
        //通过next方法就可以获取到临时表中的每一行数据,如果获取到最后一行以后再往后走就会返回false
        //next的起点并不是从第一行开始的,是从第一行的前一个位置,所以要先调用next,使之拿到第一行的数据
        //类似于迭代器遍历,迭代器是hasNext(),判断是不是最后一个,不是,再来取元素,且迭代器一开始指向的是第一行的位置
        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 class Demo2 {
    public static void main(String[] args) throws SQLException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入学号:");
        int id = scanner.nextInt();
        System.out.println("请输入姓名:");
        String name = scanner.next();

        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("自己数据库的密码");

        Connection connection = dataSource.getConnection();

        String sql = "insert into student values(" +id+ ",'" +name+"')";
        PreparedStatement statement = connection.prepareStatement(sql);

        int n =statement.executeUpdate();
        System.out.println(sql);

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

运行输入2 李四:

虽然这样确实是让用户自己输入了,但是这样不安全。在这种代码下,用户有很大的空间对数据库进行别的操作且这种写法不太优雅。下面这种写法可以很好地解决这个问题:

public class Demo3 {
    public static void main(String[] args) throws SQLException {
        Scanner scanner = new Scanner(System.in);
        System.out.println("请输入学号:");
        int id = scanner.nextInt();
        System.out.println("请输入姓名:");
        String name = scanner.next();

        DataSource dataSource = new MysqlDataSource();
        ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/java?characterEncoding=utf8&useSSL=false");
        ((MysqlDataSource)dataSource).setUser("root");
        ((MysqlDataSource)dataSource).setPassword("自己数据库的密码");

        Connection connection = dataSource.getConnection();

        String sql = "insert into student values(?,?)";//使用问号做为占位符
        PreparedStatement statement = connection.prepareStatement(sql);
        statement.setInt(1,id);//1表示替换第几个问号(从1开始算),id是int类型,所以用setInt;下面的name是String类型,所以用setString,是什么类型就用set什么
        statement.setString(2,name);

        int n = statement.executeUpdate();

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

运行输入10 王五:

其他:

  • 内聚和偶合:两个代码间的联系联系紧密就是高耦合,反之就是低耦合;把相关联的代码放在一起就叫高内聚,反之就是低内聚。写代码应该追求高内聚低耦合。
  • 在这里,数据库的连接方式有两种:
    • 一种是通过DriverManager(驱动管理类)的静态方法:
      // 加载JDBC驱动程序
      Class.forName("com.mysql.jdbc.Driver");
      // 创建数据库连接
      Connection connection = DriverManager.getConnection(url);
    • 一种是通过DataSource(数据源)对象获取。实际应用中会使用这个
      DataSource ds = new MysqlDataSource();
      ((MysqlDataSource) ds).setUrl("jdbc:mysql://localhost:3306/test");
      ((MysqlDataSource) ds).setUser("root");
      ((MysqlDataSource) ds).setPassword("root");
      Connection connection = ds.getConnection();
    • 这两种方法的区别有:
      • DriverManger类来获取的Connection连接是无法重复利用的,每次使用完释放资源时,通过Connection.close()都是关闭物理连接
      • DataSource提供连接池的支持。连接池在初始化时将创建一定数量的数据库连接,这些连接是可复用的,每次使用完数据库连接,释放资源调用Connection.close()都是将Connection连接对象回收。
  • Statement对象主要是将SQL语句发送到数据库中,Java API中主要提供了三种Statement对象:
    • Statement用于执行不带参数的简单SQL语句
    • PreparedStatement用于执行带或者不带参数的SQL语句;SQL语句会预编译在数据库中;执行速度快于Statement
      • PreparedStatement归纳:
        • 性能比Statement高
        • 占位符?下标从1开始
        • 可以阻止常见的SQL注入攻击
        • SQL预编译,加快执行速度
        • 占位符不能使用多值
        • 参数化SQL查询
    • CallableStatement用于执行数据库存储过程中的调用
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值