首页 > 其他分享 >JDBC(重点)

JDBC(重点)

时间:2024-08-01 14:18:53浏览次数:12  
标签:JDBC String rs sql null 重点 public conn

JDBC(重点)

数据库驱动

JDBC

SUN公司为了简化 开发人员的(对数据库的同一)操作,提供了一个(Java操作数据库的)规范,俗称JDBC

这些规范的实现由具体的厂商去做

对于开发人员来说,我们只需要掌握JDBC接口的操作即可

java.sql

javax.sql

还需要导入一个数据库驱动包

第一个JDBC程序

  • 创建普通项目

  • 导入数据库驱动

  • 编写代码

    package com.gs.lesson;
    
    import com.mysql.jdbc.Driver;
    
    import java.sql.*;
    
    /**
     * @version: java version 1.8
     * @author: 14
     * @description:
     */
    public class JdbcFisrstDemo {
        public static void main(String[] args) throws ClassNotFoundException, SQLException {
            // 1、加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            // 2、用户信息和url
            String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false";
            String username = "root";
            String password = "123456";
            // 3、连接成功,返回数据库对象
            Connection connection = DriverManager.getConnection(url, username, password);
    
            // 4、执行sql的对象
            Statement statement = connection.createStatement();
            // 5、执行sql的对象 去执行 sql,可能存在结果,查看返回结果
            String sql = "select * from users";
            ResultSet resultSet = statement.executeQuery(sql);// 返回的结果集,封装了全部的查询结果
            while (resultSet.next()) {
                System.out.println("id:" + resultSet.getObject("id"));
                System.out.println("name:" + resultSet.getObject("name"));
                System.out.println("pwd:" + resultSet.getObject("password"));
                System.out.println("email:" + resultSet.getObject("email"));
                System.out.println("birth:" + resultSet.getObject("birthday"));
            }
            // 6、释放连接
            resultSet.close();
            statement.close();
            connection.close();
        }
    }
    

步骤总结:

  • 加载驱动
  • 连接数据库 DriverManager
  • 获得执行sql的对象 Statement
  • 获得返回的结果集
  • 释放连接

DriverManager

//DriverManager.registerDriver(new Driver());
Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动

Connection connection = DriverManager.getConnection(url, username, password);
//connection 代表数据库
//数据库设置自动提交
//事务提交
//事务回滚
connection.setAutoCommit();
connection.commint();
connection.rollback();

URL

String url = "jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false";

//mysql --- 3306
//jdbc:mysql://主机地址:端口号/数据库名?参数1&参数2&参数3
//oralce --- 1521
//jdbc:oracle:thin:@localhost:1521:sid

Statement | PrepareStatement 执行sql的对象

String sql = "select * from users" //编写sql

statement.executeQuery();//查询操作 返回ResultSet
statement.execute();//执行任何SQL
statement.executeUpdate();//更新、插入、删除 都是用这个, 返回一个受影响的行数

ResultSet 查询的结果集:封装了所有的查询结果

获得指定的数据类型

resultSet.getObject();// 在不指定列类型的情况下使用
 // 如果知道列类型就使用指定类型
resultSet.getString();
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();

遍历,指针

resultSet.beforeFirst();//移动到最前面
resultSet.afterLast();//移动到最后面
resultSet.next();//移动到下一个
resultSet.previous();//移动到前一行
resultSet.absolute();//移动到指定行

释放资源

// 6、释放连接
resultSet.close();
statement.close();
connection.close();// 消耗资源,用完关掉

statement对象

代码实现

