Java学习日志(三十二): 原生JDBC,使用Java程序操作数据库

JavaEE学习日志持续更新----> 必看!JavaEE学习路线(文章总汇)

JDBC

JDBC的概念和原理

在这里插入图片描述

JDBC使用步骤

JDBC:使用java程序执行sql语句,对数据库表进行增删改查(CURD)
使用步骤:固定

  1. 注册驱动,告之JVM我们使用的是哪种数据库驱动程序(mysql,oracle…)

  2. 获取数据库连接对象Connection

       java程序:TCP客户端  数据库:TCP服务器
       使用客户端访问服务器,和服务器经过3次握手建立一个连接通路
       这个连接通路中有一个IO流对象,用于客户端和服务器交互数据
    
  3. 获取执行者对象Statement,用于执行sql语句,把sql语句发送到数据库中执行

  4. 执行sql语句,获取结果集
    - 增删改:int affected(受影响的) 影响数据库的有效行数
    - 查询:ResultSet结果集,把查询的多行结果存储到一个结果集中

  5. 处理结果集
    - 增删改:不用处理
    - 查询:遍历结果集

  6. 释放资源

注意:1,2,3,6固定不变,4,5根据增删改查不同而不同

第一步:注册驱动

使用java.sql.DriverManager类中的方法实现:管理一组JDBC驱动程序的基本服务。
静态方法
static void registerDriver​(Driver driver) 使用 DriverManager注册给定的驱动程序。

参数:
  java.sql.Driver:是一个接口,每个驱动程序类必须实现的接口。
  传递Driver接口的实现类对象,由mysql驱动提供
  com.mysql.jdbc.Driver
public class Demo01JDBC {
    public static void main(String[] args) throws SQLException {       
     	DriverManager.registerDriver(new Driver());
    }
}

查看com.mysql.jdbc.Driver的源码发现,有一个静态代码块,已经注册了驱动,我们再注册一个驱动,就注册了两次,会产生浪费

static {
            try {
                DriverManager.registerDriver(new Driver());
            } catch (SQLException var1) {
                throw new RuntimeException("Can't register driver!");
            }
        }

解决方案:使用反射技术,获取class文件,会执行类中的静态代码块
格式:Class.forName("foo.bah.Driver")

public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    }
}

第二步:获取数据库连接对象Connection

使用java.sql.DriverManager类中的方法实现
静态方法:
static Connection getConnection​(String url, String user, String password) 尝试建立与给定数据库URL的连接。

参数:
     String url:数据库服务器的地址,固定格式
         - jdbc:mysql://ip:端口号/数据库名称
         - jdbc:mysql://localhost:3306/day03
     String user:数据库用户名
     String password:数据库密码
返回值:
     java.sql.Connection是一个接口,返回的是Connection接口的实现类对象
     由mysql驱动提供,我们可以使用Connection接口来接收这个实现类对象(多态)
public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);com.mysql.jdbc.JDBC4Connection@28f67ac7
    }
}

第三步:获取执行者对象Statement

使用Connection接口中提供的方法实现:
Statement createStatement() 创建一个 Statement对象,用于将SQL语句发送到数据库。

返回值:
     java.sql.Statement是一个接口,返回的是Statement接口的实现类对象
     由mysql驱动提供,我们可以使用Statement接口来接收这个实现类对象(多态)
public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);com.mysql.jdbc.JDBC4Connection@28f67ac7
        Statement stat = conn.createStatement();
        //System.out.println(stat);//com.mysql.jdbc.StatementImpl@28f67ac7
    }
}

第四步:执行sql语句,获取结果集

使用Statement接口中的方法实现:

  • int executeUpdate​(String sql) 执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。
  • ResultSet executeQuery​(String sql) 执行给定的SQL语句,该语句可能为SELECT
public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);com.mysql.jdbc.JDBC4Connection@28f67ac7
        Statement stat = conn.createStatement();
        //System.out.println(stat);//com.mysql.jdbc.StatementImpl@28f67ac7
        int row = stat.executeUpdate("INSERT INTO products(pid, pname,price,flag,category_id) "+
                "VALUES('p012','键盘',500,'1','c001');");
    }
}

完整代码

public class Demo01JDBC {
    public static void main(String[] args) throws ClassNotFoundException {
    	Class.forName("com.mysql.jdbc.Driver");
    	Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/day03", "root", "root");
        //System.out.println(conn);com.mysql.jdbc.JDBC4Connection@28f67ac7
        Statement stat = conn.createStatement();
        //System.out.println(stat);//com.mysql.jdbc.StatementImpl@28f67ac7
        int row = stat.executeUpdate("INSERT INTO products(pid, pname,price,flag,category_id) "+
                "VALUES('p012','键盘',500,'1','c001');");
        //5.处理结果集
        System.out.println(row);//1
        //6.释放资源
        stat.close();
        conn.close();
    }
}

创建JDBCUtils工具类并测试

创建JDBC工具类,工具类中的方法都是静态方法,方便直接通过类名使用

  • 定义一个静态方法,获取Collection对象并返回
  • 定义一个静态方法,释放资源

代码示例:JDBCUtils工具类创建

import java.sql.*;

