当前位置: 移动技术网 > IT编程>开发语言>Java > JDBC-01

JDBC-01

2020年04月03日  | 移动技术网IT编程  | 我要评论
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注册驱动的介绍

 

 

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

原因:

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

 

所以调用 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语句

 

 

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

 

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

 

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

setautocommit

 

 

commit

 

rollback

 

 

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

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

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

  • boolean execute(string sql)

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

 

  • resultset executequery(string sql) 

  执行查询(select 语句)

 

  • int executeupdate(string sql)

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

 

 

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

 addbatch

 

clearbatch

 

executebatch

 

resultset:结果集

通过select语句的查询结果

 

结果集的遍历:

 

 

 

结果集的获取:

 

结果集的获取可以使用: 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的sql注入漏洞:

  什么是sql注入漏洞?

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

 

  漏洞分析:

 

 

  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

 

 

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

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

 

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

 

 

工具类代码

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");
    }
}

 

执行成功后:

控制台

 

 

此时user表中的数据

 

 

小结

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

                                加油!

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

如您对本文有疑问或者有任何想说的,请 点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网