欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

JDBC-01

程序员文章站 2022-03-04 09:14:56
JDBC 前言 在学习了SQL语句后,我们肯定会思考如何使用数据库里的数据。这个时候,我们便要学习JDBC来将数据库与JAVA结合在一块。 正题 什么是JDBC? Java数据库连接,(Java Database Connectivity,简称JDBC)是Java语言中用来规范客户端程序如何来访问数 ......

jdbc

前言

  在学习了sql语句后,我们肯定会思考如何使用数据库里的数据。这个时候,我们便要学习jdbc来将数据库与java结合在一块。

 

正题

什么是jdbc?

java数据库连接,(java database connectivity,简称jdbc)是java语言中用来规范客户端程序如何来访问数据库的应用程序接口。

 

jdbc的主要用途

  1. 与数据库建立连接
  2. 发送 sql 语句
  3. 处理结果

 

数据库驱动

在学习jdbc之前,我们必须了解一个东西,驱动。

驱动:两个设备(两个应用)之间通信的桥梁。

 

jdbc的开发步骤

  1. 加载驱动
  2. 获取连接
  3. 基本操作(crud)
  4. 释放资源

 

使用jdbc的准备工作

  1.创建一个maven项目(当然你也可以不用这种方法,但maven在开发中最为方便)

  【创建方式请看我之前的博客:利用maven进行导jar包】

  2.导入mysql的jar包

<dependencies>
       <dependency>
           <groupid>mysql</groupid>
           <artifactid>mysql-connector-java</artifactid>
           <version>5.1.6</version>
       </dependency>
 </dependencies>

  完成以上的操作,我们便可以开始进行jdbc的学习了。

 

jdbc的简单例子(先了解一下整体的框架,后面会相应的解释以及简化)

package com.jdbc.demo01;

import org.junit.test;
import java.sql.*;