public class JDBCUtils {
    //定义4个静态的成员变量,用于存储数据库连接的相关信息
    //注册驱动的地址
    private static String driver = "com.mysql.jdbc.Driver";
    //数据库的url地址
    private static String url = "jdbc:mysql://localhost:3306/day03";
    //数据库用户名
    private static String user = "root";
    //数据库的密码
    private static String password = "root";

    //静态代码块:优先执行,只执行一次
    static {
        //注册驱动
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //定义一个静态方法,获取Collection对象并返回
    public static Connection getConnection(){
        Connection conn = null;
        try {
            //获取Connection对象并返回
            conn = DriverManager.getConnection(url, user, password);
        } catch (Exception e) {
            /*
                如果获取数据库连接对象失败,那么程序就没有必要继续执行了
                所以可以把编译异常转换为运行时异常,让程序停止下来
             */
            throw new RuntimeException("获取数据库连接对象失败"+e);
        }
        return conn;
    }
    //定义一个静态方法,释放资源
    public static void close(ResultSet rs, Statement stat, Connection conn){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stat!=null){
            try {
                stat.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

测试类

/*
 测试JDBCUtils工具类
 */
public class Demo02testJDBCUtils {
    public static void main(String[] args) {
        //使用JDBCUtil工具类中的方法getConnection获取数据库连接对象
        Connection conn = JDBCUtils.getConnection();
        System.out.println(conn);//com.mysql.jdbc.JDBC4Connection@256216b3
    }
}

使用JDBC技术对数据库进行操作

增删改

@Test
    public void testInsert() {
        //使用JDBCUtils工具类中的方法getConnection获取数据库连接对象
        Connection conn = JDBCUtils.getConnection();
        //获取执行者对象
        Statement stat = null;
        try {
            stat = conn.createStatement();
            //执行sql语句,获取结果
            //增加数据
            int row = stat.executeUpdate("INSERT INTO products(pid, pname,price,flag,category_id)"+
                    " VALUES('p014','鼠标',500,'1','c001'),('p015','鼠标',500,'1','c001');");
            //修改数据
            //int row = stat.executeUpdate("UPDATE products SET price = 7999 WHERE pid = 'p013';");
            //删除数据
            //int row = stat.executeUpdate("DELETE from products where pid in('p001','p002','p003');");
            //处理结果
            System.out.println(row+"行数据添加成功!");


        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            //释放资源
            JDBCUtils.close(null,stat,conn);
        }
    }

查询

执行sql语句,获取结果集
ResultSet executeQuery​(String sql) 执行给定的SQL语句,该语句可能为SELECT

返回值:
   java.sql.ResultSet是一个接口,返回的是ResultSet接口的实现类对象。
   由mysql驱动提供,我们可以使用ResultSet接口来接收这个实现类对象(多态)

处理结果集,遍历结果集:和迭代器的使用方式一模一样

  • ResultSet中有一个方法叫next判断有没有下一行数据;有返回true,没用返回false
    boolean next() 将光标从当前位置向前移动一行。
  • ResultSet中有一个方法叫getXXX(列的索引/列名)取出结果
    int getInt​(int columnIndex)列的索引,从1开始
    int getInt​(String columnLabel)列名
    注意:数据库的列是什么类型,就用get类型的方法获取这个字段
    也可以使用getObject来获取所有类型的字段,返回值是Object类型

代码示例:

@Test
    public void testSelect() throws SQLException {
        //使用JDBCUtils工具类中的方法getConnection获取数据库连接对象
        Connection conn = JDBCUtils.getConnection();
        //获取执行者对象
        Statement stat = conn.createStatement();
        /*
            执行sql语句,获取结果集
            ResultSet executeQuery​(String sql) 执行给定的SQL语句,该语句可能为SELECT
            返回值:
                java.sql.ResultSet是一个接口,返回的是ResultSet接口的实现类对象
                由mysql驱动提供,我们可以使用ResultSet接口来接收这个实现类对象(多态)
         */
        ResultSet rs = stat.executeQuery("select * from products;");
        //System.out.println(rs);//com.mysql.jdbc.JDBC42ResultSet@3224f60b
        /*
            处理结果集,遍历结果集
            和迭代器的使用方式一模一样
            ResultSet中有一个方法叫next判断有没有下一行数据;有返回true,没用返回false
                boolean next() 将光标从当前位置向前移动一行。
            ResultSet中有一个方法叫getXXX(列的索引/列名)取出结果
                int getInt​(int columnIndex):列的索引,从1开始
                int getInt​(String columnLabel):列名
                注意:数据库的列是什么类型,就用get类型的方法获取这个字段
                也可以使用getObject来获取所有类型的字段,返回值是Object类型
         */
        while(rs.next()){
            /*String pid = rs.getString(1);
            String pname = rs.getString(2);
            int price = rs.getInt(3);
            String flag = rs.getString(4);
            String category_cid = rs.getString(5);*/
            String pid = rs.getString("pid");
            String pname = rs.getString("pname");
            int price = rs.getInt("price");
            String flag = rs.getString("flag");
            String category_cid = rs.getString("category_id");
            System.out.println(pid+"\t"+pname+"\t"+price+"\t"+flag+"\t"+category_cid);
        }
        //释放资源
        JDBCUtils.close(rs,stat,conn);

    }
发布了41 篇原创文章 · 获赞 51 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/Sakuraaaaaaa/article/details/104631643