JDBC学习总结

1、JDBC概念:

使用Java语言操作关系型数据库的一套API(Java database connectivity Java连接数据库);jdbc本质上是sun公司定义的一套操作所有关系型数据库的规则接口,各个数据库厂商实现这套接口,提供数据库驱动的jar包,我们使用这套接口进行编程,真正执行的代码是驱动jar包中的实现类。

JDBC好处:各个数据库厂商使用相同的接口,Java代码不需要针对不同的数据库进行开发,可以随时替换底层数据库,访问数据库的Java代码基本不变。

 2、JDBC的步骤

  1. 创建工程,导入驱动jar包 mysql-connector-java-5.1.44.jar
  2. 注册驱动   Class.forName("com.mysql.jdbc.Driver");
  3. 获取连接  Connection connection = DriverManager.getConnection(url, username, password);
  4. 定义SQL语句
  5. 获取SQL执行对象
  6. 执行SQL
  7. 处理返回结果
  8. 释放资源
public class JDBCDemo {
    public static void main(String[] args) throws Exception {
        // 1 注册驱动  mysql5以后可以省略这一步
        Class.forName("com.mysql.jdbc.Driver");
        // 2 获取连接
        String url = "jdbc:mysql://127.0.0.1:3306/db1";
        String username = "root";
        String password = "123456";
        Connection connection = DriverManager.getConnection(url, username, password);

        // 3 定义SQL语句
        String sql = "update account  set money = 3000 where id = 1";

        // 4,获取执行sql的对象 statement
        Statement statement = connection.createStatement();

        // 5 执行sql语句
        int i = statement.executeUpdate(sql); // 返回值为受影响的行数

        // 6 处理结果
        System.out.println(i);

        // 7 释放资源
        statement.close();
        connection.close();
    }
}

 执行后     

3、JDBC中的一些API

3.1、DriverManager驱动管理类:注册驱动和获取数据库的连接

1、DriverManager.registerDriver(new Driver()); 此方法注册驱动
Class.forName("com.mysql.jdbc.Driver");

源码:

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

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

mysql 5 之后驱动包可以省略注册驱动的步骤

自动加载jar包中META-INF\services\java.sql.Driver 文件中的驱动类

2、DriverManager.getConnection(url, username, password); 此方法获取连接

参数:

  1. url: 连接路径
    1. 语法:jdbc:mysql://ip:port/数据库名称?参数键值对1&参数键值对2...
    2. 例子:jdbc:mysql://127.0.0.1:3306/db1
    3. 细节:如果连接的是本机的mysql并且默认端口为3306,可以简写为jdbc:mysql:///数据库名称?参数键值对1&参数键值对2...
    4. useSSL=false是禁用安全连接,可以解决警告提示:jdbc:mysql://127.0.0.1:3306/db1?useSSL=false
  2. username:连接数据库的用户名
  3. password:连接数据库的密码

3.2、Connection 数据库连接对象 :获取执行SQL的对象 和 管理事务

1、获取执行SQL的对象

  • 普通执行SQL对象  Statement  creatStatement()
  • 预编译SQL的执行对象 PreparedStatement    prepareCreatStatement()

2、事务管理

  • MySQL中的事务管理
    • 开启事务:BEGIN; /STSRT TRANSACTION;
    • 提交事务: COMMIT;  mysql默认提交事务
    • 回滚事务:ROLLBACK;
  • JDBC中的事务管理: Connection接口中定义了三个对应的方法
    • 开启事务:setAutoCommit(boolean autoCommit ) true自动提交事务,false手动提交事务,即为开启事务
    • 提交事务:commit();
    • 回滚事务:rollback();