/**
 *

 * jdbc的入门程序

 * @author  charles
   *
    */
   public class jdbcdemo1 {
    @test public void demo01() throws classnotfoundexception, sqlexception { // 1.加载驱动 class.forname("com.jdbc.driver"); // 2.获得连接 connection conn = drivermanager.getconnection("jdbc:mysql://localhost:3306/web_test3", "root" , "1234"); // 3.基本操作:执行sql // 3.1获得执行sql语句的对象 statement statement = conn.createstatement(); // 3.2编写sql语句: string sql = "select * from user"; // 3.3执行sql: resultset rs = statement.executequery(sql); // 3.4遍历结果集 while (rs.next()){ system.out.println(rs.getint(("id")+ " ")); system.out.println(rs.getint(("username")+ " ")); system.out.println(rs.getint(("password")+ " ")); system.out.println(rs.getint(("nickname")+ " ")); system.out.println(rs.getint(("age"))); system.out.println(); } // 4.释放资源 rs.close(); statement.close(); conn.close(); } }

 

接下来我来介绍一下上面代码的含义:

drivermanager:驱动管理类

  作用:①注册驱动 ②获得连接

①:

// 1.加载驱动,双引号里面的内容一般是标准
class.forname("com.jdbc.driver");

 

此时,你或许会好奇,不是注册驱动吗,为什么代码是加载驱动。

首先,我们来看看java的api中driver注册驱动的介绍JDBC-01

 

 

这种方式的确可以完成驱动的注册,但是实际开发中并不会这么做。

原因:

  如果需要注册驱动,就会使用dirvermanager.registerdriver(new driver()); ,但是在查询源代码的时候,我们发现源代码中有一段静态代码块已经调用了注册驱动的方法。因此,如果我们再手动调用注册,就会导致驱动被注册两次。

JDBC-01

 

所以调用 class.forname 将自动将加载驱动程序类。(具体的原理可以查看一些api文档)

 

②:connection conn = drivermanager.getconnection(url, user, password);

// 2.获得连接
connection conn = drivermanager.getconnection("jdbc:mysql://localhost:3306/web_test3", "root", "1234");

 参数介绍:

  • url:与数据库连接的路径
  • user:与数据库连接的用户名
  • password:与数据库连接的密码

 

url:

"jdbc:mysql://localhost:3306/web_test3"
  • jdbc:连接数据库的协议
  • mysql:是jdbc的子协议
  • localhost:连接的mysql数据库服务器的主机地址【本机:localhost,非本机:连接主机的ip地址】
  • 3306:mysql数据库服务器的端口号
  • web_test3:数据库名称

 

connection:与数据库的连接对象

  作用:①创建执行sql语句的对象  ②管理事务

①:常用的三个对象:statement、callablestatement、preparedstatement

statement:执行sql语句

JDBC-01

 

 

callablestatement:执行数据库的存储过程

JDBC-01

 

prepardedstatement:执行sql语句,对sql进行预处理。(用于解决sql注入漏洞问题)

JDBC-01

 

②:三个常用对象:setautocommit、commit、rollback

setautocommit

JDBC-01

 

 

commit

JDBC-01

 

rollback

 JDBC-01

 

接下来我们来看看statement的详细操作:

作用:①执行sql  ②执行批处理

①:常用的执行sql方法: 主要使用的是后两个

  • boolean execute(string sql)

  执行查询,修改,添加,删除的sql语句

JDBC-01

 

  • resultset executequery(string sql) 

  执行查询(select 语句)

JDBC-01

 

  • int executeupdate(string sql)

  执行修改,添加,删除的sql语句

JDBC-01

 

 

②:常用的执行批处理的方法

 addbatch

JDBC-01

 

clearbatch

JDBC-01

 

executebatch

JDBC-01

 

resultset:结果集

通过select语句的查询结果

 

结果集的遍历:

JDBC-01

 

 

JDBC-01

 

结果集的获取:

JDBC-01

 

JDBC-01

结果集的获取可以使用: getxxx(); 通常都会有重载的方法。

getxxx(int columnindex);

getxxx(string columnname);

 

jdbc的资源释放:

  jdbc程序执行结束后,将与数据库进行交互的对象释放掉,通常是resultset,statement(preparedstatement),connection。

  这几个对象尤其是connection对象是非常稀有的,这个对象一定要做到尽量晚创建,尽早释放掉。

  注:释放代码应写入finally的代码块中。

 

具体实现:

if(rs != null){
    try{
        rs.close();
    } catch (sqlexception e){
        e.printstacktrace();
    }
    rs = null;
}
if(statement != null){
    try{
        statement.close();
    } catch (sqlexception e){
        e.printstacktrace();
    }
    statement = null;
}
if(conn != null){
    try{
        conn.close();
    } catch (sqlexception e){
        e.printstacktrace();
    }
    conn = null;
}

 

crud的操作:

保存操作:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class demo01 {
    @test
    public void demo01(){
        connection conn = null;
        statement statement = null;
        try{
            // 注册驱动
            class.forname("com.mysql.jdbc.driver");
            // 获得连接
            conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root",
                    "1234);
            // 执行操作
            // 创建执行sql语句对象
            statement = conn.createstatement();
            // 编写sql语句
            string sql = "insert into user values (null, 'eee', '123', 'jack', 21)";
            // 执行sql语句
            int num = statement.executeupdate(sql);
            if (num > 0){
                system.out.println("保存用户成功!");
            }

        }catch (exception e){
            e.printstacktrace();
        }finally {
            // 释放资源
            if (statement != null){
               try{
                   statement.close();
               } catch (sqlexception e){
                   e.printstacktrace();
               }
               statement = null;
            }

            if (conn != null){
                try {
                    conn.close();
                }catch (sqlexception e){
                    e.printstacktrace();
                }
                conn = null;
            }

        }
    }

}

 

修改操作:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class demo01 {
    @test
    public void demo01(){
        connection conn = null;
        statement statement = null;
        try{
            // 注册驱动
            class.forname("com.mysql.jdbc.driver");
            // 获得连接
            conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root",
                    "1234");
            // 执行操作
            // 创建执行sql语句对象
            statement = conn.createstatement();
            // 编写sql语句
            string sql = "update user set password='2222',nickname='biubiu' where id=6";
            // 执行sql语句
            int num = statement.executeupdate(sql);
            if (num > 0){
                system.out.println("修改用户成功!");
            }

        }catch (exception e){
            e.printstacktrace();
        }finally {
            // 释放资源
            if (statement != null){
               try{
                   statement.close();
               } catch (sqlexception e){
                   e.printstacktrace();
               }
               statement = null;
            }

            if (conn != null){
                try {
                    conn.close();
                }catch (sqlexception e){
                    e.printstacktrace();
                }
                conn = null;
            }

        }
    }

}

 

删除操作:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class demo01 {
    @test
    public void demo01(){
        connection conn = null;
        statement statement = null;
        try{
            // 注册驱动
            class.forname("com.mysql.jdbc.driver");
            // 获得连接
            conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root",
                    "1234");
            // 执行操作
            // 创建执行sql语句对象
            statement = conn.createstatement();
            // 编写sql语句
            string sql = "delete from user where id=6";
            // 执行sql语句
            int num = statement.executeupdate(sql);
            if (num > 0){
                system.out.println("删除用户成功!");
            }

        }catch (exception e){
            e.printstacktrace();
        }finally {
            // 释放资源
            if (statement != null){
               try{
                   statement.close();
               } catch (sqlexception e){
                   e.printstacktrace();
               }
               statement = null;
            }

            if (conn != null){
                try {
                    conn.close();
                }catch (sqlexception e){
                    e.printstacktrace();
                }
                conn = null;
            }

        }
    }

}

 

