JDBC (Java DataBase Connectivity)

JDBC (Java DataBase Connectivity)

JDBC的概念:

  • JDBC(Java DataBase Connectivity:java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系型数据库提供统一访问,它是由一组用Java语言编写的类和接口组成的。
  • JDBC的作用:可以通过java代码操作数据库

提供者:数据库厂商

是Java提供的、连接不同数据库的驱动

DriverManager类


提供者:Sun公司

作用:一依据数据库的不同,来管理JDBC驱动

获取驱动:

在JDBC的Driver中有一行源代码如下:

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

调用了Java.sql包下的DriverManager的registerDriver方法,注册了一个驱动

我们也可以使用Java的反射来将Driver来引入项目:

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

Connection接口


是Java程序连接数据库程序的桥梁

使用Connection来连接到数据库实例:

		String url = "jdbc:mysql://127.0.0.1:3306/emp_management?" +
                "useSSL=false&serverTimezone=UTC&useUnicode=true&characterEncoding=UTF8";
        String username = "root";
        String password = "159357";
		Connection conn = null;
try {
            /*
                1、加载驱动类,"com.mysql.cj.jdbc.Driver"类的具体路径
                也称之为类的全限定名
            */
            Class.forName("com.mysql.cj.jdbc.Driver");


            /*
            2、创建连接,需要3个参数
            参数1:数据库系统的地址:端口:数据库名称
            参数2:登录数据库系统的用户名
            参数3:登录数据库系统的密码
            */
            conn = DriverManager.getConnection(url,username,password);
            System.out.println("正常连接到数据库" + conn);

            /*
                3、操作数据
             */
            /*stmt = conn.createStatement();
            stmt.executeUpdate(sql);*/
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
                System.out.println("连接正常关闭");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

url中各项参数的解释:

参数名称参数含义
jdbc:mysql固定写法,说明连接的数据库是mysql
😕/127.0.0.1:3306表示连接到该ip地址上的数据库,本机可以写localhost和127.0.0.1
/emp_management数据库名称,表示你要连接哪个数据库
?useSSL=false因为MySQL8.0之后默认开启SSL安全协议,需要一些安全证书才能访问,因此我们需要手动关闭
&serverTimezone=UTC
&useUnicode=true使用Unicode字符集
&characterEncoding=UTF8设置字符编码,如果有中文,那么可以解决中文乱码问题

Statement接口


使用流程:

  1. 因为Statement是基于Connection对象的,因此我们需要获取数据库连接对象,连接数据库
  2. 使用Connection对象的createStatement()方法创建Statement对象实例
  3. 然后我们需要一个等待执行的SQl语句,因为需要多次拼接,所以使用StringBuffer效率更高
  4. 使用Statement对象的executeUpdate()、executeQuery()方法来执行我们拼接好的SQL语句、
  5. 关闭Statement对象,释放资源

使用实例:像admin表中插入一条数据

String name = null;
String pwd = null;
Scanner sc = new Scanner(System.in);
Connection conn = null;
Statement stmt = null;
	try {
            /*
                1、加载驱动类,"com.mysql.cj.jdbc.Driver"类的具体路径
                也称之为类的全限定名
            */
            Class.forName("com.mysql.cj.jdbc.Driver");


            /*
            2、创建连接,需要3个参数
            参数1:数据库系统的地址:端口:数据库名称
            参数2:登录数据库系统的用户名
            参数3:登录数据库系统的密码
            */
            conn = DriverManager.getConnection(url, username, password);
            System.out.println("正常连接到数据库" + conn);

            //信息录入
            System.out.print("请输入管理员姓名:");
            name = sc.next();
            System.out.print("请输入管理员密码:");
            pwd = sc.next();

            //拼接sql语句,因为是单线程,所以使用StringBuilder来提升性能
            StringBuilder sql = new StringBuilder("insert into admin values(null,'");
            sql.append(name);
            sql.append("','");
            sql.append(pwd);
            sql.append("')");
            
            /*
                3、操作数据
             */
            stmt = conn.createStatement();
            stmt.executeUpdate(sql.toString());
        } catch (ClassNotFoundException | SQLException e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
                stmt.close();
                System.out.println("连接正常关闭");
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

ResultSet接口


进行查询操作时使用

Statement对象进行executeQuery()返回的是一个ResultSet结果集

connection = DriverManager.getConnection(url, username, password);
statement = connection.createStatement();
resultset = statement.executeQuery(sql.toString());

游标机制:

实际上就是一个指针,最开始指向第0行(第0行没有任何数据),遍历的时候使用next()读取到一行数据,并将指针向下移动一行;

我们读取数据行中的数据,有两种方法:

第一种是索引:resultSet.getInt(1) 取第一列的数据

第二中是凭借列名来获取数据:resultSet.getString(“gradeName”); 获取此行列名为gradeName的数据

get后面的Int表示我们获取的数据类型是Int

同理有getString()、getDouble()等

使用实例:

while (rs.next()) {
                System.out.print(rs.getInt(1) + "\t");
                System.out.print(rs.getString("gradeName") + "\t");
                System.out.println(rs.getString(3));
            }

PreparedStatement接口


是Statement接口的子接口

  • 能够预编译好我们的SQL语句,可以防止SQl注入攻击等
  • 具有更好的可读性和可维护性
  • 能够提升SQl语句执行的效率

SQL注入攻击

我们来看一个Login_Check的例子

StringBuffer sql = new StringBuffer("select count(*) from admin where username='");
sql.append(username);
sql.append("' and userpwd = '");
sql.append(password);
sql.append("'");

如果我们输入的username 为

' or 1=1 --

那么完整的SQL语句就是

select count(*) from admin where username='' or 1=1 -- and userpwd ='password';

也就是说username=‘’ or 1=1恒成立,并且后面的内容被注释掉了,账号密码错误也能登录成功,这也就是SQL注入攻击

为什么PreparedStatement能防止sql注入呢?
因为sql语句是预编译的,而且语句中使用了占位符,规定了sql语句的结构。
用户可以设置"?"的值,但是不能改变sql语句的结构,

那么preparedStatement怎么使用呢?

String sql = "select count(*) from admin where username=? and userpwd=?";
prstmt = conn.prepareStatement(sql);
prstmt.setObject(1, username);
prstmt.setObject(2, password);
rs = prstmt.executeQuery();

第二第三句是对SQL中的问号赋值,因为不知道我们赋的值是什么类型的,所以统一用setObject()来赋值

因为赋值完之后preparedStatement就会进行预编译,所以在executeQuery()中不必传入参数

开发中的小技巧


我们在开发项目时,

设计表的时候一般会在最后添加一列状态列,通常叫active或者state,

如果碰到需要删除表信息的情况,一般不能直接delete,

而是将要删除的数据行状态值设置为隐藏(从1变成0)

这种删除方式称为逻辑删除

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值