JDBC--通过Java来访问MySQL数据库

本文详细介绍了Java数据库连接(JDBC)的使用,包括加载驱动、获取连接、执行SQL语句及事务管理。通过示例展示了如何进行数据插入,并强调了PreparedStatement相对于Statement的优势,能防止SQL注入并提高效率。此外,提到了连接池的概念,以Druid连接池为例,解释了其优化数据库连接创建和释放的过程,旨在提升应用性能。
摘要由CSDN通过智能技术生成

JDBC

概述

JDBC: Java DataBase Connectivity---- java数据库的连接

是一种专门用于执行SQL语句的Java API,可以为多种关系数据库提供统一的访问,它由一组用Java语言编写的接口组成

java代码要想操作各种数据库就得使用JDBC,这是规范

JDBC的由来

JDBC规范定义接口,具体的实现由各大数据库厂商来实现 ,JDBC是Java访问数据库的标准规范。真正怎么操作
数据库还需要具体的实现类,也就是数据库驱动(第三方JAR包)。每个数据库厂商根据自家数据库方式编写好自己数据库的驱动。所以我们只需要会调用JDBC接口中的方法即可。数据库驱动由数据库厂商提供。

我们在用java代码操作数据库时只需要会使用JDBC接口中的方法即可

入门案例-使用java代码对数据库进行数据插入

前提:操作哪个数据库就需要导入哪个数据库的驱动包

jdbc的使用步骤:

1.加载驱动

2.获取连接

3.获取语句的执行者

4.编写sql

5.执行sql语句

6.释放资源

@Test
    public void test1() throws SQLException {
        // 使用java代码调用jdbc提供的api操作数据库的数据
        // 前提:操作那个数据库就需要导入哪个数据库的驱动

        // 1 加载驱动
        DriverManager.registerDriver(new Driver());

        // 2 获取mysql数据库的连接
        String url="jdbc:mysql://localhost:3306/db1";
        String username="root";
        String password="root";
        Connection connection = DriverManager.getConnection(url, username, password);

        // 3 获取操作数据库sql语句的对象
        Statement statement = connection.createStatement();

        // 4 编写sql语句
        String sql="insert into category values(null,'床上用品2')";

        // 5 执行sql语句   i:数据库受影响的数据条数
        int i = statement.executeUpdate(sql);
        System.out.println(i);

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

    }

JDBC API详解

DriverManager:类

1 加载驱动 用反射代替了
2 获取数据库连接的对象	

方法作用:

1 加载驱动

static void registerDriver(Driver driver) 实际开发中不会选择 因为加载了2次驱动

​ 代替者:Class.forName(Driver的全限定名) 反射方式 加载一次驱动 适用开发

2 获取数据库连接的对象

static Connection getConnection(String url, String user, String password);

Url:数据库的地址 固定格式:jdbc:要连接的数据库://数据库地址:端口号/哪个数据库

user:数据库的用户名

Password:数据库的密码

如果数据出现乱码需要加上参数: ?characterEncoding=utf8,表示让数据库以UTF-8编码来处理数据。 如:

jdbc:要连的数据库://数据库地址:端口号/哪个数据库?characterEncoding=utf8

Connection:接口

1 可以获取执行SQL语句的对象(语句执行者)
2 可以做事务

方法作用:

1 可以获取执行SQL语句的对象(语句执行者)

Statement createStatement();获取语句的执行者

2 操作事务

void setAutoCommit(boolean autoCommit) ; --start transaction;
false:开启事务, ture:关闭事务(默认)

void commit(); —commit;
提交事务

void rollback(); —rollback;
回滚事务

Statement:接口

执行sql语句

方法作用:

1 执行sql语句

executeUpdate() 执行的是增删改语句

返回值是int类型 代表受影响的行数

executeQuery() 执行的是查询语句

返回的值是ResultSet类型对象 称为:结果集对象

Resultset:接口

方法作用:

1 封装查询语句的结果集

next() 可以让指针向下移动一行 默认在第一行之前 返回值是boolean true:代表有数据 false: 代表没数据

2 获取结果集中每一行的数据

get类型(int 列的位置)

get类型(String 列名)

编写JDBC的工具类实现数据的增删改查

工具类:可以将一些重复的代码进行抽取封装,以便于复用,简化代码开发

通过上面代码的编写会发现每次去执行SQL语句都需要注册驱动,获取连接,以及释放资源。
发现很多重复的劳动,我们可以将重复的代码抽取出来定义一个工具类,直接调用方法,可以简化代码。

那么我们接下来定义一个JDBCUtils 类。把注册驱动,获取连接,以及释放资源的代码放到这个类的方法
中。以后直接调用该工具类的方法即可。

JDBC操作事务

Connection:	
	void setAutoCommit(boolean autoCommit) ;
	false:开启事务 ture:关闭事务(默认的)
	void commit();
	提交事务
	void rollback();
	回滚事务

ps:在使用手动事务时,必须要抓取异常,catch块中进行回滚事务.
   只要有事务,就必须try,catch捕捉处理  查询有没有事务都行

模拟用户登录功能

需求:
	输入用户名和密码后,获取输入的值,使用jdbc操作数据库,完成登录功能.
    找到了:登录成功   找不到:用户名或密码错误  
技术分析:
	jdbc
创建用户表:
    create table user (
      id int primary key auto_increment,
      name varchar(20),
      password varchar(20)
  );
  insert into user values(null,"jack","123");

问题:使用Statement对象来操作sql语句会有缺陷:会造成数据的安全隐患

相当于注释掉了密码的校验,这种安全隐患我们称为:Sql注入