1、提取工具类

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.properties");
            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 stmt, ResultSet rs) {
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (stmt != null) {
            try {
                stmt.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
    }
}

2、编写增删改的方法 executeUpdate

public class TestInsert {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection(); //获取数据库连接
            stmt = conn.createStatement(); //获得sql的执行对象
            String sql = "INSERT INTO users(ID,NAME,PASSWORD,EMAIL,BIRTHDAY)"+
                    "VALUES(4,'KUANGSHEN','123456','[email protected]','2025-1-1')";
            int i  = stmt.executeUpdate(sql);
            if (i > 0){
                System.out.println("插入成功");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
}
public class TestDelete {
    public static void main(String[] args) {
        Connection conn = null;
        Statement stmt = null;

        try {
            conn = JdbcUtils.getConnection();
            stmt = conn.createStatement();
            String sql = "delete from users where id=4";
            int i = stmt.executeUpdate(sql);
            if ( i > 0){
                System.out.println("删除成功");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn,stmt,null);
        }
    }
}
public class TestUpdate {
    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        Statement stmt = null;

        try {
            conn = JdbcUtils.getConnection();
            stmt = conn.createStatement();
            String sql = "UPDATE users SET name= 'kuangshen' ,email = '[email protected]' where id = 1";
            int i = stmt.executeUpdate(sql);
            if (i > 0) {
                System.out.println("修改成功");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn, stmt, null);
        }
    }
}

3、查询execuQuery

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

        try {
            conn = JdbcUtils.getConnection();
            stmt = conn.createStatement();
            //SQL
            String sql = "select * from users where id = 1";
            rs = stmt.executeQuery(sql);
            while (rs.next()) {
                System.out.println(rs.getString("name"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
}

SQL注入的问题

sql存在漏洞,会被攻击导致数据泄露 SQL会被拼接 or

public class SQL注入 {
    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 stmt = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();
            stmt = conn.createStatement();
            String sql = "select * from users where name = '"+username+"' and password = '"+password+"'";
            rs = stmt.executeQuery(sql);
            while(rs.next()){
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("password"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
}

PreparedStatement

PreparedStatement 可以防止SQL注入,并且效率更高

1、新增

public class TestInsert {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection(); //获取数据库连接

            //区别
            //使用?占位符 代替参数

            String sql = "INSERT INTO users(ID,NAME,PASSWORD,EMAIL,BIRTHDAY)"+
                    "VALUES(?,?,?,?,?)";
            ps = conn.prepareStatement(sql);//预编译SQL,先写sql,然后不执行

            //手动给参数赋值
            ps.setInt(1,6);
            ps.setString(2,"shisi");
            ps.setString(3,"123456");
            ps.setString(4,"[email protected]");
            //注意点:sql.Date   数据库   java.sql.Date
            //       util.Date   java   new Date().getTime() 获得时间戳
            ps.setDate(5, new java.sql.Date(new Date().getTime()));

            //执行
            int i = ps.executeUpdate();
            if (i > 0) {
                System.out.println("插入成功");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn, ps, rs);
        }
    }
}

2、删除

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

        try {
            conn = JdbcUtils.getConnection();

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

            ps = conn.prepareStatement(sql);
            ps.setInt(1, 5);
            int i = ps.executeUpdate();
            if ( i > 0){
                System.out.println("删除成功");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn,ps,null);
        }
    }
}

3、更新

public class TestUpdate {
    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        PreparedStatement ps = null;

        try {
            conn = JdbcUtils.getConnection();
            String sql = "UPDATE users SET name=?  where id =?";

            ps = conn.prepareStatement(sql);

            ps.setString(1, "kuangshen");
            ps.setInt(2, 5);

            int i = ps.executeUpdate();
            if (i > 0) {
                System.out.println("修改成功");
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn, ps, null);
        }
    }
}

4、查询

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

        try {
            conn = JdbcUtils.getConnection();
            //SQL
            String sql = "select * from users where id =?";

            ps = conn.prepareStatement(sql);
            ps.setInt(1, 6);//传递参数
            rs = ps.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getString("name"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(conn, ps, rs);
        }
    }
}

5、防止SQL注入

public class SQL注入 {
    public static void main(String[] args) {

        login("' or'1=1","' or'1=1");
    }

    public static void login(String username, String password){
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;

        try {
            conn = JdbcUtils.getConnection();
            //PreparedStatement 防止SQL注入的本质,把传递进来的参数当做字符串
            // 假设其中存在转义字符,直接忽略,比如说'
            String sql = "select * from users where name = ? and password = ?";
            stmt = conn.prepareStatement(sql);
            stmt.setString(1, username);
            stmt.setString(2, password);
            rs = stmt.executeQuery();
            while(rs.next()){
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("password"));
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JdbcUtils.release(conn, stmt, rs);
        }
    }
}

使用IDEA连接数据库

事务

代码实现