public class JDBCDemo02_connection {
    public static void main(String[] args) throws Exception {
        // 1 注册驱动
        // Class.forName("com.mysql.jdbc.Driver");
        // 2 获取连接
        String url = "jdbc:mysql://127.0.0.1:3306/db1";
        String username = "root";
        String password = "123456";
        Connection connection = DriverManager.getConnection(url, username, password);

        // 3 定义SQL语句
        String sql1 = "update account  set money = 3000 where id = 1";
        String sql2 = "update account  set money = 3000 where id = 2";

        // 4,获取执行sql的对象 statement
        Statement statement = connection.createStatement();

        try {
            // 开启事务
            connection.setAutoCommit(false);

            // 5 执行sql语句
            int i1 = statement.executeUpdate(sql1); // 返回值为受影响的行数
            // 6 处理结果
            System.out.println(i1);

            // 5 执行sql语句
            int i2 = statement.executeUpdate(sql2); // 返回值为受影响的行数
            // 6 处理结果
            System.out.println(i2);
            // 提交事务
            connection.commit();
        } catch (SQLException throwables) {
            // 异常后回滚事务
            connection.rollback();
            throwables.printStackTrace();
        }

        // 7 释放资源
        statement.close();
        connection.close();
    }
}

3.3、Statement:执行SQL语句

1、executeUpdate(String sql) 执行DML,DDL语句

返回值:1、DML语句影响的行数;2、DDL语句执行后,执行成功也可能返回0

2、executeQuery(String sql) 执行DQL语句

返回值:ResultSet结果集

3.4、ResultSet 结果集对象:封装了DQL查询语句 的结果

获取查询结果:

boolean   next(): 

将游标从当前行的位置向下移动一行,并判断当前行是否为有效行。

返回值:true 有效行,当前行有数据,false:无效行,当前行没有数据

getXxx(参数) : 获取数据   

Xxx:数据类型

参数: int:列的编号,从1开始    String:列的名称

