(一天学完JDBC[详细知识点大吐血]

JDBC的定义与作用

  1. JDBC 是Java DataBase Connectivity 的缩写,即(Java语言连接数据库);

  2. JDBC的本质是SUN公司制定的一套接口(interface),在java.sql.*; (这个软件包下有很多接口。);

  3. 为什么SUN制定一套JDBC接口呢?;
    因为每一个数据库的底层实现原理都不一样;每一个数据库产品都有自己独特的实现原理。

  4. JDBC开发前的准备工作:
    先从官网下载对应的驱动jar包,然后将其配置到环境变量classpath当中。
    mysql-connector-java-8.0.11 提取码[aaaa]
    MySql Connector Java 5.1.23 提取码[aaaa];

  5. 使用IDEA工具配置驱动;
    一、右键目标模块在这里插入图片描述
    二、
    在这里插入图片描述
    三、点击“+”,选择Java
    在这里插入图片描述
    四、找到驱动
    在这里插入图片描述
    五、选择目标模块
    在这里插入图片描述

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

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

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

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

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

    第六步:释放资源(使用完资源之后一定要关闭资源。Java和数据库属于进程间的通信,开启之后一定要关闭。)

JDBC 编程6步(以下使用的MySQL版本为8.0)

第一步:注册驱动(两种方式)

  • 第一种方式 :
    Driver driver = new com.mysql.cj.jdbc.Driver();
    DriverManager.registerDriver(driver);

  • 第二种方式 :
    String driver = “com.mysql.cj.jdbc.Driver”;
    Class.forName(driver);

  • 对于这两种方式来说,第二种方式更加的通用一些,为什么呢?我们可以看下源码:
    在类加载的时候,静态代码块执行。

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

第二步:连接驱动

  • url :统一资源定位符(网络中某个资源的绝对路径)
    https://www.baidu.com/ 这就是URL
    URL 包括哪几部分?
    协议
    IP
    PORT
    资源名

          http://182.61.200.7:80/index.html
              http://             通信协议
              182.61.200.7        服务器IP地址
              80                  服务器上软件的端口
              index.html          服务器上某个资源名
    
          jdbc:mysql://localhost:3306/myMySQL?useSSL=false&serverTimezone=UTC
              jdbc:mysql://                       协议
              localhost                           IP
              3306                                端口
              myMySQL                         具体的数据库实例名
              ?useSSL=false&serverTimezone=UTC    是否使用 SSL 安全验证及指定服务器上的时区
    
           说明 :
              localhost 和 127.0.0.1 都是本机IP地址。
    
           什么是通信协议?有什么用?
              通信协议是 通信之前就提前定好的数据传送格式。
              数据包具体怎么传数据,格式是提前订好的。
    
  • MySQL5.0版本:

			String url = "jdbc:mysql://localhost:3306/myMysql;
          	String user = "root";
            String password = "123456";
            con = DriverManager.getConnection(url,user,password);
  • MySQL8.0及以上版本 :

			String url = "jdbc:mysql://localhost:3306/myMysql?useSSL=false&serverTimezone=UTC";
          	String user = "root";
            String password = "123456";
            con = DriverManager.getConnection(url,user,password);
  • 因为在JDBC中,对事物是自动提交的,执行一条SQL语句,提交一次,存在安全隐患,所以我们需要关闭自动提交,开启手动提交模式

Connection conn = null;
conn.setAutoCommit(false); // 开启事物
conn.commit(); // 关闭事物
conn.rollback(); // 回滚事务(在catch语句块中执行)

第三步 :获取数据库操作对象(2种)

  • 获取数据库操作对象(Statement)
    Statement st = 驱动.createStatement();
  • 获取预编译的数据库操作对象(PreparedStatement)
			// SQL语句的框架,其中一个?,表示一个占位符,一个?将来接受一个“值”,注意:占位符不能使用单引号括起来
			String sql = "select * from t_user where loginName = ? and loginPwd = ?"; //

            // 程序执行到此处,会发送SQL语句框子给DBMS,然后DBMS进行SQL语句的预编译。
            ps = conn.prepareStatement(sql);

            // 给占位符传值,第一个?下标是1,第二个?下标是2,JDBC中所有下标从1开始
            ps.setString(1,loginName);
            ps.setString(2,loginPwd);
  • 什么是SQL注入?
    程序对用户输入数据的合法性没有判断或过滤不严
  • SQL注入的原因 ?
    用户输入的信息中含有SQL语句的关键字,并且这些关键字参与了SQL语句的编译过程,
    导致SQL语句的原因被扭曲,进而导致SQL注入。
  • 对比一下Statement 和 PreparedStatement ?
    • Statement 存在SQL注入问题 ,PreparedStatement 解决了SQL注入问题
    • Statement 对SQL语句是编译一次执行一次 ,PreparedStatement 对SQL语句是编译一次执行N次 ,
      PreparedStatement 执行效率较高。
    • PreparedStatement 会在编译阶段做安全检查
  • 综上所述 :PreparedStatement 的使用比较多,只有极少情况下,必须使用Statement

第四步 :执行SQL语句(分为2种)

  • 使用 Statement 对象
			String sql = "insert into dept(deptno,dname,loc) values(50,'人事部','北京')";
			//专门执行DML语句的 int count = statement.executeUpdate(sql);*****************
            // 返回值是“影响数据库中的记录条数”
            // jdbc 中的SQL语句不需要写 分号 ";"
            int count = statement.executeUpdate(sql);
==============================================================
			// 专门执行DQL
			String sql = "select * from emp";
            // ***********************************专门执行DQL的语句 ****************************************
            ResultSet result = state.executeQuery(sql);
  • 使用 PreparedStatement 对象
// 专门执行DML
int count = PreparedStatement 对象.executeUpdate();
// 专门执行DQL
 ResultSet result = ps.executeQuery();

第五步 :处理查询结果集

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

boolean flag = result.next();                   
System.out.println(flag); // 如果有数据,返回true              
if (flag){                                       
 // 光标指向的行有数据                                   
 // 获取数据                                        
 // getString()方法的特点 :不管数据库当中的数据类型是什么,都以String的形
 // JDBC所有下标都是从1开始,而不是从0开始                      
 // 一下程序的 1 2 3 代表的是第几列 
 
 // 一、通过特定的列数获取                        
 String empno = result.getString(1); 
 // 二、通过字段名获取          
 String ename = result.getString("ename");   
 // 三、除了可以以String类型取出,还可以以特定的类型取出         
 double sal = result.getDouble(3);              

第六步 :释放资源

  • 为了保证资源一定释放,在finally语句当中关闭资源
    并且要遵循从小到大依次关闭
    例如 con 调用 createStatement()方法 获取 statement,所以先关闭statement再关闭con
finally {
            // 6、释放资源
            if (result != null) { // ResultSet 对象
                try {
                    result.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (state != null) { // Statement  对象
                try {
                    state.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
            if (con != null) { // Connection  对象
                try {
                    con.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }

完整代码

  • 工具类(自己定义的)
/**
 * JDBC工具类,简化JDBC编程
 */
public class DBUtil {
    /**
     * 工具类中的构造方法都是私有的。
     * 因为工具类当中的方法都是静态的,不需要new对象,直接采用类名调用
     */
    private DBUtil(){

    }

    // 静态代码块在类加载时执行,并且只执行一次
    static {
        try {
            Class.forName("com.mysql.cj.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取数据库连接对象
     * @return 连接对象
     * @throws SQLException
     */
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection("jdbc:mysql://localhost:3306/myMySQL?useSSL=false&serverTimezone=UTC"
                , "root","123456");
    }

    /**
     * 关闭资源
     * @param conn 连接对象
     * @param state 数据库操作对象
     * @param rs 结果集
     */
    public static void close(Connection conn, Statement state, ResultSet rs){
        if (rs != null){
            try {
                rs.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (state != null){
            try {
                state.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
        if (conn != null){
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }
    }
  • 主程序
public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            // 获取连接
            conn = DBUtil.getConnection();
            // 开启事物
            conn.setAutoCommit(false);

            String sql = "select ename,sal,job from emp where job = ? for update ";
            ps = conn.prepareStatement(sql);

            ps.setString(1,"MANAGER");

            rs = ps.executeQuery();
            while(rs.next()){
                System.out.println(rs.getString("ename")+","+rs.getDouble("sal")+","+
                        rs.getString("job"));
            }
            // 提交事务(事务结束)
            conn.commit();
        } catch (SQLException throwables) {
            // 回滚事务(事务结束)
            if (conn != null) {
                try {
                    conn.rollback();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            throwables.printStackTrace();
        }finally {
            DBUtil.close(conn,ps,rs);
        }
    }

结语

如果对您有收获的话,您还可以看看其它的文章,希望对您有用。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值