JDBC

作者: PC_Repair | 来源:发表于2019-10-26 12:53 被阅读0次

JDBC(Java DataBase Connectivity)是 Java 和数据库之间的一个桥梁,是一个规范而不是一个实现,能够执行 SQL 语句。它由一组 Java 语言编写的类和接口组成,各种不同类型的数据库都有相应的实现,下面的示例代码是采用 MySQL 数据库实现的。

1567043260200.png

JDBC 编程步骤

(1)装载相应的数据库的 JDBC 驱动并进行初始化

  • 导入 jar 包,或者通过 maven 添加依赖都可以。

  • 初始化驱动

try {
    Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
    e.printStackTrace();
}
// 注意:Class.forName 需要捕获 ClassNotFoundException
// Class.forName 是把这个类加载到 JVM 中,加载的时候,会执行其中的静态初始化块,完成驱动的初始化的相关工作

(2)建立 JDBC 和数据库之间的 Connection 连接

需要知道的数据库信息:

  • 数据库所处于的 ip ,如:127.0.0.1

  • 数据库的端口号: 3306 (mysql专用端口号)

  • 数据库名称:eee

  • 编码方式:UTF-8

  • 账号:root,密码:root

Connection c = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/exam?characterEncoding=UTF-8", "root", "root");
// Connection 是与特定数据库连接的接口,使用的时候需要导包,在程序结束的时候需要将其关闭
// getConnection 会抛出 SQLException 异常

封装后的 getConnection 方法,便于将来直接调用

public static Connection getConnection(){
    Connection conn = null;
    try {
        //初始化驱动类com.mysql.jdbc.Driver
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/exam?characterEncoding=UTF-8","root", "root");
        //该类就在 mysql-connector-java-5.0.8-bin.jar中,如果忘记了第一个步骤的导包,就会抛出ClassNotFoundException
         }catch (ClassNotFoundException e) {                
                e.printStackTrace();
         }catch (SQLException e) {                          
                e.printStackTrace();
     }
     return conn;
}

(3)创建 Statement 或者 PreparedStatement 接口,执行 SQL 语句

  • 使用 Statement 接口
Statement s = conn.createStatement();
// 准备 sql 语句
// 注意: 字符串要用单引号'
String sql = "insert into t_courses values(null,"+"'数学')";
//在 statement 中使用字符串拼接的方式,这种方式存在诸多问题
s.execute(sql);
System.out.println("执行插入语句成功");

注意:在 statement 中使用字符串拼接的方式,这种方式存在诸多问题。

  • 使用 PreparedStatement 接口
// add 操作
public void addCourse(String courseName){
        String sql = "insert into t_course(course_name) values(?)";  
 //该语句为每个 IN 参数保留一个问号(“?”)作为占位符
        Connection conn = null;             //和数据库取得连接
        PreparedStatement pstmt = null;     //创建statement
        try{
            conn = DbUtil.getConnection();
            pstmt = (PreparedStatement) conn.prepareStatement(sql);
            pstmt.setString(1, courseName); //给占位符赋值
            pstmt.executeUpdate();          //执行
        }catch(SQLException e){
            e.printStackTrace();
        }
        finally{
            DbUtil.close(pstmt);
            DbUtil.close(conn);     //必须关闭
        }
}
// delete 操作
public void delCourse(int courseId){
        String sql = "delete from t_course where course_id = ?";
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = DbUtil.getConnection();
            pstmt = (PreparedStatement) conn.prepareStatement(sql);
            pstmt.setInt(1, courseId);
            pstmt.executeUpdate();
        } catch (SQLException e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
            DbUtil.close(pstmt);
            DbUtil.close(conn);     //必须关闭
        }
}
// update 操作
public void modifyCourse(int courseId,String courseName){
        String sql = "update t_course set course_name =? where course_id=?";
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
            conn = DbUtil.getConnection();
            pstmt = (PreparedStatement) conn.prepareStatement(sql);
            pstmt.setString(1, courseName);  //利用Preparedstatement的set方法给占位符赋值
            pstmt.setInt(2, courseId);
            pstmt.executeUpdate();
        } catch (SQLException e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
            DbUtil.close(pstmt);
            DbUtil.close(conn);     //必须关闭
        }
}

注意:

  • 使用 PreparedStatement 时,它的 SQL 语句不再采用字符串拼接的方式,而是采用占位符的方式。“?”在这里就起到占位符的作用。这种方式除了避免了 statement 拼接字符串的繁琐之外,还能够提高性能。每次 SQL 语句都是一样的,数据库就不会再次编译,这样能够显著提高性能。