Sql注入:将用户输入的内容 作为了sql语句的一部分 改变了原有sql语句的结构含义

比如登录中的sql拼接:select * from user where username=‘jack’ #’ and password=‘123’;

Statement编译对象:拼接什么样的sql就执行什么样的sql语句

解决:就不能使用当前的Statement对象来操作SQL语句了,得使用另一个对象–preparedStatement对象

PreparedStatement: 预编译对象

作用:也是用来执行sql语句的

语句执行者:Statement编译对象 preparedStatement预编译对象

区别:

Statement编译对象是有什么样的sql就执行什么样的sql语句,每次执行任何一条sql语句都得让数据库去编译执行 如果执行一万条同样的查询语句 数据库要编译一万次 效率低

preparedStatement预编译对象是先将sql格式传递给数据库做预编译 其后拿着预编译结果传递参数执行sql,执行一万条同样的查询语句 数据库只编译一次 根据不同的参数做不用的执行

预编译PreparedStatement的好处:

1 只需要编译一次,效率高

2 能让数据库提前知晓要执行的sql语句格式,只负责给数据库传参即可

语法格式:

Statement编译对象: select * from 表 where 字段1=值1 and 字段2=值2;

preparedStatement:select * from 表 where name=? and password=?;

?:占位符 所有的实际参数都用占位符替换了 不在是直接设值了
通过外部方法来设置实际参数的值:set字段类型(占位符的序号,要设置的值);
占位符的序号是从1开始的 
setString(1,"jack");
setString(2,"123");

preparedStatement对象操作数据库的增删改查

使用步骤:

1.编写sql
String sql = "insert into user values(null,?,?..) ";
2.创建预编译对象–提前编译sql语句
​ PreparedStatement pst = conn.preparedStatement(sql);
3.设置具体的参数
​ pst.set字段类型(int a,值);
​ a: 第几个 ? (占位符) 默认从左向右第1个开始
4.执行sql即可
​ ResultSet rs = pst.executeQuery(); // 执行查询,返回 resultSet
​ int i = pst.executeUpdate(); // 执行 增 删 改 返回的是影响的行数

连接池(数据源)

连接池:存放数据库连接的容器(集合)

连接池出现的目的

之前在使用jdbc操作数据库数据的时候,有一个步骤是获取连接(创建连接)
连接用完,还需要释放连接(销毁连接),这2个步骤太消耗资源了
连接池就是用来优化jdbc的2个步骤的
		   1 优化的是jdbc的创建连接部分
		   1 优化的是jdbc的销毁连接部分

连接池优化原理

在连接池一初始话的时候,就在容器中创建一定量的连接
当用户要连数据库的时候,就从容器中拿一个连接使用
使用完毕之后,不再是销毁,而是把使用后的连接还放回容器 供下一个用户去循环使用

在企业中使用的都是已经成熟并且性能很高的提供好的连接池

常见的连接池:

在这里插入图片描述

druid连接池的使用

导入druid连接池的jar包

 @Test
    public void test2() throws Exception {
        // 创建一个配置文件对象
        Properties properties = new Properties();
        // 获取文件流  DruidTest.class.getResourceAsStream获取的是classess文件的路径  返回流
        InputStream is = DruidTest.class.getResourceAsStream("/druid.properties");
        // 配置文件对象加载配置文件
        properties.load(is);
        // 创建druid的连接
        DataSource ds = DruidDataSourceFactory.createDataSource(properties);
        // 获取连接
        Connection connection = ds.getConnection();

        String sql="select * from user";
        PreparedStatement preparedStatement = connection.prepareStatement(sql);
        ResultSet resultSet = preparedStatement.executeQuery();
        while (resultSet.next()){
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String password = resultSet.getString("password");
            System.out.println(id+":"+name+":"+password);
        }

        // 归还连接
        JDBCUtils.close(resultSet,preparedStatement,connection);
    }

总结:

java代码操作数据库(围绕点)
桥梁:java提供的jdbc规范
jdbc规范:里面都是大量的接口,实现都有数据库的生产商提供,所以使用jdbc操作哪个数据库就得导入对应的驱动包

JDBC的API:
DriverManager:1 加载驱动 但是我们不用 因为加载了2次  使用的是反射的方式
2 获取连接对象  Connection
Connection:接口
1 获取执行sql语句的对象(语句执行者) 
  statement编译对象(不建议使用的)
  		  执行的sql语句值是固定打的,执行一次编译一次,效率低 还容易造成sql注入的数据安全问题
  preparedStatement预编译对象
  	      执行的sql语句值是由占位符替代,执行多次只编译一次 效率高 
  	      会提前对sql语句进行预编译 能够保证数据的安全问题 不会引发sql注入
2 操作事务(将数据库的自动提交变成手动提交)
	      使用了事务,一定要trycatch  一般用于2条或2条以上的sql语句同时执行  多条查询可写可不写事务
	      
statement/preparedStatement:接口
1 执行sql语句
  statement编译对象:
  executeUpdate(sql) 增删改    返回的是int类型 代表受影响的条数
  executeQuery(sql) 查询  返回的是ResultSet结果集对象
  preparedStatement预编译对象:
  executeUpdate() 增删改    返回的是int类型 代表受影响的条数
  executeQuery()   查询  返回的是ResultSet结果集对象
  
ResultSet结果集:接口
1 用来存储查询的结果
	 使用:
	 next()  移动到下一行数据
     返回的是boolean类型  true 有值   false 无值
     获取数据:
     get字段类型(列的位置)
     get字段类型(列的名称)
     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值