public class JDBCDemo04_resultset {
    public static void main(String[] args) throws Exception {
        // 1 注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        // 2 获取连接
        String url = "jdbc:mysql://127.0.0.1:3306/db1";
        String username = "root";
        String password = "123456";
        Connection connection = DriverManager.getConnection(url, username, password);

        // 3 定义SQL语句
        String sql = "select * from account";

        // 4,获取执行sql的对象 statement
        Statement statement = connection.createStatement();

        // 5 执行sql语句
        ResultSet resultSet = statement.executeQuery(sql);

        // 6 处理结果
        while (resultSet.next()) { //光标下移一行,判断是否有数据
            int id = resultSet.getInt(3); // 可以写数字,代表列
            String name = resultSet.getString(1); // 可以写列的属性名称
            Double money = resultSet.getDouble(2);

            System.out.println(id);
            System.out.println(name);
            System.out.println(money);
            System.out.println("-------------");
        }

        // 7 释放资源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

1
张三
3000.0
-------------
2
李四
3000.0
-------------
        // 6 处理结果封装成集合对象
        List<Account> accountList = new ArrayList<>();
        while (resultSet.next()) { //光标下移一行,判断是否有数据
            int id = resultSet.getInt(3);
            String name = resultSet.getString(1);
            Double money = resultSet.getDouble(2);

            Account account = new Account();
            account.setId(id);
            account.setMoney(money);
            account.setName(name);
            accountList.add(account);
        }
        // 存入集合
        System.out.println(accountList.toString());

3.5、PreparedStatement :防止SQL注入

SQL注入问题的发生:

        // 接收用户输入的用户名和密码
        String loginName = "zhangsan";
        String loginPwd = "' or '1'='1";

        // 3 定义SQL语句
        String sql = "select *  from tb_user where username = '" + loginName+"' and password = '" + loginPwd + "'";

        // 4,获取执行sql的对象 statement  -->存在SQL注入
        // select *  from tb_user where username = 'zhangsan' and password = '' or '1'='1'
        Statement statement = connection.createStatement();

PreparedStatement的使用

1、sql语句加?占位符

2、获取preparedStatement对象,并传入sql

3、给占位符赋值

4、执行sql

        String sql = "select *  from tb_user where username = ? and password = ?";

        // 获取preparedStatement对象
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        // 给SQL的占位符设置值
        preparedStatement.setString(1, loginName);
        preparedStatement.setString(2, loginPwd);

        // 不需要在传入SQL了
        ResultSet resultSet = preparedStatement.executeQuery();

PreparedStatement的原理

好处:

  • 预编译SQL,性能更高(要在url里面设置 useSeverPrepStmts = true 才能开启预编译功能,这个是默认关闭的)
  • 防止SQL注入,原理在获取preparedStatement对象的时候,将sql语句发送给mysql服务器进行检查和编译,执行的时候就不需要进行编译了,其实就是将敏感字符进行转义

4、数据库连接池

数据库连接池是个容器,负责分配和管理数据库连接

允许应用程序重复使用一个现有的数据库连接,而不是不断的重新建立

释放“空闲时间超过最大空闲时间”的数据库连接来避免因为没有释放数据库连接而引起的数据量连接遗漏

好处:资源复用,提升系统响应速度(避免每次申请数据库连接),避免数据库连接遗漏

 5、数据库连接池的实现

标准接口:DataSource

  • 官方(sun)提供的数据库连接池的标准接口,由第三方组织实现此接口
  • 功能就是获取连接,因此就不需要用DriverManager来获取连接了
  • Druid(德鲁伊)连接池:阿里巴巴开源的数据库连接池。

Druid(德鲁伊)连接池的使用步骤:

1、导入jar包,durid-1.1.12.jar

2、定义配置文件

3、加载配置文件

4、获取数据库连接池对象

5、获取连接

配置文件 xxx.properties

driverClassName=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/db1
username=root
password=123456

#初始化连接数量
initialSize=10
#最大连接数量 
maxActive=20
#最大等待时间
maxWait=1000

 ​​​​​​

6、JDBC相关面试题

1.execute,executeQuery,executeUpdate的区别是什么?

a、Statement的execute(String query)方法用来执行任意的SQL查询,如果查询的结果是一个ResultSet,这个方法就返回true。如果结果不是ResultSet,比如insert或者update查询,它就会返回false。
b、Statement的executeQuery(String query)接口用来执行select查询,并且返回ResultSet。即使查询不到记录返回的ResultSet也不会为null。我们通常使用executeQuery来执行查询语句,这样的话如果传进来的是insert或者update语句的 话,它会抛出错误信息为 “executeQuery method can not be used for update”的java.util.SQLException。
c、Statement的executeUpdate(String query)方法用来执行insert或者update/delete(DML)语句。
d、只有当你不确定是什么语句的时候才应该使用execute()方法,否则应该使用executeQuery或者executeUpdate方法

2.JDBC的PreparedStatement是什么?

PreparedStatement对象代表的是一个预编译的SQL语句。用它提供的setter方法可以传入查询的变量。由于PreparedStatement是预编译的,通过它可以将对应的SQL语句高效的执行多次。
由于PreparedStatement自动对特殊字符转义,避免了SQL注入攻击,因此应当尽量的使用它。

3.JDBC的ResultSet是什么?

在查询数据库后会返回一个ResultSet,它就像是查询结果集的一张数据表。ResultSet对象维护了一个游标,指向当前的数据行。开始的时候这个游标指向的是第一行。如果调用了ResultSet的next()方法游标会下移一行,如果没有更多的数据了, next()方法会返回false。可以用while循环遍历数据集。

4、什么是数据库连接池?为什么要用数据库连接池?

数据库连接是一种关键的有限的昂贵的资源,对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序 的性能指标。数据库连接池正是针对这个问题提出来的。
数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。这项技术能明显提高对数据库操作的性能。
数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数来设定的。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的最大数据库连接数量限定了这个连接池能占有的最大连接数,当应用程序向连接池请求的连接数超过最大连接数量时,这些请求将被加入到等待队列中。

5、说说事务的概念,JDBC中如何处理事务?

事务是作为单个逻辑工作单元执行的一系列操作,一个逻辑工作单元必须有四个属性,称为原子性、一致性、隔离性和持久性(ACID) 属性,只有这样才能成为一个事务 。JDBC处理事务有如下操作:
conn.setAutoComit(false);设置提交方式为手工提交。
conn.commit()提交事务。
conn.rollback(),回滚。
提交与回滚只选择一个执行。正常情况下提交事务,如果出现异常,则回滚。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值