1、关闭自动提交,开启事务conn.setAutoCommit(false);

2、一组事务执行完毕,提交事务

3、可以在catch语句中显式的定义 回滚语句,但默认失败就会回滚

public class 事务 {
    public static void main(String[] args) {
        Connection con = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            con = JdbcUtils.getConnection();

            con.setAutoCommit(false);// 关闭自动提交,开启事务

            String sql = "UPDATE account SET money = money - 100 where name = 'A'";
            ps = con.prepareStatement(sql);
            ps.executeUpdate();

            //int i = 1/0; // 让 事务 不能完成

            sql = "UPDATE account SET money = money + 100 where name = 'B'";
            ps = con.prepareStatement(sql);
            ps.executeUpdate();

            con.commit();// 业务完成 提交
        }catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JdbcUtils.release(con, ps, rs);
        }
    }
}

数据库连接池

数据库连接 ---- 执行完毕 ---- 释放

连接 ---- 释放 十分浪费系统资源

池化技术:准备一些预先的资源,过来就连接预先准备好的

----- 开门 ------ 业务员:等待 ------ 服务 ------

若 常用连接数:10个

​ 最小连接数:10个

​ 最大连接数:15个 业务最高承载上限

​ 等待超时:100ms

编写连接池,实现一个接口 DataSource

开源数据源实现

DBCP

C3P0

Druid:阿里巴巴

使用了这些数据库连接池后,在项目开发中就不需要编写连接数据库的代码了

DBCP

需要的jar包

commons-dbcp-1,4.jar commons-pool-1.6.jar

工具类

public class JdbcUtils_DBCP {

    private static DataSource dataSource = null;

    static {
        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");
            Properties properties = new Properties();
            properties.load(in);

            //创建数据源 工厂模式  --->创建
            dataSource = BasicDataSourceFactory.createDataSource(properties);

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //获取连接资源
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();//从数据源中获取连接
    }

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

配置文件

#连接设置
driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=123456

#<!-- 初始化连接 -->
initialSize=10

#最大连接数量
maxActive=50

#<!-- 最大空闲连接 -->
maxIdle=20

#<!-- 最小空闲连接 -->
minIdle=5

#<!-- 超时等待时间以毫秒为单位 6000毫秒/1000等于60秒 -->
maxWait=60000
#JDBC驱动建立连接时附带的连接属性属性的格式必须为这样:【属性名=property;】
#注意:"user" 与 "password" 两个属性会被明确地传递,因此这里不需要包含他们。
connectionProperties=useUnicode=true;characterEncoding=UTF8

#指定由连接池所创建的连接的自动提交(auto-commit)状态。
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读(read-only)状态。
#如果没有设置该值,则“setReadOnly”方法将不被调用。(某些驱动并不支持只读模式,如:Informix)
defaultReadOnly=

#driver default 指定由连接池所创建的连接的事务级别(TransactionIsolation)。
#可用值为下列之一:(详情可见javadoc。)NONE,READ_UNCOMMITTED, READ_COMMITTED, REPEATABLE_READ, SERIALIZABLE
defaultTransactionIsolation=READ_UNCOMMITTED

C3P0

需要的jar包

c3p0-0.9.5.5.jar 、mchange-commons-java-0.2.19.jar

工具类

public class JdbcUtils_C3P0 {

    private static DataSource dataSource = null;

    static {
        try {
            //创建数据源 工厂模式  --->创建
            dataSource = new ComboPooledDataSource("MySQL");//配置文件写法

        }catch (Exception e){
            e.printStackTrace();
        }
    }

    //获取连接资源
    public static Connection getConnection() throws SQLException {
        return dataSource.getConnection();//从数据源中获取连接
    }

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

配置文件

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <!--
c3p0的缺省(默认)配置
如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource();"这样写就表示使用的是c3p0的缺省(默认)-->
    <default-config>
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&amp;characterEncoding=utf8&amp;uesSSL=true&amp;serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquiredIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    <!--如果在代码中"ComboPooledDataSource ds=new ComboPooledDataSource("MySQL");"这样写就表示使用的是name是MySQL的配置-->
    <named-config name="MySQL">
        <property name="driverClass">com.mysql.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&amp;characterEncoding=utf8&amp;uesSSL=true&amp;serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquiredIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>
</c3p0-config>

结论

无论使用什么数据源,本质还是一样的,DataSource接口不会变,方法也不会变

标签:JDBC,String,rs,sql,null,重点,public,conn
From: https://www.cnblogs.com/shisi2001/p/18336578

相关文章

