栏目分类:
子分类:
返回
终身学习网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
终身学习网 > IT > 软件开发 > 后端开发 > Java

【笔记】JDBC

Java 更新时间:发布时间: 百科书网 趣学号

文章目录
    • JDBC
    • 环境准备
      • IDEA开发
      • 文本编辑器开发
    • JDBC编程六步 
      • ①注册驱动
      • ②获取连接
      • ③获取数据库操作对象
      • ④执行sql
      • ⑤处理查询结果集
      • ⑥释放资源
    • 从配置文件中读取
    • 模拟用户登录功能
    • SQL注入
      • sql注入原因
      • 解决sql注入
    • 事务
    • JDBC封装
    • 参见

JDBC

Java Database Connectivity(Java语言连接数据库)

JDBC是SUN公司制定的一套接口,具体实现由数据库厂商完成,使用者面向接口编程

解决不同数据库厂商数据库实现原理不同的问题,一套代码可以共用,简化了程序的开发

环境准备

官网下载对应的驱动jar包 MySQL :: Download Connector/J

IDEA开发

idea配置比较简单,只需要在环境中引入jar包即可

文本编辑器开发

如果不使用ide则需要配置环境变量classpath

如果以前配置过,直接在末尾添加jar包路径

如果没有配置过,新建一个CLASSPATH 环境变量输入 .;后添加jar包路径

 classpass 是java编译时寻找的路径,.是指在当前路径中寻找,;是环境变量的分隔符,再在后面添加jdbc的jar包后,编译的时候会自动在这个文件中查找相关类。

⚠️ 注意都是英文字符

JDBC编程六步 
第一步:注册驱动(作用:告诉Java程序,即将要连接的是哪个品牌的数据库)

第二步:获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,重量级的,使用完之后一定要关闭通道。)

第三步:获取数据库操作对象(专门执行sql语句的对象)

第四步:执行SQL语句(DQL DML....)

第五步:处理查询结果集(只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集。)

第六步:释放资源(使用完资源之后一定要关闭资源。Java和数据库属于进程间的通信,开启之后一定要关闭。)
①注册驱动
Driver driver = new com.mysql.jdbc.Driver();
DriverManager.registerDriver(driver); // 通过驱动管理类注册

mysql中关于Driver类的源码

package com.mysql.jdbc;

import java.sql.DriverManager;
import java.sql.SQLException;

public class Driver extends NonRegisteringDriver implements java.sql.Driver {
    public Driver() throws SQLException {
    }

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

从第10行往下可以看到这里已经静态注册了驱动,所以可以使用类加载的方式

Class.forName("com.mysql.jdbc.Driver"); //由于静态实现注册,反射即可
②获取连接
String url = "jdbc:mysql://localhost:3306/bjpowernode";
String user = "root";
String pass = "root";
Connection conn = DriverManager.getConnection(url,user,pass); // 通过驱动管理类获取connection对象
System.out.println(conn);

 com.mysql.jdbc.JDBC4Connection@66d33a 工具类多态

③获取数据库操作对象

获取数据库操作对象Statement专门执行sql语句的

Statement stmt = conn.createStatement();
④执行sql

executeUpdate(sql)专门执行DML语句(insert delete update)返回值为影响的数目

⑤处理查询结果集

只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集。

String sql = "select empno,ename,sal from emp";
rs = stmt.executeQuery(sql); // ResultSet
while (rs.next()) { // 指向下一个,如果有true,没有false
    String empno = rs.getString(1);// 数字,从1开始
    String ename = rs.getString("ename");// 查询到表的表名
    String sal = rs.getString(3);
    System.out.println(empno + " " + ename + " " + sal);
}
⑥释放资源
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{......}
catch(){
    
}finally {
    // 无论如何,最后都一定要关闭
    if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close(); // 从小到大分别关闭,不然有可能中途异常导致之后代码无法关闭
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
}
从配置文件中读取
ResourceBundle bundle = ResourceBundle.getBundle("jdbc");
driver= bundle.getString("driver");
url = bundle.getString("url");
user = bundle.getString("user");
pass = bundle.getString("pass");

jdbc.properties

driver = com.mysql.jdbc.Driver
url = jdbc:mysql://localhost:3306/bjpowernode
user = root
pass = root
模拟用户登录功能
public class ForLogin {
    
