详解Java基础知识——JDBC

JDBC

Java DataBase Connectivity,java数据库连接,为了降低操作数据的难度,java提供jdbc,按照java面向对象特点,对操作进行了很多封装。

JDBC提供了很多接口,然后不同数据库厂商去实现这个接口,到底底层如何去实现,不同的数据库不一样,不同的数据库厂商需要提供接口实现类(驱动类、驱动程序 Driver、驱动)

我们连接不同的数据库,我们只需要使用不同的驱动即可。

J:Java:提供访问数据库的规范(接口),

DBC:接口的实现,厂商去实现这个接口。

JDBC是一种用于执行SQL语句的java api.

版本号

1.1.1 Major. Minor. Build

Major:项目由架构、大规模的变化

Minor:有新功能的时候

Build:编译版本

JDBC开发

Java程序使用第三方提供工具框架,都需要导入jar包

可以通过以下网址搜索找到mysql的相关jar包

https://mvnrepository.com/

下载好jar包后,在于src同级的目录下,建立一个lib文件夹,添加jar包,并添加依赖

代码实现

通过一个简单的案例来实现JDBC的使用

import java.sql.*;

public class Demo02 {
  public static void main(String[] args) throws ClassNotFoundException, SQLException {
    //1注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //2建立连接
    String url = "jdbc:mysql://localhost:3306/mydb01";
    String usernName = "xxx"; //登录数据库的账号
    String password = "xxxx"; //登录数据库的密码
    Connection conn = DriverManager.getConnection(url, usernName, password);
    //3获取执行sQL语句的对象
    Statement statement = conn.createStatement();
    //4获取数据库返回的结果
    String sql = "delete from emp where empno = " +"7499";
    String sqlUpdate = "update emp set sal = "+10000+" where empno = " +"7369";

    String sqlInsert = "INSERT INTO emp VALUES(2018,\"boss\",\"king\",NULL,\"2018-8-
              8\",15000,10000,10);";

    //5处理数据集
    int i = statement.executeUpdate(sql);
    int s = statement.executeUpdate(sqlUpdate);
    int ins = statement.executeUpdate(sqlInsert);
    System.out.println(i + "行受到影响----删除");
    System.out.println(s + "行受到影响----更新");
    System.out.println(ins + "行受到影响----插入");
    //6关闭连接

    statement.close();
    conn.close();

  }
}

使用JDBC的顺序

  1. (1)注册数据库驱动
  2. (2)和数据库建立连接
  3. (3)获取执行SQL语句的对象
  4. (4)获取数据库返回的结果
  5. (5)处理数据集(逻辑代码)
  6. (6)释放资源,关闭连接

常用类

Connection

通过配置文件可以创建一个connect对象

Statement

  1. 通过connect对象获取操作数据库的Statement对象,
  2. 通过它来实现对数据库增删改查操作。
  3. executeQuery():查,返回数据集
  4. executeUpdate():增删改,返回int的数据,影响的行数

ResultSet

数据集,可以理解就是一个集合。

取出数据:

  1. 通过下标:从1开始
  2. 通过字段名:SQL语句中select后面跟的字段,有可能和数据库一样,也可能不一样

JDBC的优化

平时开发和项目上线之后使用的数据库是不一样的,不是同一个

这也就是我们说的,开发环境不一样

开发环境不一样,使用的数据库也就不一样,那么上面的数据库中配置的三要素就要进行修改

而这种修改是人工操作的,人工操作就有存在了失误,而修改之后的.java文件,也要重新编译,这也可能出现错误

假设项目上线,需要以下四个步骤:

测试环境-->修改配置 -->重新编译-->生产环境

如果想要避免上述出现的失误的情况,就要绕开中间的两个步骤

解决的方法就是,配置文件,添加配置文件,将要修改的配置信息存放到配置文件中,每次读取信息从配置文件中读取

而配置文件的位置是固定的,也不会重新编译,这样就可以降低风险

java中用IO流也可以读取配置文件,通过一个专有的类Properties也可以读写配置文件

IO读取配置文件

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;

