Java——JDBC
今天给大家更新一篇我自己学习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的更多相关文章
- java jdbc 连接mysql数据库 实现增删改查
好久没有写博文了,写个简单的东西热热身,分享给大家. jdbc相信大家都不陌生,只要是个搞java的,最初接触j2ee的时候都是要学习这么个东西的,谁叫程序得和数据库打交道呢!而jdbc就是和数据库打 ...
- Java JDBC高级特性
1.JDBC批处理 实际开发中需要向数据库发送多条SQL语句,这时,如果逐条执行SQL语句,效率会很低,因此可以使用JDBC提供的批处理机制.Statement和PreparedStatemen都实现 ...
- Java JDBC下执行SQL的不同方式、参数化预编译防御
相关学习资料 http://zh.wikipedia.org/wiki/Java数据库连接 http://lavasoft.blog.51cto.com/62575/20588 http://blog ...
- Java JDBC批处理插入数据操作
在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...
- Java JDBC批处理插入数据操作(转)
在此笔记里,我们将看到我们如何可以使用像Statement和PreparedStatement JDBC API来批量在任何数据库中插入数据.此外,我们将努力探索一些场景,如在内存不足时正常运行,以及 ...
- java jdbc使用配置文件连接数据库:
java jdbc使用配置文件连接数据库: 创建后缀名为:.properties的文件,文件内容包括,数据库驱动.连接的数据库地址.用户名.密码…… 以Mysql为例创建config.properti ...
- Java JDBC中,MySQL字段类型到JAVA类型的转换
1. 概述 在使用Java JDBC时,你是否有过这样的疑问:MySQL里的数据类型到底该选择哪种Java类型与之对应?本篇将为你揭开这个答案. 2. 类型映射 java.sql.Types定义了常 ...
- Java JDBC连接SQL Server2005错误:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败 及sql2008外围服务器
转载:Java JDBC连接SQL Server2005错误:通过端口 1433 连接到主机 localhost 的 TCP/IP 连接失败 错误原因如下: Exception in thread & ...
- java jdbc ResultSet结果通过java反射赋值给java对象
在不整合框架的情况下,使用jdbc从数据库读取数据时都得一个个的get和set,不仅累代码还显得不简洁,所以利用java的反射机制写了一个工具类,这样用jdbc从数据库拿数据的时候就不用那么麻烦了. ...
- Java java jdbc thin远程连接并操作Oracle数据库
JAVA jdbc thin远程连接并操作Oracle数据库 by:授客 QQ:1033553122 测试环境 数据库:linux 下Oracle_11g_R2 编码工具:Eclipse 编码平台:W ...
随机推荐
- 关于jQuery中toggle参数callback函数提前执行问题
通过 jQuery,您可以使用 toggle() 方法来切换 hide() 和 show() 方法. 显示被隐藏的元素,并隐藏已显示的元素: $(selector).toggle(speed,call ...
- Python练习四-浅拷贝&深拷贝
一.数字.字符串不论是浅拷贝.深拷贝都是指向一个地址. a = 1 b = "abc" print (id(a)) print (id(b)) a1 = a b1 = b prin ...
- 关于VLC无法播放rtsp的问题分析
我之前有一篇博客说,怎么通过vlc查日志,方法不知道是不是特别好,传送门:https://www.cnblogs.com/132818Creator/p/11136714.html 虽然在调试窗口上提 ...
- python后端面试第三部分:数据储存与缓存相关--长期维护
1. 列举常见的关系型数据库和非关系型都有哪些?2. MySQL常见数据库引擎及比较?3. 简述数据三大范式?4. 什么是事务?MySQL如何支持事务?5. 简述数据库设计中一对多和多对多的应用场景? ...
- deeplearning.ai 构建机器学习项目 Week 1 机器学习策略 I
这门课是讲一些分析机器学习问题的方法,如何更快速高效的优化机器学习系统,以及NG自己的工程经验和教训. 1. 正交化(Othogonalization) 设计机器学习系统时需要面对一个问题是:可以尝试 ...
- 荼菜的iOS笔记--UIView的几个Block动画
前言:我的第一篇文章荼菜的iOS笔记–Core Animation 核心动画算是比较详细讲了核心动画的用法,但是如你上篇看到的,有时我们只是想实现一些很小的动画,这时再用coreAnimation就会 ...
- 使用iframe的好处与坏处详细比拼
一.使用iframe的坏处 1.搜索引擎的蜘蛛不会识别在iframe中被调用的图片.文本.url等内容的,因为该内容不属于该页面,只是访问的时候被临时的调用,而且在SEO建议中也有提到:"f ...
- 经典题型-打印小星星(python)
# * # * * # * * * # * * * * # * * * * * x = 0 while x < 5: x += 1 # 每次循环需要给y赋值0.清空y中存储的值 y = 0 wh ...
- maven中 pom.xml与properties等配置文件之间互相读取变量
问题由来: 最近公司的maven项目需要改进,希望把该项目依赖的一系列artifact放到properties文件中,这样做的目的是是为了很容易看到四月份release和七月份的release,它们所 ...
- 吴裕雄--天生自然HTML学习笔记:HTML 统一资源定位器(Uniform Resource Locators)
URL 是一个网页地址. URL可以由字母组成,如"runoob.com",或互联网协议(IP)地址: 192.68.20.50.大多数人进入网站使用网站域名来访问,因为 名字比数 ...




