JDBC

JDBC

1. 简介

  • JDBC(Java Data Base Connectivity, java 数据库连接),由一些接口和类构成的 API。

  • J2SE 的一部分,由 java.sql, javax.sql 包组成。

  • 应用程序、JDBC API、数据库驱动及数据库之间的关系。

在这里插入图片描述

2. 连接数据的步骤

2.1 注册驱动(只做一次)

  • Class.forName("com.mysql.jdbc.Driver");

    推荐使用这种方式,不会对具体的驱动类产生依赖。

  • DriverManager.registerDriber(com.mysql.jdbc.Driver);

    会造成 DriverManager 中产生两个一样的驱动,并会对具体的驱动类产生依赖。

  • System.setProperty(“jdbc.driver”, “driver1: driver2”);

    虽然不会对具体的驱动类产生依赖;但注册不太方便,所以很少使用。

  • 驱动类型(四种类型)

2.2 建立连接(Connection)

  • Connection conn = DriverManager.getConnection(url, user, password);
    • url 格式:JDBC:子协议:子名称//主机名:端口/数据库名?属性名=属性值&…
    • User,password 可以用 “属性名 = 属性值”方式告诉数据库;
    • 其他参数如:useUnicode = true&characterEncoding = GBK。

2.3 创建执行 SQL 的语句(Statement)

  • Statement

    Statement st = conn.createStatement();
    st.executeQuery(sql);
    
  • PreparedStatement

    String sql = "select * from table_name where col_name = ?";
    PreparedStatement ps = conn.preparedStatement(sql);
    ps.setString(1, "col_value");
    ps.executeQuery();
    

2.4 执行语句

2.5 处理执行结果(ResultSet)

ResultSet rs = statement.executeQuery(sql);
While(rs.next()){
	rs.getString("col_name");
	rs.getInt("col_name");
	//...
}

2.6 释放资源

  • 释放 ResultSet, Statement, Connection。
  • 数据库连接(Connection)是非常稀有的资源,用完后必须马上释放,如果 Connection 不能及时正确的关闭将导致系统宕机。Connection 的使用原则是尽量晚创建,尽量早的释放。

3. 第一个 JDBC 程序

  • 创建测试数据库

    CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;
    
    USE jdbcStudy;
    
    CREATE TABLE users(
    	id INT(4) PRIMARY KEY,
    	`name` VARCHAR(40),
    	`password` VARCHAR(40),
    	email VARCHAR(60),
    	birthday DATE
    ); 
    
    INSERT INTO users(id, `name`, `password`, email, birthday)
    VALUES(1, '张三', '123456', 'zs@sina.com', '1980-01-02'),
    (2, '李四', '123456', 'ls@sina.com', '1956-11-02'),
    (3, '王五', '111111', 'ww@sina.com', '1998-11-22')
    
  • 编写测试代码

    import java.sql.*;
    
    public class jdbc {
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            // 1. 注册驱动
            Class.forName("com.mysql.jdbc.Driver");
    
            // 2. 建立连接
            String url = "jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
            String userNmae = "root";
            String password = "123456";
    
            Connection conn = DriverManager.getConnection(url, userNmae, password);
    
            // 3. 创建语句
            Statement st = conn.createStatement();
    
            // 4. 执行语句
            String sql = "SELECT * FROM users";
            ResultSet rs = st.executeQuery(sql);
    
            // 5. 处理结果
            while (rs.next()) {
                System.out.println("id = " + rs.getObject("id"));
                System.out.println("name = " + rs.getObject("name"));
                System.out.println("pwd = " + rs.getObject("password"));
                System.out.println("email = " + rs.getObject("email"));
                System.out.println("birth = " + rs.getObject("birthday"));
                System.out.println("\n");
            }
    
            // 6. 释放资源
            rs.close();
            st.close();
            conn.close();
        }
    }
    
  • 程序小解:

    • DriverManager:

      // DriverManager.registerDriver(new com.mysql.jdbc.Driver());
      Class.forName("com.mysql.jdbc.Driver"); //固定写法,加载驱动
      Connection conn = DriverManager.getConnection(url, userNmae, password);
      
      // conn 代表数据库
      // 数据库设置自动提交
      // 事务提交
      // 事务滚回
      conn.rollback();
      conn.commit();
      conn.setAutoCommit();
      
    • URL

      String url = "jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true";
      
      // mysql -- 3306
      // 协议 ://主机地址:端口号/数据库名?参数1&参数2&参数3
      
      // oralce  -- 1521
      // jdbc:oracle:thin:@localhost:1521:sid
      
    • Statement 执行 SQL 的对象;Prepare Statement 执行 SQL 的对象

      String sql = "SELECT * FROM users";  // 编写 SQL
      
      st.executeQuery();  // 查询操作返回 ResultSet
      st.execute(); // 执行任何 SQL
      st.executeUpdate();  // 更新、插入、删除都是用这个,返回一个受影响的行数
      
    • ResultSet 查询的结果集:封装了所有的查询结果;

      • 获得指定的数据类型

        rs.getObject(); // 在不知道列类型的情况下使用
        // 如果知道列的类型就使用指定的类型
        rs.getString();
        rs.getInt();
        rs.getFloat();
        rs.getDate();
        ……
        
      • 遍历,指针

        rs.beforeFirst(); // 移动到最前面
        rs.afterlast();  // 移动到最后面
        rs.next();  // 移动到下一个数据
        rs.previous(); //移动到前一行
        rs.absolute(row); // 移动到指定行
        