public class IoReadProp {
  public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {
    //1注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    String[] para = read();

    //2建立连接
    String url = para[0];
    String usernName = para[1];
    String password = para[2];
    Connection conn = DriverManager.getConnection(url,usernName,password);

    //3获取执行sQL语句的对象
    Statement statement = conn.createStatement();

    //4获取数据库返回的结果
    String sql = "select * from emp";
    ResultSet resultSet = statement.executeQuery(sql);

    //5处理数据集
    try {
      while (resultSet.next()){
        //.getXXX方法中的参数 1,字段名 2.字段的下标
        int empno = resultSet.getInt("empno");
        String ename = resultSet.getString("ename");
        String job = resultSet.getString(3);
        Date date = resultSet.getDate(5);
        System.out.println("empno:"+empno+", ename:"+ename+", job:"+job+", date:"+date);
      }
    }
    catch (Exception e){
      e.printStackTrace();
    }
    finally {
      //6关闭连接
      resultSet.close();
      statement.close();
      conn.close();
    }
  }

  public static String [] read()throws IOException {
    FileReader fr = new FileReader( "E:\\javalearning\\src\\jdbc\\jdbc.properties" );
    //创建 写入 缓冲区
    BufferedReader bufferedReader = new BufferedReader( fr );
    String [] str = new String[3];
    for(int i =0 ;i < 3;i++){
      str[i] = bufferedReader.readLine().split("=")[1].replace(";","").trim();
    }
    bufferedReader.close();
    fr.close();
    return str;
  }
}

Properties读取配置文件

import java.io.*;
import java.sql.*;
import java.util.Iterator;
import java.util.Properties;

public class PropReadProp {
  public static void main(String[] args) throws ClassNotFoundException, SQLException, IOException {
    //1注册驱动
    Class.forName("com.mysql.jdbc.Driver");
    //用户数组存放数据库信息
    String[] para = new String[3];

    //读取配置文件
    int i = 0;
    Properties prop = new Properties();
    FileInputStream fileInputStream = new FileInputStream("E:\\javalearning\\src\\jdbc\\jdbc.properties");
    InputStream in = new BufferedInputStream(fileInputStream);
    prop.load(in);
    Iterator<String> it = prop.stringPropertyNames().iterator();
    while (it.hasNext()) {
      para[i] = prop.getProperty(it.next());
      i++;
    }
    in.close();
    //2建立连接
    String url = para[0];
    String usernName = para[1];
    String password = para[2];
    Connection conn = DriverManager.getConnection(url, usernName, password);

    //3获取执行sQL语句的对象
    Statement statement = conn.createStatement();

    //4获取数据库返回的结果
    String sql = "select * from emp";
    ResultSet resultSet = statement.executeQuery(sql);

    //5处理数据集
    try {
      while (resultSet.next()) {
        //.getXXX方法中的参数 1,字段名 2.字段的下标
        int empno = resultSet.getInt("empno");
        String ename = resultSet.getString("ename");
        String job = resultSet.getString(3);
        Date date = resultSet.getDate(5);
        System.out.println("empno:" + empno + ", ename:" + ename + ", job:" + job + ", date:" + date);
      }
    } catch (Exception e) {
      e.printStackTrace();
    } finally {
      //6关闭连接
      resultSet.close();
      statement.close();
      conn.close();
    }
  }
}

分层DAO

Data Access Object数据访问对象是一个面向对象的数据库接口

会建立一个包:dao,里面的类都是用来操作数据库的。

通常情况下,有几张表,就有几个DAO

分层Entity、bean、pojo

实体,也就是一个一个类,该类里面只有属性,和对应set.get方法

往往一个表一个实体,实体的属性和表的字段有没有关系,名字一般一样,类型相对应

使用逆向工程,通过表导出实体。

Utils 工具类

代替我们去操作一系列的连接关闭等操作

案例:

目录结构如下,

EmpDAO代码如下:

package jdbc.dao;

import jdbc.entity.Emp;
import jdbc.utils.JDBCUtils;

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

public class EmpDAO {

