通过Java访问数据库---JDBC
一、JDBC概述
JDBC(Java Data Base Connectivity,java数据库连接)是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成,是Java访问数据库的标准规范,具体的实现由各大数据库厂商来实现。即真正怎么操作数据库还需要具体的实现类,也就是数据库驱动。每个数据库厂商根据自家数据库的通信格式编写好自己数据库的驱动。所以我们只需要会调用 JDBC 接口中的方法即可,数据库驱动由数据库厂商提供。
我使用的是mysql的驱动mysql-connector-java-5.1.37-bin.jar
链接:https://pan.baidu.com/s/1HDQFZIL7MGfjOFdqZBIQ0A
提取码:ab4d
导入jar包过程:
使用 JDBC 的好处:
- 程序员如果要开发访问数据库的程序,只需要会调用 JDBC 接口中的方法即可,不用关注类是如何实现的。
2. 使用同一套 Java 代码,进行少量的修改就可以访问其他 JDBC 支持的数据库。
使用JDBC开发时可能使用的包:
会使用到的包 说明 |
|
java.sql |
所有与 JDBC 访问数据库相关的接口和类 |
javax.sql |
数据库扩展包,提供数据库额外的功能。如:连接池 |
数据库的驱动 |
由各大数据库厂商提供,需要额外去下载,是对 JDBC 接口实现的类 即mysql-connector-java-5.1.37-bin.jar |
JDBC 的核心 API
接口或类 作用 |
|
DriverManager 类 |
|
Connection 接口 |
一个连接对象,可用于创建 Statement 和 PreparedStatement 对象 |
Statement 接口 |
一个 SQL 语句对象,用于将 SQL 语句发送给数据库服务器。 |
PreparedStatement 接口 |
一个 SQL 语句对象,是 Statement 的子接口 |
ResultSet 接口 |
用于封装数据库查询的结果集,返回给客户端 Java 程序 |
二、JDBC实现
JDBC 访问数据库的步骤:
- 注册和加载驱动(可以省略)
- 获取连接DriverManager.getConnection(url,user,password)
- Connection 获取 Statement 对象connection.createStatement()/perpareStatement()
- 使用 Statement / perparedStatement 对象执行 SQL 语句
- 返回结果集
- 释放资源(关闭ResultSet结果集、connection连接和statement语句)
- 释放原则:先开的后关,后开的先关。ResultSet-->Statement-->Connection
- 放在哪个代码块中:finally 块
1. 导入驱动jar包:
https://blog.csdn.net/krismile__qh/article/details/89305380*
*2. 加载和注册驱动:(注:从 JDBC3 开始,目前已经普遍使用的版本。可以不用注册驱动而直接使用。Class.forName 这句话可以省略。)
加载和注册驱动的方法 描述 |
|
Class.forName(数据库驱动实现类) |
加载和注册数据库驱动,数据库驱动由 mysql 厂商提供 "com.mysql.jdbc.Driver"说明是com.mysql.jdbc包下的Driver接口 Driver 接口,所有数据库厂商必须实现的接口,表示这是一个驱动类 |
public class Demo1 {public static void main(String[] args) throws ClassNotFoundException {//抛出类找不到的异常,注册数据库驱动Class.forName("com.mysql.jdbc.Driver");//固定写法}
}
3. 获得连接:DriverManager类
(作用:管理和注册驱动、创建数据库的连接)
1. DriverManager类中的方法:
DriverManager 类中的静态方法 描述 |
|
Connection getConnection (String url, String user, String password) |
通过连接字符串,用户名,密码来得到数据 库的连接对象 |
Connection getConnection (String url, Properties info) |
通过连接字符串,属性对象来得到连接对象 |
2. 通过用户名、密码、URL得到连接对象
代码:Connection con = DriverManager.getConnection(“jdbc:mysql://localhost:3306/mydb”,”root”,”root”);
其中三个参数分别表示:url 需要连接数据库的位置(网址) user用户名 password 密码
url比较复杂,例如mysql的url:jdbc:mysql://localhost:3306/mydb
JDBC规定url的格式由三部分组成,每个部分中间使用冒号分隔。
1.第一部分是jdbc,这是固定的;
2.第二部分是数据库名称,那么连接mysql数据库,第二部分当然是mysql了;
3.第三部分是由数据库厂商规定的,我们需要了解每个数据库厂商的要求,mysql的第三部分分别由数据库服务器的IP地址(localhost)、端口号(3306),以及DATABASE名称(mydb)组成。
3. 使用属性文件和 url 得到连接对象
public static void main(String[] args) throws SQLException {//url 连接字符串String url = "jdbc:mysql://localhost:3306/day24";//属性对象Properties info = new Properties();//把用户名和密码放在 info 对象中info.setProperty("user","root"); info.setProperty("password","root");Connection connection = DriverManager.getConnection(url, info);//com.mysql.jdbc.JDBC4Connection@68de145 System.out.println(connection);
}
4. 获得语句执行平台:Connection 接口
(具体的实现类由数据库的厂商实现,代表一个连接对象)
1. Connection接口下的方法:
Statement接口:
(代表一条语句对象,用于发送 SQL 语句给服务器,用于执行静态 SQL 语句并返回它所执行成结果的对象。)
String sql = "某SQL语句";
获取Statement语句执行平台:Statement stmt = connection.createStatement();
常用方法:
- int executeUpdate(String sql); --执行insert update delete语句.
- ResultSet executeQuery(String sql); --执行select语句.
- boolean execute(String sql); --执行select查询出结果集返回true 执行其他的语句返回false.
处理结果集:ResultSet接口
(封装数据库查询的结果集,对结果集进行遍历,取出每一条记录)
常用方法:
ResultSet 接口中的方法 描述 |
|
boolean next() |
|
数据类型 getXxx() |
|
常用数据类型转换表:
SQL 类型 Jdbc 对应方法 返回类型 |
||
BIT(1) bit(n) |
getBoolean() |
boolean |
TINYINT |
getByte() |
byte |
SMALLINT |
getShort() |
short |
INT |
getInt() |
int |
BIGINT |
getLong() |
long |
CHAR,VARCHAR |
getString() |
String |
Text(Clob) Blob |
getClob getBlob() |
Clob Blob |
DATE |
getDate() |
java.sql.Date 只代表日期 |
TIME |
getTime() |
java.sql.Time 只表示时间 |
TIMESTAMP |
getTimestamp() |
java.sql.Timestamp 同时有日期和时间 |
(注:java.sql.Date、Time、Timestamp(时间戳),三个共同父类是:java.util.Date)
SQL注入问题:
示例:
· 当我们输入以下密码,我们发现我们账号和密码都不对竟然登录成功了
请输入用户名:
newboy
请输入密码:
'a' or '1' = '1'
登录成功,欢迎您:newboy
· 问题分析:
select * from user where name='newboy' and password='a' or '1'='1'
(name='newboy' and password='a') 为假
('1'='1') 真
相当于
select * from user where true; 查询了所有记录
我们让用户输入的密码和 SQL 语句进行字符串拼接。用户输入的内容作为了 SQL 语句语法的一部分,改变了原有 SQL 真正的意义,以上问题称为 SQL 注入。要解决 SQL 注入就不能让用户输入的密码和我们的 SQL 语句进行简单的字符串拼接。
PreparedStatemrnt接口:
PreparedStatement 是 Statement 接口的子接口,继承于父接口中所有的方法。它是一个预编译的 SQL 语句。
PerparedStatement的执行原理:
- 因为有预先编译的功能,提高 SQL 的执行效率。
- 可以有效的防止 SQL 注入的问题,安全性更高。
PreparedStatement 接口中的方法:
PreparedStatement 接口中的方法 描述 |
|
int executeUpdate() |
执行 DML,增删改的操作,返回影响的行数。 |
ResultSet executeQuery() |
执行 DQL,查询的操作,返回结果集 |
PreparedStatement 中设置参数的方法 描述 |
|
void setDouble(int parameterIndex, double x) |
将指定参数设置为给定 Java double 值。 |
void setFloat(int parameterIndex, float x) |
将指定参数设置为给定 Java REAL 值。 |
void setInt(int parameterIndex, int x) |
将指定参数设置为给定 Java int 值。 |
void setLong(int parameterIndex, long x) |
将指定参数设置为给定 Java long 值。 |
void setObject(int parameterIndex, Object x) |
使用给定对象设置指定参数的值。 |
void setString(int parameterIndex, String x) |
将指定参数设置为给定 Java String 值。 |
使用 PreparedStatement 的步骤:
- 编写 SQL 语句,未知内容使用?占位:"SELECT * FROM user WHERE name=? AND password=?";
- 获得 PreparedStatement 对象(传参数sql)
- 设置实际参数:setXxx(占位符的位置, 真实的值)
- 执行参数化 SQL 语句
- 关闭资源
三、JDBC事务的处理
1. 什么是事务
在实际的开发过程中,一个业务操作如:转账,往往是要多次访问数据库才能完成的。转账是一个用户扣钱,另一个用户加钱。如果其中有一条 SQL 语句出现异常,这条 SQL 就可能执行失败。
事务执行是一个整体,所有的 SQL 语句都必须执行成功。如果其中有 1 条SQL 语句出现异常,则所有的SQL 语句都要回滚,整个业务执行失败。
2. API介绍
Connection 接口中与事务有关的方法 说明 |
|
void setAutoCommit(boolean autoCommit) |
参数是 true 或 false 如果设置为 false,表示关闭自动提交,相当于开启事务 start transaction;开启事务 |
void commit() |
提交事务 |
void rollback() |
回滚事务,会回退到开启事务时的状态 |
自动提交事务:
MySQL 默认每一条 DML(增删改)语句都是一个单独的事务,每条语句都会自动开启一个事务,语句执行完毕自动提交事务,MySQL 默认开始自动提交事务
手动提交事务:
MYSQL 中可以有两种方式进行事务的操作:
- 手动提交事务
- 自动提交事务
手动提交事务使用过程:
- 执行成功的情况: 开启事务-->执行多条 SQL 语句-->成功提交事务
- 执行失败的情况: 开启事务-->执行多条 SQL 语句-->事务的回滚
3. 银行转账Java代码案例:
package com.qf;
import com.qf.utils.JdbcUtils; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.SQLException;public class Demo12Transaction {//没有异常,提交事务,出现异常回滚事务public static void main(String[] args) {//1) 注册驱动Connection connection = null; PreparedStatement ps = null;try {//2) 获取连接connection = JdbcUtils.getConnection();//3) 开启事务connection.setAutoCommit(false);//4) 获取到 PreparedStatement//从 jack 扣钱ps = connection.prepareStatement("update account set balance = balance - ? where name=?");ps.setInt(1, 500); ps.setString(2,"Jack"); ps.executeUpdate();//出现异常System.out.println(100 / 0);//给 rose 加钱ps = connection.prepareStatement("update account set balance = balance + ?where ps.setInt(1, 500); ps.setString(2,"Rose"); ps.executeUpdate();//提交事务connection.commit();System.out.println("转账成功");} catch (Exception e) { e.printStackTrace(); try {//事务的回滚connection.rollback();} catch (SQLException e1) { e1.printStackTrace();}System.out.println("转账失败");}finally {//7) 关闭资源JdbcUtils.close(connection,ps);}
}
通过Java访问数据库---JDBC相关推荐
- Java小白修炼手册--第四阶段--JDBC(Java Database Connectivity : Java访问数据库的解决方案 )
目录 JDBC原理 JDBC标准 JDBC是什么 使用JDBC优点 JDBC接 口及数据库厂商实现 JDBC工作原理 Driver ( 驱动程序)接口及驱动类加载 Connection( 连接,关 ...
- java访问数据库方式_java数据库访问(二)—JDBC方式(配合连接池)
上文记录了最基础的JDBC连接数据库的方法,但能看出一个问题,就是要不断的重复去创建connection和关闭connection,如果在对数据库的访问比较频繁的情况下,这种处理方式方式在性能方面是不 ...
- java访问数据库的中间件有哪些_数据库中间件是什么?
面向数据库的中间件是促进与数据库通信的中间件,无论是来自应用程序还是数据库之间. 开发人员通常使用面向数据库的中间件作为从本地或远程数据库提取信息的机制. 例如,为了从Oracle数据库提取信息,开发 ...
- Mybatis零基础教程,Java访问数据库核心操作,详解Spring-boot整合Mybatis持久层!
1.前言 持久层是JavaEE中访问数据库的核心操作,Mybatis是一款优秀的持久层框架,诞生于2010年,2013年迁移至Github.它支持定制化 SQL.存储过程以及高级映射.MyBatis ...
- Java访问数据库的具体步骤:
1.加载(注册)数据库 驱动加载就是把各个数据库提供的访问数据库的API加载到我们程序进来,加载JDBC驱动,并将其注册到DriverManager中,每一种数据库提供的数据库驱动不一样,加载驱动时要 ...
- Java连接数据库(JDBC)之三:java访问数据库MySQL实例
在加载驱动和使用Connection connect=DriverManager.getConnection语句时IDE会提示你使用try-catch语句防止发生异常. package cc.bb.a ...
- MySQL---数据库从入门走向大神系列(七)-Java访问数据库配置及简单使用方法execute
从操作配置文件properties中读取连接字符串,通过该字符串进行数据连接,需要写三个文件其中,两个是java类,一个是后缀名为.properties的文件,该文件放在src工作目录下. 需要准备的 ...
- Java与数据库 —— JDBC标准
JDBC由来与描述 没有JDBC前 开发者想操作数据库,必须需要了解每个数据库对应的数据库驱动程序API,由于每个数据库驱动程序的API都不同,所以当需要迁移数据库时,根本不平滑,需要大量修改与重写 ...
- Java实现数据库jdbc连接测试
若想用java实现数据库连接测试,首先需要添加对应数据库的依赖jar包 代码 public class ConnTest {public static String sqlConn(String da ...
最新文章
- hql中常用函數介紹二
- C#进行Visio二次开发之电气线路停电分析逻辑
- 在ubuntu16.04中一键创建LAMP环境
- 过程中心方法论,事务中心方法论。
- CNKI中银屑病、大肠菌群、内毒素LPS(调研手稿三)
- 网络协议分层及报文格式大全
- Android 读写SDcard (转)
- Windows Embedded Standard 7 帮零售业快速抢占市场
- python配置文件封装_Python configparser模块封装及构造配置文件代码示例
- android访问局域网电脑,如何设置电脑使安卓手机能访问局域网共享的文件
- 服务器session文件什么时候销毁,node中session存储与销毁,及session的生命周期
- html代码在线运行_在线运行html代码
- argis利用gp工具打包tpk切片包
- Sometimes you will never know the true value of a moment until it becomes a memory
- 机器学习基石(林軒田)笔记之十二
- php写火车头采集接口,的这个火车头采集接口我在火车头采集规则里已经写了采集时间的规,迅睿CMS,CodeIgniter技术文档,PHP开发文档,迅睿CMS框架官方教程...
- 递归的算法求1,1,2,3,5,8.......的第30位数是多少,然后求这些数的和.
- javaWeb快速开发框架之Play
- 《麦肯锡方法》读完后的千字感悟
- 肌肉激活度(Muscle Activation)