• JDBC操作数据库实现增、删、查、改


    0.JDBC概念

    实际开发中,手动的输入SQL语句是少之又少,大多数情况下是通过编译代码进行来控制自动执行.

    具体操作如下:

    在这里插入图片描述

    上述展示有一个【自己写的Mysql客户端】,这种操作是非常容易的,因为各种数据库本身就提供一系列的API,可以让用户很方便的实现这个客户端。**显然MySQl提供的有API(Application Programming Interface )Java也提供了一些API 这些API 提供了一些类和方法,通过这些类和方法可以进行一系列操作,比如操作硬盘的文件,进行增删查改,操作数据库等 **。不同的数据库提供的API是不相同的,于是由于不同的数据库有不同的API,一旦使用不同的数据库就需要重新学习API。这时候就有Java大佬出了一个JDBC这一套API来适配不同的数据库,不同数据库就需要提供能适应JDBC相关的“驱动包”。这也就表示JDBC规范了所有数据库的编程操作。

    JDBC: 约定了有哪些API,具体怎么用。

    驱动包: API的具体实现。

    1. 数据库连接 Connection

    • 通过DriverManager(驱动管理类)的静态方式获取
    //加载jdbc驱动程序
    Class.forName("com.mysql.jdbc.Driver");
    //创建数据库连接
    Connection connection1 = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/Class?characterEncoding=utf8&useSSL=false")
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 通过DataSource(数据源)对象获取.实际开发中会使用DataSource对象
     DataSource dataSource = new MysqlDataSource();
            ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/Class?characterEncoding=utf8&useSSL=false");
    ((MysqlDataSource)dataSource).setUser("root");
    ((MysqlDataSource)dataSource).setPassword("123456");
    
    • 1
    • 2
    • 3
    • 4
    • 以上两种方式的区别是:
      1. DriverManager类来获取的Connection连接,是无法重复利用的,每次使用完以后释放资源时,通过connection.close()都是关闭物理连接。
      2. DataSource提供连接池的支持。连接池在初始化时将创建一定数量的数据库连接,这些连接是可以复用的,每次使用完数据库连接,释放资源调用connection.close()都是将Conncetion连接对象回收。

    2.Statement 对象

    statement对象主要将SQL语句发送到数据库中,JDBC API中主要提供了三种Statement对象.

    1. statement : 用于执行不带参数的简单sql语句

    2. PrepareStatement:

      a)用于执行带参或者不带参数的sql语句.

      b)SQL语句会预编译在数据库系统.

      c)执行速度快于Statement对象.

    3. CallableStatement:用于执行数据库存储过程的调用.

    强调PrepareStatement:

    1.可以参数化SQL查询.

    2.性能比Statement高.

    3.预编译SQL.

    4.阻止常见的SQL注入攻击.(黑客…)

    5.占位符:?(下标从1开始)

    6.占位符不能使用多值.

    7.主要掌握两种执行SQL方法:

    a).executeQuery()方法执行后返回单个结果集,通常用于select语句.

    b).executeUpdate()方法返回值是一个整数,表示受影响的行数,通常用于update,insert,delete,语句.

    3.ResultSet对象

    ResultSet对象它被称为结果集,它代表符合SQL语句条件的所有行,并且它通过一套getXXX()方法提供了对这些行中数据的访问.

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

    4.使用JDBC操作MySQL

    【idea导入MySQL驱动包教程】

    咱先来看看JDBC是如何操作的:(抽象画家)

    通过JDBC使用不同的数据库,JDBC会调用相对应的数据库的“驱动包”,来和数据库的服务器进行交互。

    在这里插入图片描述

    4.1 插入-删除-修改

    1. 创建数据库源

    在使用之前,需要提前准备好数据库和数据表

    打开Mysql客户端,创建一个Class数据库,创建一个student表,字段:id,姓名.

    
    import com.mysql.jdbc.jdbc2.optional.MysqlDataSource;
    import javax.sql.DataSource;
    //1.创建数据源..javax.sql底下的DataSource
    
    DataSource dataSource = new MysqlDataSource();//向上转型,这样避免后期换服务器需要到处修改代码
    
    //2.说明数据库服务器在哪里,向下转型
    ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/Class?characterEncoding=utf8&useSSL=false");
    //3.设置用户名和密码  我默认的是“root”  密码是“123456”
    ((MysqlDataSource)dataSource).setUser("root");
    ((MysqlDataSource)dataSource).setPassword("123456");
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • DataSource内置了数据量连接池,可以重复利用.
    • MysqlDataSource();这是驱动包,里面提供了具体的类。
    • setUrl()里写的内容,直接复制粘贴就行,除了class要换成你自己需要连接的数据库名。url是给JDBC中的mysql使用的。
    • 你的数据库用户名是什么就写什么,自己设置的密码是什么就写什么。

    在这里插入图片描述

    1. 建立数据库连接
    //建立连接
    import java.sql.Connection;
    Connection connection = dataSource.getConnection();
    
    • 1
    • 2
    • 3
    • Connection :选择java.sql.Connection包。

    • getConnection():需要处理受查异常。

      a)受查异常:必须要显示处理;

      b)非受查异常:可以忽略

    1. 构造SQL语句-插入数据
    //1.构造语句
    //写法1
    String sql = "insert into student values(1,‘张三’)";
    //2.在JDBC中需要搭配一个特定的对象,来描述sql的情况
    PreparedStatement preparedStatement = connection.prepareStatement(sql);
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 使用占位符替换:实现动态sql语句构造
    
    //写法2:
     Scanner scanner = new Scanner(System.in);
    int id = scanner.nextInt();//输入学号  -> 1
    String name = scanner.nextLine();//输入姓名 ->"李四"
     String sql = "insert into student values(?,?)";//注释1
     PreparedStatement preparedStatement = connection.prepareStatement(sql);
     preparedStatement.setInt(1,id);//注释2
     preparedStatement.setString(2,name);//注释3
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 注意:name输入"李四",如果报错,大概率是字符集不是utf8
    • 注释1处:(?,?),问号表示通配符(占位符),可以自己输入[输入的字段,类型要配对]
    • 注释2处:设置从左开始数,第一个问号,下标为1,使用setInt()把id设置为1.
    • 注释2处:设置第二个问号,下标为2,使用setString()把名字设置为"李四";
    • sql语句是先构造,再执行的,不管是否使用了通配符(占位符).
    1. 执行SQL语句
     int ret = preparedStatement.executeUpdate();
    
    • 1
    • executeUpdate();返回结果是:操作在数据库表里影响了几行.
    • 针对增,删,改,使用executeUpdate();针对使用executeQuery().这些操作跟插入操作的代码几乎相同,修改sql语句,再修改preparedStatement调用的方法就可以了
    • executeQuery()返回的是一个查询的结果集,用ResultSet
    1. 断开连接,释放资源
    preparedStatement.close();
    connection.close();
    
    • 1
    • 2
    • 注意: 释放资源是从后往前释放.

    • 最后创建的preparedStatement,就最先释放.

    • 最先创建的connection,最后释放.

    • 完整版insert代码

        public static void main(String[] args) throws SQLException {
            //1.创建数据源
            DataSource dataSource = new MysqlDataSource();
            ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/Class?characterEncoding=utf8&useSSL=false");
            ((MysqlDataSource)dataSource).setUser("root");
            ((MysqlDataSource)dataSource).setPassword("123456");
            //2.手动输入id name
            Scanner scanner = new Scanner(System.in);
            int id = scanner.nextInt();
            String name = scanner.nextLine();
            //3.连接
            Connection connection = dataSource.getConnection();
            //4.构造
            String sql = " insert into student values (?,?)";
            //5.执行
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
            preparedStatement.setInt(1,id);//id
            preparedStatement.setString(2,name);//name
           
            System.out.println("sql:"+preparedStatement);//返回一个修改执行后的sql语句
            //执行
            int ret = preparedStatement.executeUpdate();
            //关闭资源
            preparedStatement.close();
            connection.close();;
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    4.2 查找

    public class Demo1 {
        public static void main(String[] args) throws SQLException {
            //1.先创建数据源
            DataSource dataSource = new MysqlDataSource();
            ((MysqlDataSource)dataSource).setUrl("jdbc:mysql://127.0.0.1:3306/Class?characterEncoding=utf8&useSSL=false");
            ((MysqlDataSource)dataSource).setUser("root");
            ((MysqlDataSource)dataSource).setPassword("123456");
    
            //2.连接数据库
            Connection connection = dataSource.getConnection();
    
            //3.构造sql
            String sql = "select * from student";
    		//可以其他加入限制条件
    		//String sql = "select * from student where id = 1";
    		
            //4.执行sql
            PreparedStatement preparedStatement = connection.prepareStatement(sql);
    
            //5.注意 这里返回的是一个结果结合
            //注意这次调用的是executeQuery()
            ResultSet resultSet = preparedStatement.executeQuery();
    
            //6.循环遍历每一行记录
            //next(): 只要存在下一行就取出当前一行
            while(resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                
                System.out.println("id = "+ " name");
            }
     		resultSet.close();
            preparedStatement.close();
            connection.close();
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 查询调用的是executeQuery(),返回的是一个结果集,用 ResultSet对象接收.
    • resultSet.next(): 取出当前一行数据;如果指向了结尾,则返回false;
    • 使用getXX方法获得具体列;
    • 方法里的参数就是数据表里的列名,注意如果你在查询时,取了别名,这里也要用别名
    • 可以写多条sql语句,但是每条语句执行,都要重新创建一个PreparedStatement对象,进行执行.
    • 在这写的sql语句,和数据库里的语句是相同的,比如加入限制条件where order by…
  • 相关阅读:
    基于SSM的亲子活动平台的搭建与实现(源码+数据脚本+论文+技术文档)
    Python科学计算与可视化 C1
    搜维尔科技: 使用 Xsens 和 HTC Vive进行电影制作案例
    09-MySQL主从复制
    网络安全(黑客)自学
    云计算学习7——云计算OpenStack运维基础
    Java 本地内存 & 直接内存 & 元空间
    【目标检测】YOLOv5遇上知识蒸馏
    黄仁勋口述:英伟达的发展之道和星辰大海
    XAPP585框架详解-LVDS时钟恢复逻辑
  • 原文地址:https://blog.csdn.net/Original0/article/details/128069628