String sql = "update t_course set course_name =? where course_id=?";
  • 用到 PreparedStatement 接口创建的 pstmt 的 set 方法给占位符进行赋值。注意一点,这里的参数索引是从1开始的。
pstmt = (PreparedStatement) conn.prepareStatement(sql);
pstmt.setString(1, courseName);  //利用Preparedstatement的set方法给占位符赋值
pstmt.setInt(2, courseId);
pstmt.executeUpdate();
  • 使用 PreparedStatement 进行批量操作
for(int i=1;i<100;i++){
    pstmt.setInt(1,8000+i);
    pstmt.setString(2,"赵_"+i);
    pstmt.addBatch();
    //批量更新
    if(i%10 == 0){
        pstmt.executeBatch();
    }
}

(4)查询操作 & 处理显示结果

public List<Course> findCourseList(){
        String sql = "select * from t_course order by course_id";
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        //创建一个集合对象用来存放查询到的数据
        List<Course> courseList = new ArrayList<>();
        try {
            conn = DbUtil.getConnection();
            pstmt = (PreparedStatement) conn.prepareStatement(sql);
            rs = (ResultSet) pstmt.executeQuery();
            while (rs.next()){
                int courseId = rs.getInt("course_id"); // 可以填属性值
                String courseName = rs.getString("course_name");
                //每个记录对应一个对象
                Course course = new Course();
                course.setCourseId(courseId);
                course.setCourseName(courseName);
                //将对象放到集合中
                courseList.add(course);
            }
        } catch (SQLException e) {
            // TODO: handle exception
            e.printStackTrace();
        }finally{
            DbUtil.close(pstmt);
            DbUtil.close(conn);     //必须关闭
        }
        return courseList;
}

(5)释放资源

    public static void close(PreparedStatement pstmt){
        if(pstmt != null){  //避免出现空指针异常
            try{
                pstmt.close();
            }catch(SQLException e){
                e.printStackTrace();
            }
            
        }
    }

    public static void close(Connection conn){
        if(conn != null){
            try {
                conn.close();
            } catch (SQLException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    }
    
    public static void close(ResultSet rs){
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                // TODO: handle exception
                e.printStackTrace();
            }
        }
    }

Statement 和 PreparedStatement 的比较

相同点:

  • 两者都是用来执 SQL 语句的。

不同点:

  • PreparedStatement 需要根据 SQL 语句来创建,它能够通过设置参数,指定相应的值。
  • Statement 使用字符串拼接的方式。

PreparedStatement 的优点:

  • 其使用参数设置,可读性好,不易记错。在 statement 中使用字符串拼接,可读性和维护性比较差。
  • 其具有预编译机制,性能比 statement 更快。
  • 其能够有效防止 SQL 注入攻击。

execute 和 executeUpdate 的区别

相同点:二者都能够执行增加、删除、修改等操作。

不同点:

  • execute可以执行查询语句,然后通过 getResult 把结果取出来。
  • executeUpdate 不能执行查询语句。
  • execute 返回 Boolean 类型,true 表示执行的是查询语句,false 表示执行的 insert、delete、update 等。
  • executeUpdate 的返回值是 int,表示有多少条数据受到了影响。

相关文章

  • JDBC

    JDBC原理: JDBC: 抽取JDBC工具类 : JDBCUtils JDBC控制事务:

  • JDBC 的使用

    JDBC JDBC什么是JDBCJDBC 的使用JDBC 的数据类型 什么是JDBC JDBC(Java Data...

  • Java和MySQL简建立连接

    JDBC JDBC插入多条数据 JDBC查询 JDBC动态传参 JDBC回滚 JDBC将数据库中的信息装入List...

  • JDBC

    JDBC JDBC:Java DataBase Connectivity JDBC的本质是什么?JDBC是SUN公...

  • java异常合集

    jdbc com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorExce...

  • Day05--JDBC

    JDBC: 抽取JDBC工具类:JDBCUtils JDBC控制事务

  • JDBC

    JDBC: 抽取JDBC工具类 : JDBCUtils JDBC控制事务:

  • JDBC编程目录

    JDBC编程目录 SQL基础JDBC基础JDBC进阶

  • JDBC和数据库连接池

    1.JDBC介绍1.1 1.1 JDBC介绍 2.JDBC之API2.1 2.1 JDBC之API 3.JDBC例...

  • # day10_JDBC基础

    一,JDBC概述 1.为什么要使用JDBC 1.1没有JDBC 1.2有了JDBC后 2.JDBC的概念 2.1....

网友评论

      本文标题:JDBC

      本文链接:https://www.haomeiwen.com/subject/mriyvctx.html