JDBC学习笔记

概述

  • 概念:JDBC(Java DataBase Connectivity),可操作关系型数据库的接口(eg.MySQL、Oracle、DB2…)【通用接口,SQL都行】
  • 作用:驱动关系型数据库,为访问不同数据库提供了同一路径

体系结构

  • 接口包括两个层面

    • 面向应用的API,供程序员使用
    • 面向数据库的API,供数据库厂商开发程序驱动
  • Java Application —— JDBC API —— JDBC Driver Manager —— JDBC 驱动 —— 数据库

  • JDBC API

    • Java官方提供
    • 作用:供开发者调用的接口
    • java.sql 和 javax.sql
      • DriverManager 类
      • Connection 接口
      • Statement 接口
      • ResultSet 接口
  • Driver Manager

    • Java官方提供
    • 作用:管理不同JDBC驱动,以获取连接
  • JDBC 驱动

    • 数据库厂商提供
    • 作用:负责连接不同的数据库

使用

  • 导入驱动jar包 mysql-connector-java-5.1.37-bin.jar

    • 复制mysql-connector-java-5.1.37-bin.jar到项目的libs目录下

    • 右键–>Add As Library

    • JDBC下载链接:https://repo1.maven.org/maven2/mysql/mysql-connector-java/

  • 注册/加载驱动【Java程序和数据库的桥梁】——类似“基站”

    • 通过反射,获取运行时类,把类加载到JVM内存中
    • 建议用新版本cj包的Class.forName(“com.mysql.cj.jdbc.Driver”);
    • 记得处理异常
  • 获取Connection连接对象,Java程序与数据库的一次连接 ——有了“基站”,电话才能打通

    • 可以使用IDEA的Database插件查看数据库
    • url = “jdbc:mysql://localhost:3306/[库ID]?useUnicode=true&characterEncoding=UTF-8(处理乱码)”
    • user 用户名
    • password密码
  • 定义SQL语句

  • 获取执行SQL语句的表单对象 Statement,由Connection产生

    • 先创建
    • 再传值(sql)
  • 执行被创建的表单的SQL语句

    • 增/删/改【对数据有影响】:statement.executeUpdate(sql);
    • 查【对数据无影响】:statement.executeQuery(sql);
  • 如需接收返回值,int reult或者创建ResultSet对象,保存Statement执行之后的查询结果

    • 返回值result = 1,代表成功
  • 处理结果

  • 释放资源

    • statement.close()
    • connection.close()
  • 代码

package com.microsoft.jdbc;

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

public class JDBCDemo1 {
    public static void main(String[] args){
        try {
            //1.加载驱动
            Class.forName("com.mysql.cj.jdbc.Driver");
            //2.获取连接对象
            String url = "jdbc:mysql://localhost:3306/how2java?useUnicode=true&characterEncoding=UTF-8";
            Connection connection = DriverManager.getConnection(url,"root","admin");
            //3.定义sql语句
            //String sql = "insert into account(name,money) values('张三','666')";
            String sql = "select * from account";
            //4.获取执行sql语句的表单对象
            Statement statement = connection.createStatement();
            //5.执行sql
            //int result = statement.executeUpdate(sql);
            ResultSet resultSet = statement.executeQuery(sql);
            //6.处理结果(为1代表成功)
            //System.out.println("result = " + result);
            while(resultSet.next()){
                int id = resultSet.getInt("id");
                String name = resultSet.getString("name");
                Double money = resultSet.getDouble("money");
                System.out.println(id+" "+name+" "+money);
            }
            //7.释放资源
            statement.close();
            connection.close();
        } catch (Exception e) {
            e.printStackTrace();
        }
   }
}

PreparedStatement

  • Statement本身是个接口,PreparedStatement是它的子类,提供了SQL的占位符功能

  • 使用Statement开发有两个问题

    • 需要频繁拼接字符串,出错率高
    • 存在SQL注入的风险
  • 与Statement不同的是

    • 先传值
    • 再创建
    • 用?代替变量的值,如果有非法注入,也会被算作整个值
String name = "张三";
String sql = "select * from account where name=?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,name);
ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next()){
    System.out.println("登录成功!");
}else{
    System.out.println("登录失败!");
}

SQL注入

  • 利用某些系统没有对用户输入的信息进行充分检测,在用户输入的数据中注入非法的SQL语句,从而利用系统的SQL引擎完成恶意行为
  • 举个例子(下面这个所有内容就都拿得到了,可以登录成功):
select * from account where username="张三" or "1"="1" and password="123456" or "1"="1"

常见问题

  • win系统下的mysql重启(配置后需要)

  • cmd命令下:net stop mysql,停止后再net start mysql

  • 连接MySql时区错误(The server time zone value ‘Öйú±ê׼ʱ¼ä’ is unrecognized or represents more t…)

    • 原因:MySql安装默认设置为美国时区,而北京时间比美国迟8小时。

    • 解决方法1:

      • 在mysql安装目录下找到my.ini文件

      • [mysqld]下方添加:default-time-zone=’+08:00’

      • 重启

    • 解决方法2:

      • 在连接mysql语句的url后面添加?useSSL=true&serverTimezone=UTC即可解决该代码报错问题
  • JDBC注册驱动为什么要用反射而不是new?

    • 加载驱动有两种方式

      • 第一种:DriverManager.registerDriver(new com.mysql.jdbc.Driver());

      • 会导致驱动会注册两次,过度依赖于mysql的api,脱离的mysql的开发包,程序则无法编译

      • 第二种:Class.forName("com.mysql.jdbc.Driver");

      • 驱动只会加载一次,不需要依赖具体的驱动,灵活性高

    • 我们一般都是使用第二种方式,因为使用反射创建出来的对象耦合性更低,更加通用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值