    public static void main(String[] args) {
        Map userLoginInfo = initUI();// 初始化界面,返回登录信息
        boolean loginSuccess = login(userLoginInfo);// 判断登录信息
        if (loginSuccess) {
            System.out.println("success");
        } else {
            System.out.println("failure");
        }
    }
    private static boolean login(Map userLoginInfo) {
        boolean loginSuccess = false;
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode", "root", "root");
            stmt = conn.createStatement();
            String sql = "select * from t_user where name = '" + userLoginInfo.get("name") + "' and pass = '"
                    + userLoginInfo.get("pass") + "'";
            rs = stmt.executeQuery(sql);
            if (rs.next()) {
                loginSuccess = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            ...// close 代码过长省略
        }
        return loginSuccess;
    }

    private static Map initUI() {
        Scanner s = new Scanner(System.in);
        System.out.println("输入用户名:");
        String name = s.nextLine();
        System.out.println("输入密码:");
        String pass = s.nextLine();
        Map userLoginInfo = new HashMap<>();
        userLoginInfo.put("name", name);
        userLoginInfo.put("pass", pass);
        return userLoginInfo;
    }
}
SQL注入

使信息存在安全隐患

sql注入原因

用户输入的信息中包含了sql语句中的关键字,并且这些关键字参与了sql语句的编译过程,导致sql语句的原意被扭曲进而达到sql注入

解决sql注入

只要用户输入的信息不参与编译的过程,问题就解决了

使用PreparedStatement,PreparedStatement 继承了Satatement 属于预编译的数据库操作对象,预先给sql语句框架编译,然后再给sql语句传值

private static boolean login(Map userLoginInfo) {
    boolean loginSuccess = false;
    Connection conn = null;
    PreparedStatement ps = null;
    ResultSet rs = null;
    try {
        Class.forName("com.mysql.jdbc.Driver");
        conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode", "root", "root");
        // sql语句框架,一个问号表示一个占位符,将来接受传入数据
        String sql = "select * from t_user where name = ? and pass = ?";
        ps = conn.prepareStatement(sql);
        // 传值,从下标1开始
        ps.setString(1,userLoginInfo.get("name"));
        ps.setString(2,userLoginInfo.get("pass"));
        rs = ps.executeQuery();
        if (rs.next()) {
            loginSuccess = true;
        }
    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        ...// close
    }
    return loginSuccess;
}
事务

jdbc事务是默认自动提交的,执行任意一条语句则自动提交一次,要开启事务只需添加 conn.setAutoCommit(false)

public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try{
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","root");
            
            // 取消自动提交,开启事务
            conn.setAutoCommit(false);

            String sql = "update t_act set balance = ? where actno = ?";
            ps = conn.prepareStatement(sql);
            ps.setDouble(1,1000);
            ps.setInt(2,111);
            ps.executeUpdate();
//            String s=null;
//            s.toString();
            ps.setDouble(1,1000);
            ps.setInt(2,222);
            ps.executeUpdate();

            // 无异常提交
            conn.commit();
        }catch (Exception e){
            // 异常,回滚
            try {
                conn.rollback();
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            ...// close
        }
    }
JDBC封装
public class DBUtil {
    // 工具类 私有化
    private DBUtil(){}
    
    // 静态代码块
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }
    
    // 得到conn
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/bjpowernode","root","root");
    }
    // 关闭,释放资源
    public static void close(Connection conn, Statement stmt, ResultSet rs){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(stmt!=null){
            try {
                stmt.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn!=null){
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
参见
  • JDBC从入门到精通视频教程-JDBC实战精讲,动力节点
转载请注明:文章转载自 www.051e.com
本文地址:http://www.051e.com/it/293171.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 ©2023-2025 051e.com

ICP备案号:京ICP备12030808号