4. Statement 对象

4.1 基本的 CRUD(创建、读取、更新、删除)

JDBC 中的 statement 对象用于向数据库发送 SQL 语句,想完成对数据库的增删改查,只需要通过这个对象
向数据库发送增删改查语句即可。

  • 模板代码

    Connection conn = null;
    Statement st = null;
    ResultSet rs = null;
    try{
        //获取 Connection
        //创建 Statement
        //处理查询结果 ResultSet
    }finally{
        //释放资源ResultSet,Statement,Connection
    }
    
  • 创建:增加对应 SQL 的 INSERT,返回增加成功的行(记录)数

    conn = getConnection();
    Statement st = conn.creatStatement();
    String sql = "insert into user(name, age, regist_date)" + "values('name',10,now())";
    int i = st.executeUpdate(sql);  // i 为插入的记录数
    
  • 读取:读取(查询)对应 SQL 的 SELECT,返回查询结果

    conn = getConnection();
    st = conn.createStatement();
    String sql = "select id, name, age,regist_date from user";
    rs = st.executeQuery(sql);
    while (rs.next()) {
    		System.out.print(rs.getInt("id") + " \t\t ");
    		System.out.print(rs.getString("name") + " \t\t ");
    		System.out.print(rs.getInt("age") + " \t\t ");
    		System.out.print(rs.getTimestamp("regist_date") + " \t\t ");
    		System.out.println();
    }
    
  • 更新:更新(修改)对应 SQL 的 UPDATE,返回被修改的行(记录)数

    conn = getConnection();
    Statement st = conn.createStatement();
    String sql=“update person set name='new name‘”;
    int i = st.executeUpdate(sql);	//i为符合条件的记录数
    
  • 删除:删除对应 SQL 的 DELETE,返回被删除的行(记录)数

    conn = getConnection();
    Statement st = conn.createStatement();
    String sql=“delete from user where id=1;
    int i = st.executeUpdate(sql);	//i为删掉的记录数
    
  • CRUD 总结

    • 增、删、改用 Statement.executeUpdate 来完成,返回整数(匹配的记录数),这类操作相对简单。
    • 查询用 Statement.executeQuery 来完成,返回的是 ResultSet 对象,ResultSet 中包含了查询的结果;查询相对与增、改要复杂一些,因为有查询结果要处理。

4.2 代码实现

1. 在 src 下建立资源文件db.properties

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcStudy?useUnicode=true&characterEncoding=utf8&useSSL=true
userNmae=root
password=123456

2. 提取工具类

package com.sd.jdbc.Statement.Utils;