  /**
   * 根据员工id获取员工信息
   */
  public Emp getEmpById(Integer id){
    Connection connection =null;
    Statement statement = null;
    ResultSet rs = null;
    Emp emp = null;

    try {
      connection = JDBCUtils.getConnection();
      statement = connection.createStatement();
      rs = statement.executeQuery("select * from emp where empno='"+id+"'");

      while (rs.next()){
        emp = new Emp();
        int empno = rs.getInt("empno");
        emp.setEmpno(empno);

        String ename = rs.getString("ename");
        emp.setEname(ename);

        String job = rs.getString(3);
        emp.setJob(job);

        String hiredate = rs.getString(5);
        emp.setHiredate(hiredate);
      }

    } catch (SQLException e) {
      e.printStackTrace();
    }
    finally {
      JDBCUtils.close(connection,statement,rs);
    }
    return emp;
  }

  public Emp getEmpById(String id){
    Connection connection =null;
    Statement statement = null;
    ResultSet rs = null;
    Emp emp = null;

    try {
      connection = JDBCUtils.getConnection();
      statement = connection.createStatement();
      rs = statement.executeQuery("select * from emp where empno="+id);

      while (rs.next()){
        emp = new Emp();
        int empno = rs.getInt("empno");
        emp.setEmpno(empno);

        String ename = rs.getString("ename");
        emp.setEname(ename);

        String job = rs.getString(3);
        emp.setJob(job);

        String hiredate = rs.getString(5);
        emp.setHiredate(hiredate);
      }

    } catch (SQLException e) {
      e.printStackTrace();
    }
    finally {
      JDBCUtils.close(connection,statement,rs);
    }
    return emp;
  }
}

entity中的Emp代码如下

package jdbc.entity;

public class Emp {
  //emp表中的相关属性
  private Integer empno;
  private String ename;
  private String job;
  private String mgr;
  private String hiredate ;
  private double sal;
  private double comm;
  private Integer deptno;

  public Integer getEmpno() {
    return empno;
  }

  public void setEmpno(Integer empno) {
    this.empno = empno;
  }

  public String getEname() {
    return ename;
  }

  public void setEname(String ename) {
    this.ename = ename;
  }

  public String getJob() {
    return job;
  }

  public void setJob(String job) {
    this.job = job;
  }

  public String getMgr() {
    return mgr;
  }

  public void setMgr(String mgr) {
    this.mgr = mgr;
  }

  public String getHiredate() {
    return hiredate;
  }

  public void setHiredate(String hiredate) {
    this.hiredate = hiredate;
  }

  public double getSal() {
    return sal;
  }

  public void setSal(double sal) {
    this.sal = sal;
  }

  public double getComm() {
    return comm;
  }

  public void setComm(double comm) {
    this.comm = comm;
  }

  public Integer getDeptno() {
    return deptno;
  }

  public void setDeptno(Integer deptno) {
    this.deptno = deptno;
  }

  //默认输出方法

  @Override
  public String toString() {
    return "Emp{" +
        "empno=" + empno +
        ", ename='" + ename + '\'' +
        ", job='" + job + '\'' +
        ", mgr='" + mgr + '\'' +
        ", hiredate='" + hiredate + '\'' +
        ", sal=" + sal +
        ", comm=" + comm +
        ", deptno=" + deptno +
        '}';
  }
}

utils中的JDBCUtils代码如下

package jdbc.utils;

import java.io.BufferedInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Iterator;
import java.util.Properties;

public class JDBCUtils {

  private static final String URL ;
  private static final String USERNAME ;
  private static final String PASSWORD ;

  static{
    String [] parp = null;
    try {
      parp = PropRead();
    } catch (IOException e) {
      e.printStackTrace();
    }
    URL = parp[0];
    USERNAME = parp[1];
    PASSWORD=parp[2];
    try {
      Class.forName("com.mysql.jdbc.Driver");
    } catch (ClassNotFoundException e) {
      e.printStackTrace();
    }
  }

  /**
   * 创建连接
   */

  public static Connection getConnection() throws SQLException {
    Connection conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
    return conn;
  }

