首页 >> 大全

测试方向基础——JDBC数据库连接技术浅析

2023-11-20 大全 26 作者:考证青年

DBC数据库连接技术浅析

数据库简介

没有文件以前,数据的存储方式以内存为主,无法长期保存。文件系统的产生,数据可以长期保存在文件中。常见的文件类型:

(1)纯文本:没有格式要求

(2)数据传输格式:html,xml,json,规定一定的规范的纯文本文件

(3)制定公司特定格式:excel,csv等

(4)专门做数据存储的公司:mysql,,,DB2等

关于数据库:

数据库服务器:硬件

数据库服务、数据库客户端:软件

命令行:sql语句; 客户端软件:不唯一;数据库的名字:一般代表某一个应用程序

数据库的主要职能:保存大量数据、检索数据、数据维护(备份、压缩等)

常见数据库:MySql, , ,,通用语言都是SQL

SQL是 Query (结构化查询语言)的缩写,SQL是专为数据库而建立的操作命令集,是一种功能齐全的数据库语言

SQL对数据库的操作:

(1)数据定义:称为“SQL DDL”,定义数据库的逻辑结构,包括定义数据库、基本表、视图和索引

(2)数据操纵:称为“SQL DML”,其中包括数据查询和数据更新两大类操作,其中数据更新又包括插入、删除和更新

(3)数据控制:称为“DCL”,对用户访问数据的控制有基本表和视图的授权、完整性规则的描述,事务控制语句等

(4)其他要素:规定SQL语句在宿主语言的程序中使用的规则

数据控制:

(1)安全性控制:授权—>GRANT, 回收---->…

(2)完整性控制:数据库的完整性是指数据的正确性和相容性,主要防止语义上不正确的数据进入数据库。

(3)事务控制:事务提交:; 事务撤销:…

(4)并发控制:数据库作为共享资源,允许多个用户程序并行地存取数据**。当多个用户并行地操作数据库时,需要通过并发控制对它们加以协调、控制,以保证并发操作的正确执行,并保证数据库的一致性**,LOCK TABLE 表名(或表名集合)IN ……

Java中JDBC的基本操作

JDBC的概念:是由一组Java语言编写的类和接口组成,是一种用于执行SQL语句的规范 官网链接

JDBC API(API: 应用程序编程接口)提供两类主要接口:

(1)面向开发人员的java.sql程序包,使得Java程序员能够进行数据库连接,执行SQL查询,并得到结果集合

(2)面向底层数据库厂商的JDBC

创建JDBC应用的步骤:

(1)加载数据库的驱动程序(首先引入数据库驱动的jar包)

下载地址

Class.("com.mysql.jdbc.");

(2)建立数据库连接

(3)执行数据库操作SQL

stmt = conn.();

rs = stmt.(sql);

(4)得到进行结果处理

(5)关闭数据库连接。

:是JDBC的管理层,管理一组JDBC驱动程序的基本服务。类的主要作用:追踪可用的驱动程序,并在数据库和相应驱动程序之间建立连接。调用.()方法将建立与数据库的连接,得到与数据库连接的对象

(1) 类是JDBC规范中最核心的类,对象和对象等都直接或者间接的来源于它

(2)对象表示与特定数据库的连接(会话)。

1)得到对象的方法:

();

( sql); 【该方法返回一个对象,并能把sql语句提交到数据库进行预编译】

( sql)

2)为了保证数据库事务的原子性,可以设置手动提交事务

补充该类的两个方法:

()进行当前业务开始以来的所有变化;

()放弃当前业务开始以来的所有改变。

是向数据库提交SQL语句并返回相应结果的工具。语句可以是SQL查询、修改、插入或者删除

(1)接口:防止SQL注入攻击(使用占位符“?”); 提高SQL的执行性能(在执行之前有预处理); 避免使用SQL方言; 提高JDBC中有关SQL代码的可读性。

(2)接口用于执行SQL存储过程的接口

(3)常用方法:

* :执行给定SQL语句,可能返回多条结果

* :执行给定的 SQL 语句,该语句返回单个 对象

* 执行,该语句可能为 、 或 DELET给定 SQL 语句

* :获取生成此 对象的 对象

* close:立即释放此 对象的数据库和 JDBC 资源,而不是等待该对象自动关闭时发生此操作

* :获取结果集合的行数

* :获取驱动程序等待 对象执行的秒数

类:是的子接口。用类效率会更高。

实例要通过对象调用( sql)方法获得。

常用方法:

用于执行 SQL 存储过程的接口

继承了接口,所以也继承了的方法(很少用)

:表示数据库结果集的数据表,通常通过执行查询数据库的语句生成。

其对象具有指向其当前数据行的光标

常用方法: (int ):以 Java 编程语言中 的形式获取此 对象的当前行中指定列的值

while (rs.next()) {System.out.println(rs.getString("name"));
}

常用方法:

关于关闭数据库的连接,一共有三处:

检测是否关闭,否则关闭

检测是否关闭,否则关闭

检测是否关闭,否则关闭

if(rs!=null)try{rs.close();}catch(Exception e){e.printStackTrace();}
if(stmt!=null)try{stmt.close();}catch(Exception e){e.printStackTrace();}
if(conn!=null)try{conn.close();}catch(Exception e){e.printStackTrace();}

数据库造作的完整封装(DAO) 所以我们对于一张表的所有操作,在Java程序中体现到了一个实体类的所有的操作。

一般标准工程中一个实体类会有一个对应的DAO类(Data ),来进行这个类的所有的操作。

下面也都是代码的栗子了:

创建一个数据库

package xxx.www.xhx;import java.net.CookieHandler;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;//创建数据库
public class Demo1 {public static void main(String[] args) {String connUrl = "jdbc:mysql://127.0.0.1:3306";String driverStr = "com.mysql.jdbc.Driver";Statement stmt = null;Connection con = null;try {// 1.加载驱动Class.forName(driverStr);// 2.建立数据库的连接con = DriverManager.getConnection(connUrl, "root", "123456");if (!con.isClosed()) {System.out.println("数据库连接成功");// 3.使用statement执行SQL语句stmt = con.createStatement();boolean flag = stmt.execute("create database demo1112");// 创建一个数据库// 4.对执行结果进行处理if (flag) {System.out.println("数据库创建成功");} else {System.out.println("数据库创建失败");}}} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();} finally {try {// 5.关闭数据库的连接if (stmt != null) {stmt.close();}if (con != null) {con.close();}} catch (Exception e) {// TODO: handle exception}}}
}

查询

在创建的数据库中,可以加入一个表,我这里命名为, 下面代码用来查询表中的信息。

提示,URL后的?=true&=utf-8&=true或者仅加上?=true是因为警告:在没有SSL连接的情况下建立ssl连接不建议使用服务器的身份验证。此用此方法,仅仅是初学,不同太在意。

package xxx.www.xhx;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;//查询
public class Demo2 {public static void main(String[] args) throws ClassNotFoundException, SQLException {String connUrl = "jdbc:mysql://127.0.0.1:3306/test0509?useUnicode=true&characterEncoding=utf-8&useSSL=true";String driverStr = "com.mysql.jdbc.Driver";String querySql = "select id,name as username,password,age from user";Class.forName(driverStr);Connection conn = DriverManager.getConnection(connUrl, "root", "123456");Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(querySql);// 执行sql语句while (rs.next()) {int id = rs.getInt(1);// 对应的查询结果的第几列String name = rs.getString("username");// 形参是字段名String password = rs.getString("password");System.out.println("---" + id + "---" + name + "----" + password);}rs.close();stmt.close();conn.close();}
}

打印出来的效果如下:

下面基于此运行结果,示例几个常用的方法。

package xxx.www.xhx;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;//查询
public class Demo2 {public static void main(String[] args) throws ClassNotFoundException, SQLException {String connUrl = "jdbc:mysql://127.0.0.1:3306/test0509?useSSL=true";String driverStr = "com.mysql.jdbc.Driver";String querySql = "select id,name as username,password,age from user";Class.forName(driverStr);Connection conn = DriverManager.getConnection(connUrl, "root", "123456");Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(querySql);// 执行sql语句// ResultSet 指针初始值在第一行之前rs.absolute(3);// 指针定位到第三行System.out.println(rs.getString("username")); // 第三行打印出tom3rs.beforeFirst(); // 指针定位到第一行之前rs.next();// 指针定位到下一行,即第一行,应该为tom1System.out.println(rs.getString("username"));rs.afterLast();// 指针定位到最后一行之后rs.previous();// 指针向前移动一行,即tomSystem.out.println(rs.getString("username"));rs.close();stmt.close();conn.close();}
}

结果如下:

查询结果的列名获取。

package xxx.www.xhx;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;//查询
public class Demo2 {public static void main(String[] args) throws ClassNotFoundException, SQLException {String connUrl = "jdbc:mysql://127.0.0.1:3306/test0509?useSSL=true";String driverStr = "com.mysql.jdbc.Driver";String querySql = "select id,name as username,password,age from user";Class.forName(driverStr);Connection conn = DriverManager.getConnection(connUrl, "root", "123456");Statement stmt = conn.createStatement();ResultSet rs = stmt.executeQuery(querySql);// 执行sql语句ResultSetMetaData metaData = rs.getMetaData(); //返回结果的列名int count = metaData.getColumnCount();System.out.println(count);System.out.println(metaData.getColumnLabel(2));// as之后的别名System.out.println(metaData.getColumnName(2));// as之前的原列名rs.close();stmt.close();conn.close();}
}

结果如下:

在此,我们需要了解一个问题:SQL注入问题。在此就浅浅的了解一下吧。举个例子:

插入or 1 = 1 --后,所有信息都会被查出。

上面那一大堆类中,有浅浅的一个细节,hh,你品,你慢慢品,就是得到对象,他会把sql语句提交到数据库进行预编译。效率更高一点,更安全些。

package xxx.www.xhx;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;import javax.naming.spi.DirStateFactory.Result;public class Demo4 {public static void main(String[] args) throws SQLException {String sql = "select count(*) from user where name = ? and password = ?";// 这个问号就相当于一个占位符Connection conn = DBUtils.openConnection();PreparedStatement pStatement = conn.prepareStatement(sql);// 普通的一个查询pStatement.setString(1, "tom1");// 1表示第一个占位符pStatement.setString(2, "123");// 2表示第二个占位符ResultSet rSet = pStatement.executeQuery();// 返回结果// 因为只有一行,我们用if即可。超过一行就得用循环rSet.next(); // 移动到第一行System.out.println(rSet.getInt(1));// SQL注入查询pStatement.setString(1, "'or 1=1 -- '");// 1表示第一个占位符pStatement.setString(2, "123");// 2表示第二个占位符rSet = pStatement.executeQuery();// 返回结果// 因为只有一行,我们用if即可。超过一行就得用循环rSet.next(); // 移动到第一行System.out.println(rSet.getInt(1));//关闭连接}
}

效果如下:

插入

封装的意识:我们不妨把建立连接,关闭连接的代码装在一个类里。

package xxx.www.xhx;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;public class DBUtils {static String connUrl = "jdbc:mysql://127.0.0.1:3306/test0509?useSSL=true";static String driverStr = "com.mysql.jdbc.Driver";static {try {Class.forName(driverStr);} catch (ClassNotFoundException e) {// TODO Auto-generated catch blocke.printStackTrace();}}public static Connection openConnection() {Connection conn = null;try {conn = DriverManager.getConnection(connUrl, "root", "123456");} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}return conn;}public static void closeCoonection(Connection conn) {if (conn != null) {try {conn.close();} catch (SQLException e) {// TODO Auto-generated catch blocke.printStackTrace();}}}
}

插入一条数据

package xxx.www.xhx;import java.lang.Thread.State;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;//插入
public class Demo3 {public static void main(String[] args) throws SQLException {String insert_sql="INSERT INTO user(name, password, age) "+ "VALUES ('tom13', '123', '20')";Connection conn = DBUtils.openConnection();Statement stmt = conn.createStatement();int count = stmt.executeUpdate(insert_sql);//影响了多少行System.out.println(count);stmt.close();DBUtils.closeCoonection(conn);}
}

输出为1.

用实现插入:

package xxx.www.xhx;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;import com.mysql.jdbc.Driver;public class Demo5 {public static void main(String[] args) throws ClassNotFoundException, SQLException {Class.forName("com.mysql.jdbc.Driver");String connStr = "jdbc:mysql://127.0.0.1:3306/test0509?useSSL=true";String sql = "INSERT INTO  user (name,password,age) VALUES (?, ?, ?)";Connection connection = DriverManager.getConnection(connStr, "root", "123456");PreparedStatement pstmt = connection.prepareStatement(sql);for (int i = 15; i < 29; i++) {pstmt.setString(1, "tom" + i);pstmt.setString(2, "11112333");pstmt.setInt(3, 33);int count = pstmt.executeUpdate();// 不放循环里,只插入一次}pstmt.close();connection.close();}
}

查看表,可以发现插入成功:

更新操作,只需要修改sql语句即可

user set age =?

更新操作封装时,可能出现参数个数不确定的问题,浅浅给出一个代码,不想看就别看了。

public static int update(String sql, Object...objects) {return 0;}

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了