JDBC入门(1)

本文深入解析Java Database Connectivity(JDBC)的概念与作用,探讨其如何通过接口实现数据库操作的标准化,有效提升程序的扩展性和跨数据库兼容性。文章详细介绍了JDBC的使用步骤,包括驱动加载、连接建立、SQL执行及结果集处理,并对比了Statement与PreparedStatement的优劣,重点阐述了PreparedStatement如何避免SQL注入,提高执行效率。

JDBC是什么?

Java Database Connectivity(Java语言连接数据库)
是Sun公司制定的一套接口

目的:解耦合,增强程序扩展力
在 java.sql.*; 包下
为什么制定JDBC接口?
因为每一个数据库的底层实现原理不一样
如果没有接口
则对不同的数据库,比如 MySQL,Oracle,Sqlserver;
每一个数据库我们都要写一套Java程序
有了接口,实现类 由各数据库厂家完成即可,程序员只需对一套接口进行代码编写即可
需要从各数据库官网下载jar包(驱动),并配置到配置文件中
步骤

  1. 告诉java要执行哪一个数据库
  2. 连接:jvm进程和数据库的通信是重量级的,使用完要关闭
  3. 获取数据库操作对象(执行SQL语句的对象)
  4. 执行SQL语句
  5. 处理查询结果集
  6. 释放资源
    JDBC的模板架构
    添加 jar 包(驱动)
  • 先导包import java.sql.*
  • 分别创建Connection ,Statement ,ResultSet 对象
    分别为为连接器对象,数据库操作对象,查询结果集对象
  • 将上文提到的6大步骤的前5步写到一个try catch 语句块中(因为此程序运用反射机制,所以需要添加ClassNotFoundException)
  • 最后对Connection ,Statement ,ResultSet 对象进行关闭,按照
    ResultSet,Statement ,Connection 顺序进行关闭
  • Statement对象用来处理 sql 语句ResultSet 对象是专门用来处理 查询 语句
import java.sql.*;
public class JDBCTest05 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        String driver = null;
        String url = "jdbc:mysql://127.0.0.1:3306/数据库名?useUnicode=true&characterEncoding=UTF-8&userSSL=false&serverTimezone=GMT%2B8";
        //自己使用的数据是8版本,url格式和驱动字符串格式与5版本有差异
        //jdbc:mysql://127.0.0.1:3306/ DatabaseName ?useUnicode=true&characterEncoding=UTF-password8&userSSL=false&serverTimezone=GMT%2B8
        String user = "root";
        String password = "password";
        try{
            //1.注册驱动
            //DriverManager.registerDriver(new com.mysql.jdbc.Driver());
            driver = "com.mysql.cj.jdbc.Driver";
            Class.forName(driver);
            //2.获取连接
            conn = DriverManager.getConnection(url,user,password);
            System.out.println("数据库连接对象 = "+conn);
            //3.获取数据库操作对象(Statement对象专门执行sql语句)
            stmt = conn.createStatement();
            //4.执行sql(JDBC sql 语句不需要加 ';' )
            //String sql = "update my_employees set Last_name = 'hahahaha' where Id = 1";
            String sql = "select * from my_employees";
            rs = stmt.executeQuery(sql);  //此方法专门执行查询语句
            //5.处理查询结果集

            //int count = stmt.executeUpdate(sql);     该方法处理DML语句,返回影响数据库中的记录条数
            //System.out.println(count == 1 ? "保存成功":"保存失败");
            while(rs.next()){
                String First_name = rs.getString("First_name");
                String Last_name = rs.getString("Last_name");
                String Userid = rs.getString("Userid");
                int Salary = rs.getInt("Salary");
                System.out.println(First_name+","+Last_name+","+Userid+","+Salary);
            }
        }catch(SQLException e){
            e.printStackTrace();
        }catch (ClassNotFoundException e){
            e.printStackTrace();
        } finally{
            if (rs != null) { //先关闭rs
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (stmt != null) { //再关闭stmt
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {  //最后关闭conn
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

SQL注入问题,如何解决?

  1. 使用户提供的信息不参与SQL语句的编译
  2. 所以要使用Statement的子接口PreparedStatement,它属于预编译数据库操作对象
    Statement 和 PreparedStatement 区别
  • PreparedStatement解决了SQL注入问题
  • Statement是编译一次执行一次,PreparedStatement 编译一次可以执行无数次,相对而言效率较高
  • PreparedStatement会在编译阶段做类型的安全检查
    原本的代码顺序为

//3.获取数据库操作对象(Statement对象专门执行sql语句)
stmt = conn.createStatement();
//4.执行sql(JDBC sql 语句不需要加 ‘;’ )
//String sql = “update my_employees set Last_name = ‘hahahaha’ where Id = 1”;
String sql = “select * from my_employees”;
rs = stmt.executeQuery(sql); //此方法专门执行查询语句

现在要先设置sql,然后预处理,接着给占位符赋值,然后获取查询结果集 PreparedStatement ps

		//3.获取处理sql对象
        String sql = "select * from my_employees where Salary = ?";
        ps = conn.prepareStatement(sql);
        //4.给占位符赋值
        ps.setString(1,"1000");
        //获取处理查询结果集对象
        rs = ps.executeQuery();          

在执行多条DML语句(增删改),比如银行转账的业务逻辑,因为MySQL默认是自动提交,所以,为了防止信息丢失,需要关闭自动提交
拿到连接对象后,重点三行代码

开启事务(关闭自动提交) Connection conn;

conn.setAutoCommit();

conn.commit();

conn.rollback();
    
因为有多行DML语句,所以如果用一个变量来获取处理成功sql语句的个数  int count;
每执行完成一次(int count = ps.executeUpdate(); )
count +=  ps.executeUpdate();
...
...
想让代码变得更加美观,则将一些固定的模块封装到一个工具类中即可
工具类的方法都为静态方法,所以我们在设置构造方法时,用**private**修饰,防止他人构造对象
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值