  public static void close(Connection co , Statement state, ResultSet rs){
    if(rs != null){
      try {
        rs.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }

    if(state !=null){
      try {
        state.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }

    if(co !=null){
      try {
        co.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }

  public static void close(Connection co , Statement state){

    if(state !=null){
      try {
        state.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }

    if(co !=null){
      try {
        co.close();
      } catch (SQLException e) {
        e.printStackTrace();
      }
    }
  }

  /**
   * 读取配置文件
   * @return
   * @throws IOException
   */
  public static String [] PropRead()throws IOException {
    String[] para = new String[3];
    int i = 0;
    Properties prop = new Properties();
    FileInputStream fileInputStream = new FileInputStream("E:\\javalearning\\src\\jdbc\\jdbc.properties");
    InputStream in = new BufferedInputStream(fileInputStream);
    prop.load(in);
    Iterator<String> it = prop.stringPropertyNames().iterator();
    while (it.hasNext()) {
      para[i] = prop.getProperty(it.next());
      i++;
    }
    in.close();
    return para;
  }

}

测试代码如下:

package jdbc;

import jdbc.dao.EmpDAO;
import jdbc.entity.Emp;

import java.util.Scanner;

public class Main {
  public static void main(String[] args) {
    EmpDAO empDAO = new EmpDAO();
    System.out.println("请输入ID");
    Scanner scanner = new Scanner( System.in );
    String value = scanner.nextLine();
    Emp emp = empDAO.getEmpById (value);
    Emp emp1 = empDAO.getEmpById (7900);
    System.out.println(emp);
    System.out.println(emp1);
  }
}

这样就简单实现了一个分层的使用JDBC的案例

SQL注入攻击

根据上述案例,我们可以输入一个员工的id来查找该员工

但是有一个问题,你如何去规定用户的输入,下面给大家看一个现象

我的数据库在中并没有123456789这个id的人,那么为什么还会有结果呢?

就是因为我们的sql语句是根据字符串拼接生成的,当你输入的数据中包含sql关键字时,会被当成sql语句去执行

注意:这是很危险的!

不友好的用户可以根据这个漏洞对你的数据库进行修改,甚至删除你的数据库!

解决方法:PreparedStatement类

PreparedStatement是statement的子类

解决原理:

SQL语句不在拼接,而是通过预处理,也就是说,用户输入的任何内容,都只能作为值,不解析特殊字符。

修改之后打代码如下:

public Emp getEmpById2(String id){
    Connection connection =null;
    PreparedStatement statement = null;
    ResultSet rs = null;
    Emp emp = null;

    try {
      connection = JDBCUtils.getConnection();
      String sql = "select * from emp where empno=?";
      statement = connection.prepareStatement(sql);
      statement.setString(1,id);
      rs = statement.executeQuery();
      while (rs.next()){
        emp = new Emp();
        int empno = rs.getInt("empno");
        emp.setEmpno(empno);

        String ename = rs.getString("ename");
        emp.setEname(ename);

        String job = rs.getString(3);
        emp.setJob(job);

        String hiredate = rs.getString(5);
        emp.setHiredate(hiredate);
      }

    } catch (SQLException e) {
      e.printStackTrace();
    }
    finally {
      JDBCUtils.close(connection,statement,rs);
    }
    return emp;
  }

再次测试:结果如图

总结:并不是意味着Statement不能用,或者不能SQL拼接

但是如果是前端穿过的来的值需要直接放到SQL语句中,就需要注意。

以上所述是小编给大家介绍的Java基础知识——JDBC详解整合,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对我们网站的支持!

(0)

相关推荐

  • Java中使用JDBC操作数据库简单实例

    好久没有编写有关数据库应用程序啦,这里回顾一下java JDBC. 1.使用Java JDBC操作数据库一般需要6步: (1)建立JDBC桥接器,加载数据库驱动: (2)连接数据库,获得Connection对象(使用数据库连接地址,用户名,密码): (3)获得数据库Statement对象: (4)执行数据库操作: (5)读取结果: (6)关闭数据库连接: 2.使用Java JDBC操作数据库(mysql)代码: 连接mysql数据库,需要导入mysql数据库jar包,本代码使用mysql-con

  • Java使用JDBC连接数据库的实现方法

    本文实例讲述了Java使用JDBC连接数据库的实现方法,是Java数据库程序设计里非常实用的重要技巧.分享给大家供大家参考.具体如下: JDBC(Java Data Base Connectivity)数据库连接,通常我们在编写web应用或java应用程序要连接数据库时就要使用JDBC.使用JDBC连接数据库一般步骤有: 1.加载驱动程序 Class.forName(driver); 2.创建连接对象 Connection con = DriverManager.getConnection(ur

  • Java开发Oracle数据库连接JDBC Thin Driver 的三种方法

    Oracle的jdbc驱动三种主要分类: 1.JDBC OCI: oci是oracle call interface的缩写,此驱动类似于传统的ODBC 驱动.因为它需要Oracle Call Interface and Net8,所以它需要在运行使用此驱动的JAVA程序的机器上安装客户端软件,其实主要是用到orcale客户端里以dll方式提供的oci和服务器配置. 2.JDBC Thin: thin是for thin client的意思,这种驱动一般用在运行在WEB浏览器中的JAVA程序.它不是

  • JAVA使用JDBC技术操作SqlServer数据库实例代码

    JDBC(Java Data Base Connectivity,Java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成.JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序. JDBC并不能直接访问数据库,需要借助于数据库厂商提供的JDBC驱动程序. 数据库连接 如果要在Java访问数据库,首先要加载一个数据库驱动,数据库驱动只需要在第一次访问时加载一次.然后再每次访问

  • 在eclipse导入Java的jar包的方法JDBC(图文说明)

    在使用JDBC编程时需要连接数据库,导入JAR包是必须的,导入其它的jar包方法同样如此,导入的方法是 打开eclipse 1.右击要导入jar包的项目,点properties  2.左边选择java build path,右边选择libraries  3.选择add External jars  4.选择jar包的按照路径下的 确定后就行了. Java连接MySQL的最新驱动包下载地址 http://www.mysql.com/downloads/connector/j 有两种方法导入jar包

  • Java加载JDBC驱动程序实例详解

    本文实例说明了Java加载JDBC驱动程序的方法,运行本文实例代码后,如果连接成功就会显示如下一条语句:sun.jdbc.odbc.JdbcOdbcDriver@6ec12,如果连接不成功,则显示加载数据库驱动程序出现异常. Java加载JDBC的实现方法: 通过调用Class.forName()方法可以显式地加载一个驱动程序.该方法的入口参数为要加载的驱动程序.例如:Class.forName("sun.jdbc.odbc.JdbcOdbcDriver")语句加载了SUN 公司开发的

  • java jdbc连接mysql数据库实现增删改查操作

    jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打交道非常基础的一个知识,也是比较接近底层的,在实际的工作中大家用得更多的其实还是比较成熟的框架,例如Hibernate.Mybatis. 但是作为这些成熟框架的底层的jdbc却也是我们应该去掌握的,只有了解了jdbc的增删改查,这样在以后如果有兴趣去研究Hibernate或者Mybatis的源代码的时候才能更好的去理解这些成熟的框架是如何去实现增删改查

  • java使用jdbc连接数据库工具类和jdbc连接mysql数据示例

    这个工具类使用简单,实例化直接调用就可以了,大家还可以方便的根据自己的需要在里面增加自己的功能 复制代码 代码如下: package com.lanp.ajax.db; import java.sql.Connection;import java.sql.DriverManager;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException; /** * 连接数据库的工具类,被定

  • 基于Java回顾之JDBC的使用详解

    尽管在实际开发过程中,我们一般使用ORM框架来代替传统的JDBC,例如Hibernate或者iBatis,但JDBC是Java用来实现数据访问的基础,掌握它对于我们理解Java的数据操作流程很有帮助. JDBC的全称是Java Database Connectivity. JDBC对数据库进行操作的流程:•连接数据库•发送数据请求,即传统的CRUD指令•返回操作结果集JDBC中常用的对象包括:•ConnectionManager•Connection•Statement•CallableStat

  • java中JDBC实现往MySQL插入百万级数据的实例代码

    想往某个表中插入几百万条数据做下测试,原先的想法,直接写个循环10W次随便插入点数据试试吧,好吧,我真的很天真.... DROP PROCEDURE IF EXISTS proc_initData;--如果存在此存储过程则删掉 DELIMITER $ CREATE PROCEDURE proc_initData() BEGIN DECLARE i INT DEFAULT 1; WHILE i<=100000 DO INSERT INTO text VALUES(i,CONCAT('姓名',i),

随机推荐