查询操作:

①多条信息查询:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class demo01 {
    @test
    public void demo01(){
        connection conn = null;
        statement statement = null;
        resultset rs = null;
        try{
            // 注册驱动
            class.forname("com.mysql.jdbc.driver");
            // 获得连接
            conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root",
                    "1234");
            // 执行操作
            // 创建执行sql语句对象
            statement = conn.createstatement();
            // 编写sql语句
            string sql = "select * from user";
            // 执行sql语句
            rs = statement.executequery(sql);
            while(rs.next()){
                 system.out.println(rs.getint(("id")+ " "));
                system.out.println(rs.getint(("username")+ " "));
                system.out.println(rs.getint(("password")+ " "));
                system.out.println(rs.getint(("nickname")+ " "));
                system.out.println(rs.getint(("age")));
                system.out.println();
            }

        }catch (exception e){
            e.printstacktrace();
        }finally {
            // 释放资源
            if (statement != null){
               try{
                   statement.close();
               } catch (sqlexception e){
                   e.printstacktrace();
               }
               statement = null;
            }

            if (conn != null){
                try {
                    conn.close();
                }catch (sqlexception e){
                    e.printstacktrace();
                }
                conn = null;
            }
            
            if (rs != null){
                try {
                    rs.close();
                }catch (sqlexception e){
                    e.printstacktrace();
                }
                conn = null;
            }

        }
    }

}

 

②一条信息查询:

package com.charles.sql;

import org.junit.*;

import java.sql.*;