  • jdbc
    1.添加依赖(因为创建的是maven项目所以不用去创建lib目录去导入包了方便)点击查看代码<dependencies><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>5.1.47&l......
  • JdbcTemplate
    JdbcTemplate是Spring框架提供的一个用于简化JDBC操作的类。它处理了资源的创建和释放,使得开发者能够更专注于SQL语句本身和结果的处理。JdbcTemplate提供了大量的方法,用于执行各种类型的SQL语句,包括查询、更新、批处理、调用存储过程等。导入jar包<depende......
  • 矩阵论重点总结
    矩阵论第一章线性空间和线性变换线性空间的基与维数线性空间:加法和数乘的封闭性+8条规则基底:一组线性无关的向量,且其他元素可以由它们线性表出维数:基底向量的个数子空间生成子空间交子空间:$V_1\capV_2$和子空间:$V_1+V_2$维数定理:$dimV_1+dimV_2=dimV_......
  • sharding-jdbc 兼容 MybatisPlus的动态数据源
    背景:之前的项目做读写分离的时候用的MybatisPlus的动态数据做的,很多地方使用的@DS直接指定的读库或者写库实现的业务;随着表数据量越来越大,现在打算把比较大的表进行水平拆分,准备使用ShardingJDBC实现,但是发现两者配合起来并不是那么顺利,网上大部分文章都是直接把整个Sharding的......
  • GBase8c使用JDBC获取游标类型数据
    GBase8c使用JDBC获取游标类型数据JDBC游标GBase8c当JDBC遇到cursor时,如何处理?使用jdbc访问GBase8c数据库里的cursor游标数据,可以通过下面用例获取游标数据。一、创建自定义函数CREATEORREPLACEFUNCTIONget_users()RETURNSrefcursorAS$$DECLAREresult_c......
  • 一篇学会JDBC的使用。
    目录一、基础篇1.1概念1.2快速入门1.3核心API讲解1.4基于PreparedStatement实现CRUD(创建,读取,更新,删除四种操作)1.4.1查询1.4.1增,删,改二、进阶篇2.1jdbc扩展2.2主键回显2.3连接池(Druid为例)2.4properties集合三、高级篇3.1jdbc工具类封装3.2Dao层......
  • 3、集成Mybatis框架、JDBC、mybatis-plus
    简化代码加入lombok依赖<dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId></dependency> 1、pom.xml添加jdbc、mysql驱动、mybatis框架、mybatis-plus<dependency><groupId>org.sprin......
  • 【YashanDb知识库】YashanDB的JDBC/OCI驱动如何设置字符编码
    问题现象Oracle、Mysql数据库链接串,JDBC驱动连接串可以指定客户端的编码格式:jdbc:mysql://hostname:port/database_name?useUnicode=true&characterEncoding=utf8mb4jdbc:oracle:thin:@//hostname:port/service_name?NLS_LANGUAGE=AMERICAN&NLS_TERRITORY=AMERICA&NLS_CHARACTE......
  • 求教Postgresql在jdbc处理bit(1)字段的预处理解决方案
    文章目录1.建表语句:2.使用以下方式的预处理方式都报错了3.可以先用sql拼接实现功能1.建表语句:CREATETABLEpublic.h_user( idserial4notnull, usernamevarchar(50)NULL, "password"varchar(64)NULL, nicknamevarchar(60)NULL, emailvarchar(255)N......
  • 【YashanDB数据库】yasdb jdbc驱动集成druid连接池,业务(java)日志中有token IDENTIFIE
    问题现象客户的java日志中有如下异常信息:问题的风险及影响对正常的业务流程无影响,但是影响druid的mergesql功能(此功能会将sql语句中的字面量替换为绑定变量,然后将替换以后的sql视为同一个,然后用做执行性能统计)问题影响的版本与yashandb版本无关问题发生原因druid源码中在......