19JDBC初体验
一、JDBC常用类和接口
JDBC(Java DataBase Connectivity,java数据库连接)是一种用于执行SQL语句的Java API。JDBC是Java访问数据库的标准规范,可以为不同的关系型数据库提供统一访问,它由一组用Java语言编写的接口和类组成。
JDBC与数据库驱动的关系:接口与实现类的关系。
二、JDBC常用类和接口
JDBC有关的类:都在java.sql 和 javax.sql 包下.
接口在Java中是用来定义 `行为规范的`. 接口必须有实现类.
JDBC规范(四个核心对象):
DriverManager:用于注册驱动
Connection: 表示与数据库创建的连接
Statement: 操作数据库sql语句的对象
ResultSet: 结果集或一张虚拟表
// JDBC 初体验
@Test
public void demo01() throws SQLException {
// 1. 装载驱动
DriverManager.registerDriver(new Driver());
// 2. 建立连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "111");
// 3. 操作数据
String sql = "select * from user;";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
String email = rs.getString("email");
System.out.println(id + " : " + username + " : " + password + " : " + email);
}
// 4. 释放资源
rs.close();
stmt.close();
conn.close();
}
// JDBC 初体验
@Test
public void demo01() throws SQLException {
// 1. 装载驱动
DriverManager.registerDriver(new Driver());
// 2. 建立连接
Connection conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb", "root", "111");
// 3. 操作数据
String sql = "select * from user;";
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(sql);
while (rs.next()) {
int id = rs.getInt("id");
String username = rs.getString("username");
String password = rs.getString("password");
String email = rs.getString("email");
System.out.println(id + " : " + username + " : " + password + " : " + email);
}
// 4. 释放资源
rs.close();
stmt.close();
conn.close();
}
// 配置文件的名字 jdbc.properties
#mysql
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC&characterEncoding=utf-8
user=root
password=111
// 配置文件的名字 jdbc.properties
#mysql
driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb?serverTimezone=UTC&characterEncoding=utf-8
user=root
password=111
public class JDBCUtils {
// 属性
private static String driverClass;
private static String url;
private static String username;
private static String password;
// 什么时候加载外部配置文件最合适 ???
// 特点1 : 随着类的加载而加载.
// 特点2 : 静态代码块只在类加载的被执行一次. 仅一次.
static {
Properties prop = new Properties();
try {
prop.load(new FileReader("jdbc.properties"));
// 如果程序执行到这里, 说明外部资源文件加载成功, 需要给我们的静态属性赋值
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
// 直接执行加载驱动
loadDriver();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件资源加载失败!");
}
}
// 加载驱动
public static void loadDriver() {
try {
// 1. 加载驱动
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
// e.printStackTrace();
// 驱动加载失败!
throw new RuntimeException("驱动加载失败!");
}
}
// 建立连接
public static Connection getConnection() throws SQLException {
// 2. 建立连接
return DriverManager.getConnection(url, username, password);
}
// 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
// 4. 释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
// 将 rs 清空
rs = null;
}
// 直接调用
release(conn, stmt);
}
public static void release(Connection conn, Statement stmt) {
// 4. 释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
public class JDBCUtils {
// 属性
private static String driverClass;
private static String url;
private static String username;
private static String password;
// 什么时候加载外部配置文件最合适 ???
// 特点1 : 随着类的加载而加载.
// 特点2 : 静态代码块只在类加载的被执行一次. 仅一次.
static {
Properties prop = new Properties();
try {
prop.load(new FileReader("jdbc.properties"));
// 如果程序执行到这里, 说明外部资源文件加载成功, 需要给我们的静态属性赋值
driverClass = prop.getProperty("driverClass");
url = prop.getProperty("url");
username = prop.getProperty("username");
password = prop.getProperty("password");
// 直接执行加载驱动
loadDriver();
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException("文件资源加载失败!");
}
}
// 加载驱动
public static void loadDriver() {
try {
// 1. 加载驱动
Class.forName(driverClass);
} catch (ClassNotFoundException e) {
// e.printStackTrace();
// 驱动加载失败!
throw new RuntimeException("驱动加载失败!");
}
}
// 建立连接
public static Connection getConnection() throws SQLException {
// 2. 建立连接
return DriverManager.getConnection(url, username, password);
}
// 释放资源
public static void release(Connection conn, Statement stmt, ResultSet rs) {
// 4. 释放资源
if (rs != null) {
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
// 将 rs 清空
rs = null;
}
// 直接调用
release(conn, stmt);
}
public static void release(Connection conn, Statement stmt) {
// 4. 释放资源
if (stmt != null) {
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
stmt = null;
}
if (conn != null) {
try {
conn.close();
} catch (SQLException e) {
e.printStackTrace();
}
conn = null;
}
}
}
@Test
public void test_update() {
Connection conn = null;
Statement stmt = null;
try {
// 2. 建立连接
conn = JDBCUtils.getConnection();
// 3. 操作数据
String sql = "update user set username = 'zhaoliu', password = '123', email = 'zhaoliu@youjian.cn' where id = 4;";
stmt = conn.createStatement();
int affectedRowNum = stmt.executeUpdate(sql);
System.out.println(affectedRowNum);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 释放资源
JDBCUtils.release(conn, stmt);
}
}
@Test
public void test_delete() {
Connection conn = null;
Statement stmt = null;
try {
// 1. 建立连接
conn = JDBCUtils.getConnection();
// 2. 操作数据
String sql = "delete from user where id = 5;";
stmt = conn.createStatement();
int affectedRowNum = stmt.executeUpdate(sql);
System.out.println(affectedRowNum);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 释放资源
JDBCUtils.release(conn, stmt);
}
}
@Test
public void test_insert() {
Connection conn = null;
Statement stmt = null;
try {
// 1. 建立连接
conn = JDBCUtils.getConnection();
// 2. 操作数据
String sql = "insert into user values(null, 'xiaoqi', '123', 'xiaoqi@youjian.cn');";
stmt = conn.createStatement();
int affectedRowNumber = stmt.executeUpdate(sql);
System.out.println(affectedRowNumber);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 释放资源
JDBCUtils.release(conn, stmt);
}
}
// 以上使用时 在进行查询的操作时 有可能会出现 sql注入问题
// 解决SQL注入:使用PreparedStatement 取代 Statement
// PreparedStatement 解决SQL注入原理,运行在SQL中参数以?占位符的方式表示
// select * from user where username = ? and password = ? ;
// 将带有?的SQL 发送给数据库完成编译 (不能执行的SQL 带有?的SQL 进行编译 叫做预编译),在SQL编译后发现缺少两个参数
// PreparedStatement 可以将? 代替参数 发送给数据库服务器,因为SQL已经编译过,参数中特殊字符不会当做特殊字符编译,无法达到SQL注入的目的
/************ JDBC 数据库连接操作 ***************/
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
// 1. 建立连接
conn = JDBCUtils.getConnection();
// 2. 操作数据
String sql = "select * from user where username = ? and password = ?;";
stmt = conn.prepareStatement(sql);
// 设置sql语句的参数
stmt.setString(1, username);
stmt.setString(2, password);
// 执行sql语句
rs = stmt.executeQuery();
// 判断返回的结果
if (rs.next()) {
// 登录成功
int id = rs.getInt("id");
String u_name = rs.getString("username");
String u_pwd = rs.getString("password");
String email = rs.getString("email");
System.out.println(id + " : " + u_name + " : " + u_pwd + " : " + email);
System.out.println("登录成功!");
} else {
// 登录失败
System.out.println("登录失败! 用户名或密码错误!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 3. 释放资源
JDBCUtils.release(conn, stmt, rs);
}
}
}
x
@Test
public void test_update() {
Connection conn = null;
Statement stmt = null;
try {
// 2. 建立连接
conn = JDBCUtils.getConnection();
// 3. 操作数据
String sql = "update user set username = 'zhaoliu', password = '123', email = 'zhaoliu@youjian.cn' where id = 4;";
stmt = conn.createStatement();
int affectedRowNum = stmt.executeUpdate(sql);
System.out.println(affectedRowNum);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 释放资源
JDBCUtils.release(conn, stmt);
}
}
@Test
public void test_delete() {
Connection conn = null;
Statement stmt = null;
try {
// 1. 建立连接
conn = JDBCUtils.getConnection();
// 2. 操作数据
String sql = "delete from user where id = 5;";
stmt = conn.createStatement();
int affectedRowNum = stmt.executeUpdate(sql);
System.out.println(affectedRowNum);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 释放资源
JDBCUtils.release(conn, stmt);
}
}
@Test
public void test_insert() {
Connection conn = null;
Statement stmt = null;
try {
// 1. 建立连接
conn = JDBCUtils.getConnection();
// 2. 操作数据
String sql = "insert into user values(null, 'xiaoqi', '123', 'xiaoqi@youjian.cn');";
stmt = conn.createStatement();
int affectedRowNumber = stmt.executeUpdate(sql);
System.out.println(affectedRowNumber);
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 4. 释放资源
JDBCUtils.release(conn, stmt);
}
}
// 以上使用时 在进行查询的操作时 有可能会出现 sql注入问题
// 解决SQL注入:使用PreparedStatement 取代 Statement
// PreparedStatement 解决SQL注入原理,运行在SQL中参数以?占位符的方式表示
// select * from user where username = ? and password = ? ;
// 将带有?的SQL 发送给数据库完成编译 (不能执行的SQL 带有?的SQL 进行编译 叫做预编译),在SQL编译后发现缺少两个参数
// PreparedStatement 可以将? 代替参数 发送给数据库服务器,因为SQL已经编译过,参数中特殊字符不会当做特殊字符编译,无法达到SQL注入的目的
/************ JDBC 数据库连接操作 ***************/
Connection conn = null;
PreparedStatement stmt = null;
ResultSet rs = null;
try {
// 1. 建立连接
conn = JDBCUtils.getConnection();
// 2. 操作数据
String sql = "select * from user where username = ? and password = ?;";
stmt = conn.prepareStatement(sql);
// 设置sql语句的参数
stmt.setString(1, username);
stmt.setString(2, password);
// 执行sql语句
rs = stmt.executeQuery();
// 判断返回的结果
if (rs.next()) {
// 登录成功
int id = rs.getInt("id");
String u_name = rs.getString("username");
String u_pwd = rs.getString("password");
String email = rs.getString("email");
System.out.println(id + " : " + u_name + " : " + u_pwd + " : " + email);
System.out.println("登录成功!");
} else {
// 登录失败
System.out.println("登录失败! 用户名或密码错误!");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
// 3. 释放资源
JDBCUtils.release(conn, stmt, rs);
}
}
}
<wiz_tmp_tag id="wiz-table-range-border" contenteditable="false" style="display: none;">
19JDBC初体验的更多相关文章
- .NET平台开源项目速览(15)文档数据库RavenDB-介绍与初体验
不知不觉,“.NET平台开源项目速览“系列文章已经15篇了,每一篇都非常受欢迎,可能技术水平不高,但足够入门了.虽然工作很忙,但还是会抽空把自己知道的,已经平时遇到的好的开源项目分享出来.今天就给大家 ...
- Xamarin+Prism开发详解四:简单Mac OS 虚拟机安装方法与Visual Studio for Mac 初体验
Mac OS 虚拟机安装方法 最近把自己的电脑升级了一下SSD固态硬盘,总算是有容量安装Mac 虚拟机了!经过心碎的安装探索,尝试了国内外的各种安装方法,最后在youtube上找到了一个好方法. 简单 ...
- Spring之初体验
Spring之初体验 Spring是一个轻量级的Java Web开发框架,以IoC(Inverse of Control 控制反转)和 ...
- Xamarin.iOS开发初体验
aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAKwAAAA+CAIAAAA5/WfHAAAJrklEQVR4nO2c/VdTRxrH+wfdU84pW0
- 【腾讯Bugly干货分享】基于 Webpack & Vue & Vue-Router 的 SPA 初体验
本文来自于腾讯bugly开发者社区,非经作者同意,请勿转载,原文地址:http://dev.qq.com/topic/57d13a57132ff21c38110186 导语 最近这几年的前端圈子,由于 ...
- 【Knockout.js 学习体验之旅】(1)ko初体验
前言 什么,你现在还在看knockout.js?这货都已经落后主流一千年了!赶紧去学Angular.React啊,再不赶紧的话,他们也要变out了哦.身旁的90后小伙伴,嘴里还塞着山东的狗不理大蒜包, ...
- 在同一个硬盘上安装多个 Linux 发行版及 Fedora 21 、Fedora 22 初体验
在同一个硬盘上安装多个 Linux 发行版 以前对多个 Linux 发行版的折腾主要是在虚拟机上完成.我的桌面电脑性能比较强大,玩玩虚拟机没啥问题,但是笔记本电脑就不行了.要在我的笔记本电脑上折腾多个 ...
- 百度EChart3初体验
由于项目需要在首页搞一个订单数量的走势图,经过多方查找,体验,感觉ECharts不错,封装的很细,我们只需要看自己需要那种类型的图表,搞定好自己的json数据就OK.至于说如何体现出来,官网的教程很详 ...
- Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验
Python导出Excel为Lua/Json/Xml实例教程(二):xlrd初体验 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出E ...
随机推荐
- Microsoft Tech Summit 2018 课程简述:利用 Windows 新特性开发出更好的手绘视频应用
概述 Microsoft Tech Summit 2018 微软技术暨生态大会将于10月24日至27日在上海世博中心举行,这也会是国内举办的最后一届 Tech Summit,2019 年开始会以 Mi ...
- Ubuntu 18.04 根目录为啥只有 4G 大小
其实准确点儿的描述应该是:Ubuntu Server 18.04 ,设置 LVM,安装完成后根目录的容量为什么只有 4G?只有 Server 版有问题,Desktop 版没有问题,Ubuntu 16. ...
- elasticsearch简单操作(二)
让我们建立一个员工目录,假设我们刚好在Megacorp工作,这时人力资源部门出于某种目的需要让我们创建一个员工目录,这个目录用于促进人文关怀和用于实时协同工作,所以它有以下不同的需求:1.数据能够包含 ...
- Python—函数的名称空间
名称空间 又名name space, 顾名思义就是存放名字的地方,存什么名字呢?举例说明,若变量x=1,1存放于内存中,那名字x存放在哪里呢?名称空间正是存放名字x与1绑定关系的地方 名称空间共3种, ...
- vue组件化开发组件拆分原则是什么
原则:可复用.可组合: 两大类:页面组件.功能组件: 除了公共头导航.侧导航.脚部内容,还有:
- c++入门之 再话类
对于类,其结构并不难,但要理解其设计思想也并不容易,在此,我们可以通过下面的代码进一步理解和使用类: # ifndef VECTOR_H_ # define VECTOR_H_ # include & ...
- 第十二届湖南省赛 (B - 有向无环图 )(拓扑排序+思维)好题
Bobo 有一个 n 个点,m 条边的有向无环图(即对于任意点 v,不存在从点 v 开始.点 v 结束的路径). 为了方便,点用 1,2,…,n 编号. 设 count(x,y) 表示点 x 到点 y ...
- Jmeter之上传数据流(图片、文本等)请求
MIME类型~Content-Type: 参数名称~name
- Centos6.x升级内核方法支持Docker
Centos6升级内核方法_百度经验https://jingyan.baidu.com/article/7e4409531bda252fc1e2ef4c.html
- React Native之code-push的热更新(ios android)
React Native之code-push的热更新(ios android) React Native支持大家用React Native技术开发APP,并打包生成一个APP.在动态更新方面React ...