今天给大家更新一篇我自己学习Java——JDBC的经验

Java中JDBC是(Java DataBase Connectivity)的简称,由java语言编写的类和接口组成,可为多种关系型数据库提供了统一访问。

Sun公司(现被Oracle公司收购)提供了JDBC的接口规范——JDBC API,而数据库厂商和第三方中间件根据JDBC接口规范提供了不同数据库的具体实现——JDBC驱动。

JDBC API:提供各种不同数据库交互的标准接口,如Connection接口、PreparedStatement接口等,供开发人员使用JDBC接口进行各数据库的操作。

JDBC API主要做:与数据库建立连接、发送SQL语句、处理结果

DriverManager类:根据数据库的不同,管理相应的JDBC驱动   注:它位于JDK的java.sql包中

Connection接口:负责连接数据库并担任传输数据的任务

Statement接口:位于Connection接口中,负责执行SQL语句

PreparedStament接口:Statement的子接口,同样负责执行SQL语句,但它比Statement的具有更好的安全性、高性能、高效率及可维护性的优点。开发中推荐使用此接口,因PreparedStatement它使用的是预编译语句,不会和以预编译的SQL语句进行拼接,避免了SQL的注入。具体可看源代码Connection接口中PreparedStatement prepareStatement(String sql)的注解

ResultSet接口:负责保存和Statement或者PreparedStatement执行后所产生的查询结果

Connection接口有两种连接方式:JDBC-ODBC桥接和纯Java驱动

JDBC-ODBC:它通过ODBC与数据库进行连接

纯Java驱动:它直接同数据库进行连接,由JDBC驱动直接访问数据库,具跨平台特点。但由于技术原因需要数据库厂商和第三方中间件自己提供JDBC驱动。   注:此类JDBC驱动只对应一种类型数据库,且当数据库进行升级后,有些需要进行更换JDBC驱动

驱动版本不匹配又是运行时会报version本版的错误,如下注意红框处(version 51.0):

一般决解此问题,更换相匹配的jdk

常见version和jdk匹配版本如下:

version 52.0        JDK 8.0(也可以理解为JDK1.8)

version 51.0        JDK 7.0(也可以理解为JDK1.7)

version 50.0        JDK 1.6

version 49.0        JDK 1.5

接下来,来一个纯java建立连接并关闭的示例

此示例需要注意:我使用的是sqlserver数据库,并且需要下载sqlserver数据库的JDBC驱动

在使用Connection建立连接和关闭各连接是需要加长try{}catch{}进行捕获异常并处理一场,或者将他继续往上抛异常,(异常可以看上一篇的讲解),否则会报如:Unhandled exception:java.SQLException

报此错误原因是因为在DriverManager源代码类中,它的方法声明了一个SQLException的一个异常,所以此时需要我们进行处理此异常,具体代码如图下:

示例代码:

DemoOneTest.class

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException; public class DemoOneTest {
public static void main(String[] args) {
/**
* 使用jdbc纯java的方式建立连接
*/
Connection conn = null;
//加载驱动
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//建立连接
try {

        //DriverManager类是JDBC的管理层,作用于用户和驱动程序之间,DriverManager类跟踪可用的驱动程序,并在数据库和相应的驱动程序之间建立连接。
        //当调用getConnection()方法时,DriverManager类首先从已加载的驱动程序列表中找到一个可以接受该数据库的URL的驱动程序,然后请求该驱动程序使用相关的URL、用户名、密码
        //连接到数据库中建立与数据库的连接,创建连接对象并返回引用

            conn = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=自己数据库的名称", "sa", "123456");
if(null != conn){
System.out.println("建立连接!!!");
}else{
System.out.println("建立失败!!!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
//关闭连接
try {
if (null != conn) {
conn.close();
System.out.println("关闭连接成功!!!");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}

编程的习惯,在我们执行使用完数据库后,最好将它的连接关闭进行释放资源,这样会提高项目的性能

大家都已经练习了,示例一进行数据库的连接和关闭,我们在说一下PreparedStatement对象,之后使用PreparedStatement进行数据库的增、删、改、查、操作吧

创建PreparedStatement对象:通过Connection接口的preparedStatement(String sql)方法来进行PreparedStatment对象,SQL语句可具有一个或者多个输入参数。而这些参数的值都是在SQL语句创建时未指定的,此时我们可以使用?为每个输入的参数作为占位符。为什么会这样,请看Connection接口的源代码,图片如下

设置SQL中每个输入参数的值:通过setXxx()方法来完成。Xxx是与该参数相对应的类型。如:参数为String类型,我们则使用方法为setString().

注意的是setXxx()方法中,会有两个参数是(int parameterIndex, String x)

int paramenterIndex:此参数类型说的是“?”占位符的序号位置(从1开始)

String x :此参数类型说的是,为占位符设置参数的值

具体来源可看如下图片,根据PreparedStatemnt源代码的方法和注解得来的

执行SQL语句:设置完了输入的参数后,我们可以使用PreparedStatement接口的3个执行方法:

1:ResultSet executeQuery():可以执行SQL查询并获得ResultSet对象

2:int executeUpdate():可以执行增加、删除、更新操作,返回值为执行该操作所影响的行数

3:boolean execute():可以执行SQL语句,若结果为ResultSet对象,则返回true;若更新计数或者不存在任何结果,则返回false;

如上介绍了PreparedStatement对象,下面写增、删、改、查的示例了。

使用PreparedStatement对象,增加示例:

Department.class

public class Department {
private int departmentId;
private String departmentName;
public void setDepartmentId(int departmentId){
this.departmentId = departmentId;
}
public int getDepartmentId(){
return departmentId;
}
public void setDepartmentName(String departmentName){
this.departmentName = departmentName;
}
public String getDepartmentName(){
return departmentName;
} }

DemoThreeTest.class

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException; public class DemoThreeTest {
public static void main(String[] args){
Connection connection = null;
PreparedStatement ps = null;
Department department = new Department();
/**
* 加载驱动
*/
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}catch (Exception e){
e.printStackTrace();
}
/**
* 建立连接
*/
try {
connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=Company", "sa", "123456");
String sql = "insert into Department (departmentId,departmentName) values (?,?)";
ps = connection.prepareStatement(sql);
department.setDepartmentId(5);
department.setDepartmentName("研发部");
ps.setInt(1,department.getDepartmentId());
ps.setString(2,department.getDepartmentName());
int id = ps.executeUpdate();
if(id > 0){
System.out.println("插入成功!!!");
}
else{
System.out.println("插入失败!!!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
if(ps != null){
ps.close();
System.out.println("PrepareStatement关闭连接!!!");
}
if(connection != null){
connection.close();
System.out.println("Connection关闭连接!!!");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
} 结果如下:
使用PreparedStatement对象,删除示例:
DemoFourTest.Class
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException; public class DemoFourTest {
public static void main(String[] args){
Connection connection = null;
PreparedStatement ps = null;
Department department = new Department();
/**
* 加载驱动
*/
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}catch (Exception e){
e.printStackTrace();
}
/**
* 建立连接
*/
try {
connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=Company", "sa", "123456");
String sql = "delete Department where departmentId = ?";
ps = connection.prepareStatement(sql);
department.setDepartmentId(5);
ps.setInt(1,department.getDepartmentId());
int id = ps.executeUpdate();
if(id > 0){
System.out.println("删除成功!!!");
}
else{
System.out.println("删除失败!!!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
if(ps != null){
ps.close();
System.out.println("PrepareStatement关闭连接!!!");
}
if(connection != null){
connection.close();
System.out.println("Connection关闭连接!!!");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}

结果如下:

使用PreparedStatement对象,修改示例:
DemoFive.Class
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException; public class DemoFiveTest {
public static void main(String[] args){
Connection connection = null;
PreparedStatement ps = null;
Department department = new Department();
/**
* 加载驱动
*/
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}catch (Exception e){
e.printStackTrace();
}
/**
* 建立连接
*/
try {
connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=Company", "sa", "123456");
String sql = "update Department set departmentName = ? where departmentId = ?";
ps = connection.prepareStatement(sql);
department.setDepartmentId(3);
department.setDepartmentName("营销部");
ps.setString(1,department.getDepartmentName());
ps.setInt(2,department.getDepartmentId());
int id = ps.executeUpdate();
if(id > 0){
System.out.println("修改成功!!!");
}
else{
System.out.println("修改失败!!!");
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
if(ps != null){
ps.close();
System.out.println("PrepareStatement关闭连接!!!");
}
if(connection != null){
connection.close();
System.out.println("Connection关闭连接!!!");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
结果如下:

使用PreparedStatement对象,查询示例:
DemoSixTest.Class

import java.sql.*;

public class DemoSixTest {
public static void main(String[] args){
Connection connection = null;
PreparedStatement ps = null;
ResultSet rs = null;
Department department = new Department();
/**
* 加载驱动
*/
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
}catch (Exception e){
e.printStackTrace();
}
/**
* 建立连接
*/
try {
connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=Company", "sa", "123456");
String sql = "select departmentId, departmentName from department";
ps = connection.prepareStatement(sql);
rs = ps.executeQuery();
if(rs!=null){
while(rs.next()){
System.out.print(rs.getInt("departmentId")+"\t");
System.out.println(rs.getString("departmentName"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
try {
if(rs!= null){
rs.close();
System.out.println("ResultSet关闭连接!!!");
}
if(ps != null){
ps.close();
System.out.println("PrepareStatement关闭连接!!!");
}
if(connection != null){
connection.close();
System.out.println("Connection关闭连接!!!");
}
}catch (Exception e){
e.printStackTrace();
}
}
}
}
结果如下:


好了,刚刚大家看了也练习了这么多的代码,最后给大家讲一下大家都想了解的,SQL注入

为什么会有SQL注入攻击,原因是在使用Statment接口方法时要进行SQL语句的拼接,并且每次调用方法执行SQL语句时,都要进行SQL语句的解析和编译操作,导致可以对SQL截取后注入

具体示例如下:

DemoSevenTest.class

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Scanner; public class DemoSevenTest {
public static void main(String[] args){
Connection connection= null;
Statement statement = null;
Department department = new Department();
ResultSet rs = null; //根据控制台提示输入部门ID和部门名称
Scanner input = new Scanner(System.in);
System.out.println("请输入部门ID:");
int departmentId = input.nextInt();
System.out.println("请输入部门名称:");
String departmentName = input.next();
/**
* 加载驱动
*/
try {
Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} /**
* 建立连接
*/
try {
connection = DriverManager.getConnection("jdbc:sqlserver://localhost:1433;DatabaseName=Company", "sa", "123456");
department.setDepartmentId(departmentId);
department.setDepartmentName(departmentName);
//判断是否正确
statement = connection.createStatement();
String sql = "select departmentId, departmentName from department where departmentId = '"+department.getDepartmentId()+"' and departmentName = '"+department.getDepartmentName()+"'";
rs = statement.executeQuery(sql);
if(rs!=null){
if(rs.next()){
System.out.println("部门ID和部门名称正确!!!");
}else{
System.out.println("部门ID和部门名称不正确!!!");
}
}
}catch (Exception e){
e.printStackTrace();
}
}
} 结果情况:正确

结果情况:错误

当我使用SQL注入,在执行结果情况:错误的,再看一下

其上就是典型的SQL注入攻击!!!

谢谢!!!

 

Java——JDBC的更多相关文章

  1. java jdbc 连接mysql数据库 实现增删改查

    好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...

  2. Java JDBC高级特性

    1.JDBC批处理 实际开发中需要向数据库发送多条SQL语句,这时,如果逐条执行SQL语句,效率会很低,因此可以使用JDBC提供的批处理机制.Statement和PreparedStatemen都实现 ...

  3. Java JDBC下执行SQL的不同方式、参数化预编译防御

    相关学习资料 http://zh.wikipedia.org/wiki/Java数据库连接 http://lavasoft.blog.51cto.com/62575/20588 http://blog ...

  4. Java JDBC批处理插入数据操作

    在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...

  5. Java JDBC批处理插入数据操作(转)

    在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...

  6. java jdbc使用配置文件连接数据库:

    java jdbc使用配置文件连接数据库: 创建后缀名为:.properties的文件,文件内容包括,数据库驱动.连接的数据库地址.用户名.密码…… 以Mysql为例创建config.properti ...

  7. Java JDBC中,MySQL字段类型到JAVA类型的转换

    1. 概述 在使用Java JDBC时,你是否有过这样的疑问:MySQL里的数据类型到底该选择哪种Java类型与之对应?本篇将为你揭开这个答案. 2. 类型映射  java.sql.Types定义了常 ...

  8. Java JDBC连接SQL Server2005错误:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败 及sql2008外围服务器

    转载:Java JDBC连接SQL Server2005错误:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败 错误原因如下: Exception in thread & ...

  9. java jdbc ResultSet结果通过java反射赋值给java对象

    在不整合框架的情况下,使用jdbc从数据库读取数据时都得一个个的get和set,不仅累代码还显得不简洁,所以利用java的反射机制写了一个工具类,这样用jdbc从数据库拿数据的时候就不用那么麻烦了. ...

  10. Java java jdbc thin远程连接并操作Oracle数据库

    JAVA jdbc thin远程连接并操作Oracle数据库 by:授客 QQ:1033553122 测试环境 数据库:linux 下Oracle_11g_R2 编码工具:Eclipse 编码平台:W ...

随机推荐

  1. day26-socket(server和client通信)

    # socket是应用层与TCP/IP协议通信的中间软件抽象层,它是一组接口.它把复杂的TCP/IP协议隐藏到socket #接口的后面,让socket去组织数据,以符合指定的协议. # socket ...

  2. PAT甲级——1006 Sign In and Sign Out

    PATA1006 Sign In and Sign Out At the beginning of every day, the first person who signs in the compu ...

  3. jsonConfig用法

    1.先编写jsonConfig的初始化代码 private JsonConfig jsonConfig; public action构造方法() { jsonConfig = new JsonConf ...

  4. 堆排Heap Sort

    1. #define LeftChild(i) (2*(i)+1) void PercDown(vector<int>&num, int i, int n) { int child ...

  5. ByteCode Instrumentation

    Bytecode Instrumentation 定义 我们首先来看看,什么叫"Instrumentation"?Instrumentation这个词有很多意思,在维基百科中,它是 ...

  6. Leetcode14._最长公共前缀

    题目 编写一个函数来查找字符串数组中的最长公共前缀. 如果不存在公共前缀,返回空字符串 "". 示例 1: 输入: ["flower","flow&q ...

  7. 吴裕雄--天生自然 HADOOP大数据分布式处理:CenterOS 7 多台物理机、虚拟机相互桥连接ping通,并且能够成功连接外网

    选择用于桥接模式下的虚拟交换机,并且要选择对应的有线或者无线的网卡,如果主机是插网线联网的,那就选择有线网卡,如果主机是连无线网络的就选择无线网卡.Realtek PCIe GBE Family Co ...

  8. hdu6582

    题意:给定一个无向图,删除某些边有一定的代价,要求删掉使得最短路径减小,求最小代价. 分析:首先要spfa求出起点到各个点的最短距离.对于一条权值为w,起点为i,终点为j的边,设dis[k]为起点到k ...

  9. better-scroll插件的介绍及使用

    在我们日常的移动端项目开发中,处理滚动列表是再常见不过的需求了,可以是竖向滚动的列表,也可以是横向的,用better-scroll可以帮助我们实现这个 什么是 better-scroll better ...

  10. nodejs 客户端证书设置。

    最近的系统要求较高的安全等级 https+usbkey证书 https的操作很简单 openssl 生成ca 和证书,配置启动即可 生成成功后,类似这样. 类似这样 var options = { k ...