当前位置: 首页 > news >正文

JDBC基础(1)

一、概述

1.1、什么是JDBC

JDBC(Java Database Connectivity,Java数据库连接) 是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问。

简单说就是用Java语言来操作数据库。原来我们操作数据库是在控制台使用SQL语句来操作数据库,JDBC是用Java语言向数据库发送SQL语句。

1.2、JDBC原理

二、JDBC入门

2.1、准备工作

2.1.1、建库建表

2.1.2、新建项目

1、新建Java项目;

2、在项目下新建lib目录;

3、将MySQL驱动jar包拷贝到lib目录下;

4、选中lib目录右键Add as Library -- 单击OK

2.2、建立连接

2.2.1、准备四大参数

 2.2.2、加载驱动

例:

//加载驱动  Class.forName(driverName);

//建立连接  Connection conn = DriverManager.getConnection(url, username,password);

System.out.println(conn);

2.3、获取发送SQL的对象

//先准备好SQL语句 String sql = "";

//创建Statement Statement statement = conn.createStatement();

//发送SQL语句 增删改--executeUpdate(),返回受影响的行数  查--executeQuery(),返回结果集

int result = statement.executeUpdate(sql);

System.out.println("result = " + result);

//关闭 -- 后打开的先关闭

statement.close();

conn.close();

2.4、入门案例_查询_处理结果集

这里可见代码及其注释:

package day35;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class TestSelect {public static void main(String[] args) throws Exception{//四大参数String driverName = "com.mysql.jdbc.Driver";String url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";String user = "root";String password = "123456";//SQLString sql = "select * from 'tb_stu'";//加载驱动Class.forName(driverName);//建立连接Connection conn = DriverManager.getConnection(url, user, password);//获取StatementStatement statement = conn.createStatement();//发送SQLResultSet rSet = statement.executeQuery(sql);//处理结果 next()判断结果集中是否还有内容while (rSet.next()) {//列的标识从1开始int sid = rSet.getInt(1);String sname = rSet.getString(2);String sage = rSet.getString(3);String sgender = rSet.getString(4);//int sid = rSet.getInt("sid"); 也可这样System.out.println(sid + "-" + sname + "-" + sage + "-" + sgender);}//关闭 先进的后关闭rSet.close();statement.close();conn.close();}
}

三、PreparedStatement

3.1、SQL注入

3.1.1、什么是SQL注入

package day35;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;public class TestSelect {public static void main(String[] args) throws Exception{//四大参数String driverName = "com.mysql.jdbc.Driver";String url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";String username = "root";String password = "123456";//假设用户输入的数据String uname = "Peter' OR 1=1 AND `password`='a";//本来不对,但1=1永远对,即为SQL注入,是要处理的!!!!!!!!!!!!!!!!String pwd = "123";//SQLString sql = "select * from 'user' WHERE 'username'='" + username + "' AND 'password'='" + pwd + "'" ;//加载驱动Class.forName(driverName);//建立连接Connection conn = DriverManager.getConnection(url, username, password);//获取StatementStatement statement = conn.createStatement();//发送SQLResultSet rSet = statement.executeQuery(sql);//处理结果 next()判断结果集中是否还有内容if (rSet.next()) {System.out.println("登录成功....");}else{System.out.println("登录失败!!!");}//关闭 先进的后关闭rSet.close();statement.close();conn.close();}
}

3.1.2、如何避免SQL注入

由于编写的SQL语句是在用户输入数据,整合后再进行编译。所以为了避免SQL注入的问题,我们要使SQL语句在用户输入数据前就进行编译成完整的SQL语句,再进行填充数据。

使用PreparedStatement.

3.2、PreparedStatement使用

PreparedStatement继承了Statement接口,执行SQL语句的方法无异。

作用:

预编译SQL语句,效率高。

安全,避免SQL注入。

可以动态的填充数据,执行多个同构的SQL语句。

3.3、解决SQL注入

package day36;import java.sql.*;
//这个版面是重要的,需要背过的!!
public class TestSelect {public static void main(String[] args) throws Exception{//四大参数String driverName = "com.mysql.jdbc.Driver";String url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";String username = "root";String password = "123456";//假设用户输入的数据String uname = "Peter' OR 1=1 AND `password`='a";//本来不对,但1=1永远对,即为SQL注入,是要处理的!!!!!!!!!!!!!!!!String pwd = "123";//SQLString sql = "select * from 'user' WHERE 'username'=? AND 'password'=? " ;//建立连接Connection conn = DriverManager.getConnection(url, username, password);//获取PreparedStatementPreparedStatement statement = conn.prepareStatement(sql);//设置参数,注意:?的索引从1开始statement.setString(1, uname);statement.setString(2, pwd);//发送SQL 增删改-executeUpdate 查-executeQueeryResultSet resultSet = statement.executeQuery();//处理结果if(resultSet.next()){System.out.println("登录成功");}else{System.out.println("登录失败");}//关闭资源resultSet.close();statement.close();conn.close();}
}

把uanme改成Peter即可登录成功。

3.4、PreparedStatement_添加

package day36;import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;public class TestInsert {public static void main(String[] args) throws Exception {//四大参数String driverName = "com.mysql.jdbc.Driver";String url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";String username = "root";String password = "123456";//SQLString sql = "INSERT INTO 'tb_stu'('sname', 'sage', 'sgender') VALUES (?,?,?)";//加载驱动Class.forName(driverName);//建立连接Connection conn = DriverManager.getConnection(url, username, password);//获取PreparedStatementPreparedStatement statement = conn.prepareStatement(sql);//设置参数statement.setObject(1,"zhangsan");statement.setObject(2,20);statement.setObject(3,"male");//发送SQLint result = statement.executeUpdate();//处理结果System.out.println(result);//关闭资源statement.close();conn.close();}
}

只需要改SQL语句和设置参数

3.5、PreparedStatement_查询

package day36;import java.io.IOException;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;public class TestSelect1 {public static void main(String[] args) throws Exception {//四大参数String driverName = "com.mysql.jdbc.Driver";String url = "jdbc:mysql://localhost:3306/mydbjdbc?useSSL=false";String username = "root";String password = "123456";//根据性别查询学生String sql = "SELECT * FROM 'tb_stu' WHERE 'sgender'=?";//加载驱动Class.forName(driverName);//获取连接Connection conn = DriverManager.getConnection(url, username, password);//获取PreparedStatementPreparedStatement statement = conn.prepareStatement(sql);//设置参数 对应SQL语句的,SQL语句没问号时可以没有statement.setObject(1,"male");//发送SQLResultSet resultSet = statement.executeQuery();//处理结果while (resultSet.next()) {Integer sid = resultSet.getInt("sid");String sname = resultSet.getString("sname");int sage = resultSet.getInt("sage");String sgender = resultSet.getString("sgender");System.out.println(sid + " " + sname + " " + sage + " " + sgender);}//关闭资源resultSet.close();statement.close();conn.close();}
}

修改删除省。 。。

4、封装工具类

资源包配置文件:

工具类:

package utils;import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;//工具类 static Arrays Collections
public class JdbcUtil {private static String driverName;private static String url;private static String username;private static String password; static {try {Properties prop = new Properties();//加载配置文件prop.load(new FileInputStream("jdbc.properties"));//初始化四大参数driverName = prop.getProperty("jdbc.driverName");url = prop.getProperty("jdbc.url");username = prop.getProperty("jdbc.username");password = prop.getProperty("jdbc.password");//加载驱动Class.forName(driverName);} catch (IOException e) {throw new RuntimeException(e);} catch (ClassNotFoundException e) {throw new RuntimeException(e);}}//获取连接public static Connection getConnection() throws SQLException {Connection conn = DriverManager.getConnection(url, username, password);return conn;}//关闭资源public static void closeAll(Connection conn, PreparedStatement statement, ResultSet rSet) throws Exception{if(rSet != null){rSet.close();}if(statement != null){statement.close();}if(conn != null){conn.close();}}
}

 测试类:

package test03;import utils.JdbcUtil;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class TestSelect {public static void main(String[] args) throws SQLException {String sql = "SELECT * FROM 'tb_stu' WHERE 'sage'=?";//获取连接Connection conn = JdbcUtil.getConnection();//获取PreparedStatementPreparedStatement statement = conn.prepareStatement(sql);//设置参数statement.setObject(1, 20);//发送SQLResultSet rs = statement.executeQuery();//处理结果while (rs.next()) {int sid = rs.getInt("sid");String sname = rs.getString("sname");int sage = rs.getInt("sage");String sgender = rs.getString("sgender");System.out.println(sid + "\t" + sname + "\t" + sage + "\t" + sgender);}}
}

5、连接池介绍

例子:Druid连接池

Druid是阿里巴巴开源的一个数据源,主要用于java数据库连接池,相比spring推荐的DBCP和hibernate推荐的C3P0,此连接池比较占优势。

准备工作:导入lib等包

使用:

5.1、连接池_工具类

资源包配置文件:

 连接池工具类:

package utils;import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Properties;//工具类 static Arrays Collections
public class JdbcUtil {private static DataSource dataSource;static {try{Properties prop = new Properties();//加载配置文件InputStream in = JdbcUtil.class.getResourceAsStream("/jdbc.properties");prop.load(in);//创建连接池dataSource = DruidDataSourceFactory.createDataSource(prop);}catch(Exception e){e.printStackTrace();}}public static Connection getConnection() throws SQLException {return dataSource.getConnection();}public static void closeAll(Connection conn, PreparedStatement statement, ResultSet resultSet) throws SQLException{if(resultSet != null){resultSet.close();}if(statement != null){statement.close();}if(conn != null){conn.close();}}
}

测试类:

import utils.JdbcUtil;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;public class TestSelect {public static void main(String[] args) throws SQLException {//String sql = "SELECT * FROM 'tb_stu' WHERE 'sage'=?";//获取连接Connection connection = JdbcUtil.getConnection();//获取PreparedStatementPreparedStatement statement = connection.prepareStatement("SELECT * FROM 'tb_stu' WHERE 'sage'=?");//设置参数statement.setObject(1, 5);//发送SQLResultSet rs = statement.executeQuery();//处理结果while (rs.next()) {int sid = rs.getInt("sid");String sname = rs.getString("sname");int sage = rs.getInt("sage");String sgender = rs.getString("sgender");System.out.println(sid + "\t" + sname + "\t" + sage + "\t" + sgender);}//关闭资源JdbcUtil.closeAll(connection, statement, rs);}
}

6、三层架构

表示层(View)

以项目设计举例

 

7、DBUtils

是对JDBC的简单封装,但是它还是被很多公司使用。

主要功能:用来操作数据库,简化JDBC的操作。

在使用的时候要和数据库连接池、MySQL的jar配合使用。

7.1、主要类与方法

QueryRunner 执行sql语句的类

创建QueryRunner

 构造器:QueryRunner(),在事务里面使用。

 构造器:QueryRunner(连接池对象)

update():执行INSERT、UPDATE、DELETE

query():执行SELECT

且还有BeanListHandler(多行的)接口_实体类注意事项,BeanHandler(单行)

此构造器需要一个Class类型的参数,用来把一些指定结果转换成指定类型的javaBean对象

这里举例:

@Test

public void test04() throws SQLException{

String sql = "SELECT * FROM 'tb_stu' WHERE 'age'>?";

Object[] params = {10};

QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource());

List<Student> studentList = qr.query(sql, new BeanListHandler<student>(Student.class), params);

studentList.stream()

                 .forEach(System.out::println);

}

}

此外还有MapListHandler(多行),MapHandler(单行),同理:

//其他代码同上

List<Map<String, Object>> list = qr.query(sql, new MapListHandler(), params);

//List<Map<String, Object>> list = qr.query(sql, new MapHandler(), params);

最后还有ScalarHandler(单行单列):通常用于select count(*) from t_stu语句!结果集是单行单列的!它返回一个Object聚合函数。

@Test

public void test08() throws SQLException{

String sql = "SELECT COUNT(1) FROM 'tb_stu'";

QueryRunner qr = new QueryRunner(JdbcUtil.getDataSource());

Long count = qr.query(sql, new ScalarHandler<long>());

System.out.println(count);

}

}

8、事务

8.1、

MYSQL - TPL

1、事务处理的SQL语句 见mysql基础

2、常见的面试题 背过

Java处理事务 - 在Service层处理事务,不能在Dao层处理事务

1、在JDBC中怎么处理事务 - 方法

2、在dbutils怎么处理事务 - JdbcUtil工具类

8.2、关于事务

8.1、什么是事务?

一个操作序列,这些操作序列要么都执行,要么都不执行,它是一个不可分割的工作单位。

事务要处理的问题,把多个对数据库的操作绑定成一个事务,要么都成功,要么都失败。

8.2、MySQL中处理事务

MySQL中处理事务涉及三个操作:

开启事务 START TRANSACTION;

中间有多个操作 delete update add select 等等

提交事务 COMMIT;

回滚 ROLLBACK;

8.3、事务原理

数据库会为每一个客户端都设立一个空间独立的缓存区(回滚段),一个事务中所有的增删改语句的执行结果都会缓存在回滚段中,只有当事务中所有SQL语句均正常结束(COMMIT),才会将回滚段中的数据同步到数据库。否则无论因为哪种原因失败,整个事务将回滚(ROLLBACK).

8.4、事务特性

原子性 一致性 隔离性 持久性

8.5 事务隔离级别

8.5.1、事务并发读问题

数据被b读取后跑了,之后b的操作是不准的

 

8.5.2、四大隔离级别简介

四、JDBC中处理事务

4.1、相关方法(必须掌握)

以下的方法都是Connection中的方法。

setAutoCommit(boolean) 如果true 表示自动提交,false表示开启事务;

commit()提交事务

rollback()回滚事务

4.2、Dao层处理事务

 

}finally{

   //释放资源

   JdbcUtils.close(conn, null, null);

}

}

4.3、Service层才是处理事务的地方

Service层代码及其注释详解:

 

 可用事务处理方法升级工具类及使用ThreadLocal

相关文章:

  • 快速学习GO语言总结
  • 1.16 Cookie 和 Session
  • Linux进程池详解:从入门到理解
  • 『uniapp』搜索功能+商品列表滚动效果(详细图文注释)
  • 华为OD机试_2025 B卷_数组排列求和(Python,100分)(附详细解题思路)
  • WWDC25中的HDR技术洞察
  • MySQL 锁学习笔记
  • 浏览器拨打电话 nginx代理wss (mod_cti基于FreeSWITCH)
  • 计算机是怎么跑起来的第五章
  • 【医疗电子技术-7.1】动态血压测量技术
  • 人工智能学习18-Pandas-按标签选择
  • 人工智能学习17-Pandas-查看数据
  • 【Linux】Linux多路复用-poll
  • 【LLM Tool Learning】论文分享: Chain-of-Tools
  • 【Python-Day 26】解锁时间魔法:深入解析 time 与 datetime 模块
  • Java-String
  • Python惰性函数与技术总结-由Deepseek产生
  • 【软测】脚本实现 - 网页自动化测试
  • 搜索问答技术概述:基于知识图谱与MRC的创新应用
  • rt-thread的定时器驱动(裸机版本)记录.
  • 做网站销售电话术语/网站推广app软件
  • wordpress注册跳过邮箱验证/河南纯手工seo
  • 律师推广网站排名/aso优化渠道
  • wordpress qq聊天/独立站seo搜索优化
  • 织梦57网站的友情链接怎么做/百度竞价推广的优势
  • 武汉手机网站建设咨询/自动外链工具