import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class jdbcUtils {
    private static String driver = null;
    private static String url = null;
    private static String userName = null;
    private static String password = null;

    static{
        try{
            InputStream in = jdbcUtils.class.getClassLoader().getResourceAsStream("db.propertoes");
            Properties properties = new Properties();
            properties.load(in);

            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            userName = properties.getProperty("userName");
            password = properties.getProperty("password");

            // 1. 驱动只用加载一次
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    // 获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url, userName, password);
    }

    // 释放连接资源
    public static void release(Connection conn, Statement st, ResultSet rs){
        if(rs != null){
            try{
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(st != null){
            try{
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(conn != null){
            try{
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

3. 增加方法

package com.sd.jdbc.Statement;

import com.sd.jdbc.Statement.Utils.jdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Demo01 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try{
            conn = jdbcUtils.getConnection(); //获取数据库连接
            st = conn.createStatement(); //获得 SQL 的执行对象

            String sql = "INSERT INTO users(id, `name`, `password`, `email`, `birthday`)" +
                    "VALUES(4, 'SS', '123123', '12341111@sina.com', '2001-09-01')";

            int i = st.executeUpdate(sql);
            if( i > 0){
                System.out.println("插入成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            jdbcUtils.release(conn, st, rs);
        }
    }

}

4. 删除

package com.sd.jdbc.Statement;

import com.sd.jdbc.Statement.Utils.jdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Demo02 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = jdbcUtils.getConnection();  // 获取数据库连接
            st = conn.createStatement(); // 获得 SQL 的执行对象

            String sql = "DELETE FROM  user where id = 3";

            int i = st.executeUpdate(sql);
            if (i > 0) {
                System.out.println("删除成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            jdbcUtils.release(conn, st, rs);
        }
    }
}

5. 修改

package com.sd.jdbc.Statement;

import com.sd.jdbc.Statement.Utils.jdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Demo03 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = jdbcUtils.getConnection();
            st = conn.createStatement();

            String sql = "UPDATE user SET `name`='SS', `emai`=`111@qq.com` WHERE id=2";

            int i = st.executeUpdate(sql);
            if (i > 0) {
                System.out.println("更新成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            jdbcUtils.release(conn, st, rs);
        }
    }
}

6. 查询

package com.sd.jdbc.Statement.Utils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class Demo04 {
    public static void main(String[] args) {
        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;

        try {
            conn = jdbcUtils.getConnection();
            st = conn.createStatement();

            String sql = "select * from user where id=1";

            rs = st.executeQuery(sql);
            while (rs.next()) {
                System.out.println(rs.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            jdbcUtils.release(conn, st, rs);
        }
    }
}

4.3 SQL 注入

  • 在 SQL 中包含特殊字符或 SQL 的关键字(如:’ or 1 or ')时 Statement 将出现不可预料的结果(出现异常或查询的结果不正确),可用 PreparedStatement 来解决。

  • lPreperedStatement(从 Statement 扩展而来)相对 Statement 的优点:

    • 没有 SQL 注入的问题。
    • Statement 会使数据库频繁编译 SQL,可能造成数据库缓冲区溢出。
    • 数据库和驱动可以对 PreperedStatement 进行优化(只有在相关联的数据库连接没有关闭的情况下有效)。
  • 案例:

    package com.sd.jdbc.Statement;
    
    import com.sd.jdbc.Statement.Utils.jdbcUtils;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    public class Demo05 {
    
        public static void main(String[] args) {
            login(" 'or ' 1=1", " 'or ' 1=1");    
        }
    
        public static void login(String userName, String password){
            Connection conn = null;
            Statement st = null;
            ResultSet rs = null;
    
            try{
                conn = jdbcUtils.getConnection();
                st = conn.createStatement();
    
                String sql = "select * from user where `name`='  "+userName+" ' and '  ' "+password+" ' ";
    
                rs = st.executeQuery(sql);
                while(rs.next()){
                    System.out.println(rs.getString("name"));
                    System.out.println(rs.getString("password"));
                    System.out.println("==========================");
                }
    
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                jdbcUtils.release(conn, st, rs);
            }
        }
    }
    

5. PreparedStatement 对象

PreparedStatement 可防止 SQL 注入。效率更高!

1. 插入

package com.sd.jdbc.PreparedStaement;

import com.sd.jdbc.Statement.Utils.jdbcUtils;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Demo01 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = jdbcUtils.getConnection();
            // 区别: 使用 ? 占位符代替参数
            String sql = "insert into user(id, `name`, `password`, `email`, `birthday`) values(?,?,?,?,?)";

            st = conn.prepareStatement(sql);  // 预编写 SQL,先写 sql,然后不执行

            // 手动给参数赋值
            st.setInt(1, 4); // id
            st.setString(2, "qwer");
            st.setString(3, "111111");
            st.setString(4, "12312312@qq.com");
            st.setDate(5, new java.sql.Date(new Date().getTime()));

            // 执行
            int i = st.executeUpdate();
            if (i > 0) {
                System.out.println("插入成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            jdbcUtils.release(conn, st, null);
        }

    }
}

2. 删除

package com.sd.jdbc.PreparedStaement;

import com.sd.jdbc.Statement.Utils.jdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Demo02 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = jdbcUtils.getConnection();

            String sql = "delete from user where id=?";

            st = conn.prepareStatement(sql);

            //手动给参数赋值
            st.setInt(1, 4);

            int i = st.executeUpdate();
            if (i > 0) {
                System.out.println("删除成功!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            jdbcUtils.release(conn, st, null);
        }
    }
}

3. 更新

package com.sd.jdbc.PreparedStaement;

import com.sd.jdbc.Statement.Utils.jdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Demo03 {

    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;

        try {
            conn = jdbcUtils.getConnection();

            String sql = "update user set `name`=? where id=?";

            st = conn.prepareStatement(sql);

            st.setString(1, "钱六");
            st.setInt(2, 1);

            int i = st.executeUpdate();
            if (i > 0) {
                System.out.println("更新成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            jdbcUtils.release(conn, st, null);
        }
    }
}

4. 查询

package com.sd.jdbc.PreparedStaement;

import com.sd.jdbc.Statement.Utils.jdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class Demo04 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            conn = jdbcUtils.getConnection();

            String sql = "select * from user where id =?";

            st = conn.prepareStatement(sql);  //预编译

            st.setInt(1, 2); //传递参数

            rs = st.executeQuery();  // 执行

            if (rs.next()) {
                System.out.println(rs.getString("name"));
            }
        } catch (SQLException e1) {
            e1.printStackTrace();
        } finally {
            jdbcUtils.release(conn, st, rs);
        }

    }
}

6. 使用 IDEA 连接数据库

  1. 连接数据库
    在这里插入图片描述
    在这里插入图片描述2. 选择数据库
    在这里插入图片描述3. 操作数据库
    在这里插入图片描述
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值