public class demo01 {
    @test
    public void demo01(){
        connection conn = null;
        statement statement = null;
        resultset rs = null;
        try{
            // 注册驱动
            class.forname("com.mysql.jdbc.driver");
            // 获得连接
            conn = drivermanager.getconnection("jdbc:mysql:///web_test3", "root",
                    "1234");
            // 执行操作
            // 创建执行sql语句对象
            statement = conn.createstatement();
            // 编写sql语句
            string sql = "select * from user where id=1";
            // 执行sql语句
            rs = statement.executequery(sql);
            if(rs.next()){
                system.out.println(rs.getint("id")+" "+rs.getstring("username")+" 
                                   "+re.getstring("password"));
            }

        }catch (exception e){
            e.printstacktrace();
        }finally {
            // 释放资源
            if (statement != null){
               try{
                   statement.close();
               } catch (sqlexception e){
                   e.printstacktrace();
               }
               statement = null;
            }

            if (conn != null){
                try {
                    conn.close();
                }catch (sqlexception e){
                    e.printstacktrace();
                }
                conn = null;
            }
            
            if (rs != null){
                try {
                    rs.close();
                }catch (sqlexception e){
                    e.printstacktrace();
                }
                conn = null;
            }

        }
    }

}

 

jdbc工具类的抽取:

目的:包装成工具类后,能够更方便地使用jdbc,减少不必要的工作量

package org.charl;

import java.sql.*;

/**
 * jdbc工具类
 * @author charles
 */

public class demo {

    // 默认设置
    public static final string driverclassname;
    public static final string url;
    public static final string username;
    public static final string password;
    static {
        driverclassname = "com.mysql.jdbc.driver";
        url = "jdbc:mysql:///web_test3";
        username = "root";
        password = "1234";
    }
    // 注册驱动类
    public static void loaddriver(){
        try {
            class.forname(driverclassname);
        } catch (classnotfoundexception e) {
            e.printstacktrace();
        }
    }

    // 获得连接
    public static connection getconnection(){
        connection conn = null;
        try {
            loaddriver();
            conn = drivermanager.getconnection(url,username,password);
        } catch (sqlexception e) {
            e.printstacktrace();
        }
        return conn;
    }

    // 资源释放
    public static void release(statement st,connection conn){
        if (st != null){
            try{
                st.close();
            } catch (sqlexception e){
                e.printstacktrace();
            }
            st = null;
        }

        if (conn != null){
            try {
                conn.close();
            }catch (sqlexception e){
                e.printstacktrace();
            }
            conn = null;
        }
    }

    public static void release(statement st,connection conn, resultset rs){
        if (st != null){
            try{
                st.close();
            } catch (sqlexception e){
                e.printstacktrace();
            }
            st = null;
        }

        if (conn != null){
            try {
                conn.close();
            }catch (sqlexception e){
                e.printstacktrace();
            }
            conn = null;
        }

        if (rs != null){
            try {
                rs.close();
            }catch (sqlexception e){
                e.printstacktrace();
            }
            rs = null;
        }
    }
}

 

配置文件:

  创建一个:db.properties配置文件

  作用:用来存储数据库用户等信息

  目的:简化工具类的代码

演示:

JDBC-01

 

 

在工具类中解析属性文件

JDBC-01

 

jdbc的sql注入漏洞:

  什么是sql注入漏洞?

    假设有一个网站,用户需要进行注入。用户注册后根据用户名和密码进行登录。假设该用户的用户名被其他人知道了,但他并不     知道密码,也可以登录到网站上进行相应的用户操作。

 

  漏洞分析:

JDBC-01

 

 

  sql注入漏洞的解决方法

  采用preparedstatement对象解决sql注入漏洞问题。该对象将sql预先进行编译,使用'?'作为占用符。'?'所代表的内容是sql所固定。如果再次传入变量(包括sql的关键字),这个时候也不会识别这些关键字。

 

preparedstatement预编译:

具体操作:

package com.charles.sql;

import java.sql.*;

/***
 * @return
 * @author charles
 */

public class demo02 {
    public boolean login(string username, string password){

        connection conn = null;
        preparedstatement preparedstatement = null;
        resultset rs = null;
        boolean flag = false;
        try{
            conn = org.charl.demo.getconnection();
            string sql = "select * from user where username = ? and password = ?";
            preparedstatement = conn.preparestatement(sql);
            // 设置参数
            preparedstatement.setstring(1,username);
            preparedstatement.setstring(2,password);
            rs = preparedstatement.executequery();
            if (rs.next()){
                flag = true;
            }
        } catch (sqlexception e){
            e.printstacktrace();
        } finally {
            org.charl.demo.release(preparedstatement,conn,rs);
        }
        return flag;
    }
}

 

jdbc批处理操作:

  什么是批处理?

    批处理就是将所有sql语句一起执行。

常用的方法已在前面介绍过。

注意:通常情况下mysql批处理是没有开启的,要想执行批处理,就要在url的内容中进行相应的添加。

?rewritebatchedstatements=true

JDBC-01

 

 

接下来展示一下比较完整的实例:

【里面包含了preparedstatement等内容,之前的案例看不懂没关系,这个案例供大家参考】

 

数据库web_test4中user表原先的信息

JDBC-01

 

 

工具类代码

package org.charl;

import java.sql.*;
import java.util.properties;

/**
 * jdbc工具类
 * @author charles
 */

public class demo {

    // 默认设置
    public static final string driverclassname;
    public static final string url;
    public static final string username;
    public static final string password;
    static {
        driverclassname = "com.mysql.jdbc.driver";
        url = "jdbc:mysql:///web_test4?rewritebatchedstatements=true?characterencoding=utf-8";
        username = "root";
        password = "1234";
    }
    // 注册驱动类
    public static void loaddriver(){
        try {
            class.forname(driverclassname);
        } catch (classnotfoundexception e) {
            e.printstacktrace();
        }
    }

    // 获得连接
    public static connection getconnection(){
        connection conn = null;
        try {
            loaddriver();
            conn = drivermanager.getconnection(url,username,password);
        } catch (sqlexception e) {
            e.printstacktrace();
        }
        return conn;
    }

    // 资源释放
    public static void release(statement st,connection conn){
        if (st != null){
            try{
                st.close();
            } catch (sqlexception e){
                e.printstacktrace();
            }
            st = null;
        }

        if (conn != null){
            try {
                conn.close();
            }catch (sqlexception e){
                e.printstacktrace();
            }
            conn = null;
        }
    }

    public static void release(statement st,connection conn, resultset rs){
        if (st != null){
            try{
                st.close();
            } catch (sqlexception e){
                e.printstacktrace();
            }
            st = null;
        }

        if (conn != null){
            try {
                conn.close();
            }catch (sqlexception e){
                e.printstacktrace();
            }
            conn = null;
        }

        if (rs != null){
            try {
                rs.close();
            }catch (sqlexception e){
                e.printstacktrace();
            }
            rs = null;
        }
    }
}

 

执行主代码

package com.charles.sql;

import org.junit.test;

import java.sql.*;

public class demo03 {
    @test
    public void test(){
        long begin = system.currenttimemillis();
        connection conn = null;
        preparedstatement preparedstatement = null;
        resultset rs = null;
        try{
            // 注册驱动 + 获得连接
            conn = org.charl.demo.getconnection();
            // 编写sql语句
            string sql = "insert into user values(null,?)";
            // 预编译
            preparedstatement = conn.preparestatement(sql);
            for (int i =1;i<10000;i++){
                preparedstatement.setstring(1,"name"+i);
                // 添加到批处理
                preparedstatement.addbatch();
                // 执行批处理
                if (i % 1000 == 0){
                    preparedstatement.executebatch();
                    // 进行清空防止数据溢出
                    preparedstatement.clearbatch();
                }
            }
        }catch (exception e){
            e.printstacktrace();
        }finally {
            // 释放资源
            org.charl.demo.release(preparedstatement,conn,rs);
        }
        long end = system.currenttimemillis();
        system.out.println("耗时:"+ (end - begin) + "ms");
    }
}

 

执行成功后:

控制台

JDBC-01

 

 

此时user表中的数据

JDBC-01

 

 

小结

  以上就是jdbc入门的介绍,当然在刚学习jdbc的时候,肯定会出现许多错误,这些错误或许一时间会让你抓狂,但请耐心地解决,相信后面收获肯定满满的。

                                加油!

                          时间:2020-04-02 20:57:18

推荐阅读