什么是JDBC
JDBC全称是Java Database Connectivity(Java数据库连接),是Java连接数据库的标准与规范
-
同一了连接的过程
-
如何执行sql
-
如何接收结果
JDBC接口的实现叫做驱动包
JDBC的操作步骤
-
导入驱动包
-
加载驱动
-
打开连接
-
获取预处理器
-
设置参数
-
执行SQL
-
解析结果
-
关闭连接
Connection connection = null;
try {
//2.加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// DriverManager.registerDriver(new Driver());
//3.打开连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc?serverTimezone=UTC", "root", "root");
//4.获取预处理器
PreparedStatement preparedStatement = connection.prepareStatement("insert into t_user(id,name)values(?,?) ");
//5.设置参数 setInt(第几个参数,值)
preparedStatement.setInt(1,3);
preparedStatement.setString(2,"王五");
//6.执行sql
preparedStatement.execute();//返回布尔类型
// int len = preparedStatement.executeUpdate();
// System.out.println(len);
//7.解析结果
}catch (ClassNotFoundException e){
e.printStackTrace();
}catch (SQLException e){
e.printStackTrace();
}finally {
connection.close();
}
JDBC的使用可以理解为是让数据能永久保存在数据库的一种方法,能让写的程序发生质变,更能贴近于现实社会状况,更符合需求
JDBC实现CRUD
PreparedStatement preparedStatement = connection.prepareStatement("insert into t_user(id,name)values(?,?) ");
//5.设置参数 setInt(第几个参数,值)
preparedStatement.setInt(1,3);
preparedStatement.setString(2,"王五");
//6.执行sql
preparedStatement.execute();//返回布尔类型
PreparedStatement preparedStatement = connection.prepareStatement("delete from t_user where id = ?");
preparedStatement.setInt(1,1);
int len = preparedStatement.executeUpdate();
PreparedStatement preparedStatement = connection.prepareStatement("update t_user set name = ? where id = ?");
preparedStatement.setString(1,"zs");
preparedStatement.setInt(2,2);
int len = preparedStatement.executeUpdate();
PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user");
ResultSet resultSet = preparedStatement.executeQuery();//查询方法
while (resultSet.next()){
int id = resultSet.getInt("id");
String name = resultSet.getString("name");
System.out.println(id+"\t"+name);
}
与数据库的增删改查同理,只是在java中如何实现该功能
JDBC的驱动加载
1.Class.forName("xxx");
2.DriverManager.registerDrver(mew Drover()); //重复加载
3.不显示加载驱动类 //依赖包的配置文件,有的jar包没有该文件
如果没有驱动,JDBC将毫无作用,不能与数据库建立连接
SQL注入
什么是SQL注入
SQL注入是利用SQL拼接的特点而实现的一种攻击方式
SQL注入的案例
select * from t_user where name = 'werewrewrewe' and pwd = ' or 1=1';
注入也可以理解为访问数据库一种特殊的方式
防止SQL注入的方法
使用?占位符形式设置参数
防止SQL注入的原理
内部对参数进行了处理
package com.lxz.jdbc;
import java.sql.*;
import java.util.Scanner;
/**
* SQL注入
*/
public class Demo5 {
public static void main(String[] args){
Scanner sc = new Scanner(System.in);
System.out.println("请输入登录用户名");
String name = sc.nextLine();
System.out.println("请输入登录密码");
String pwd = sc.nextLine();
// Class.forName("com.mysql.cj.jdbc.Driver");
try {
Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc?serverTimezone=UTC", "root", "root");
// PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user where name = ? and pwd = ?");
PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user where name = '"+name+"' and pwd = '"+pwd+"'");
// preparedStatement.setString(1,name);
// preparedStatement.setString(2,pwd);
ResultSet resultSet = preparedStatement.executeQuery();
if (resultSet.next()){
System.out.println("登录成功");
}else{
System.out.println("登录失败");
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
使用java防注入能避免90%的黑客入侵
JDBC中的核心对象
DriverManager: 驱动管理(驱动的注册,打开连接)
Connection: 连接(控制连接,处理事务)
PreparedStatement: 设置参数,执行SQL
PreparedStatement和Statement的联系与区别
联系:两者都是处理器对象,都是负责执行SQL语句父子关系,PreparedStatement是Statement的子接口,拥有更多的API
区别:PreparedStatement可以防止注入,Statement不能防止注入
ResultSet: 结果集(封装了查询语句中返回的所有数据)
1.获取结果数据
2.获取元数据
Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc?serverTimezone=UTC", "root", "root");
Statement statement = connection.createStatement();
String sql = "select * from t_user where id = '1'";
ResultSet resultSet = statement.executeQuery(sql);
if(resultSet.next()){
//1.获取结果集数据
// System.out.println(resultSet.getInt("id"));
// System.out.println(resultSet.getString("name"));
// System.out.println(resultSet.getString("pwd"));
//2.获取元数据
//获取元数据对象
ResultSetMetaData metaData = resultSet.getMetaData();
//获取总列数
int count = metaData.getColumnCount();
for (int i = 1; i < count; i++) {
//获取列名
String columnName = metaData.getColumnName(i);
//获取列类型名称
String columnTypeName = metaData.getColumnTypeName(i);
//获取对应的Java中的数据类型
String columnClassName = metaData.getColumnClassName(i);
System.out.println(columnName);
System.out.println(columnTypeName);
System.out.println(columnClassName);
}
}
结果集是你从数据调用的数据临时存放的位置,想要使用则需从结果集中获取
JDBC事务操作
1.设置手动提交
connection.setAutoCommit(false);
2.提交事务
connection.commit();
3.回滚事务
connection.rollback();
JDBC注册案例
1.输入账号和密码 2.校验账号是否存在 存在:提示用户名已存在,不能重复注册 不存在:完成注册功能,提示注册成功
package com.blb.demo1;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Scanner;
/**
* JDBC注册案例
* 1.输入账号和密码
* 2.校验账号是否存在
* 存在:提示用户名已存在,不能重复注册
* 不存在:完成注册功能,提示注册成功
*/
public class Demo9 {
public static void main(String[] args) throws Exception {
System.out.println("---------用户注册----------");
Scanner sc = new Scanner(System.in);
System.out.println("请输入用户名:");
String name = sc.next();
System.out.println("请输入密码:");
String pwd = sc.next();
//加载驱动
Class.forName("com.mysql.cj.jdbc.Driver");
//打开连接
Connection connection = DriverManager.getConnection("jdbc:mysql:///jdbc?serverTimezone=UTC", "root", "root");
//获取预处理对象
PreparedStatement preparedStatement = connection.prepareStatement("select * from t_user where name = ?");
//设置参数
preparedStatement.setString(1, name);
//执行sql
ResultSet resultSet = preparedStatement.executeQuery();
if(resultSet.next()){
//已存在
System.err.println("用户名已存在,不能重复注册!!!");
}else{
//不存在,插入数据
PreparedStatement preparedStatement1 = connection.prepareStatement("insert into t_user(name, pwd) values(?,?)");
preparedStatement1.setString(1, name);
preparedStatement1.setString(2, pwd);
preparedStatement1.executeUpdate();
System.out.println("注册成功");
}
}
}
有了事务可以避免数据出现脏读,更新丢失,不可重复读,幻读等问题
JDBC登录案例
1.输入账号和密码 2.根据用户名判断是否存在 存在:继续判断密码 密码正确:登录成功 密码错误:密码错误 不存在:提示:用户名不存在
三层架构
什么是三层架构?
三层架构是一种软件设计架构,是一种组织代码的手段和方式。
表现层: 数据的显示或者数据的录入
业务层: 业务的具体操作流程
持久层: 提供数据库表的CRUD
三层架构的优点:
扩展性 复用性
三层架构的缺点:
步骤多,代码多,效率降低
三层架构的实现
目录说明
dao:持久层
entity:实体类
service:业务层
utils:工具类
view:表示层
使用三层架构编写代码,能使代码结构更加清晰,层次明显,对于后期代码编写有巨大帮助
连接池
什么是连接池
一种存放数据库连接的容器,并且拥有动态新增连接,管理连接等功能于一体的容器。
为什么要使用连接池
加快连接的获取速度
合理的应用连接
连接池的分类
dbcp
c3p0
druid
hikaricp
...
连接池的核心对象
DataSource
hikaricp连接池的使用
1.导包
2.创建连接池对象
3.从连接池中获取连接
4.使用连接
5.回收连接
架包https://mvnrepository.com/ 4.0版本
将连接池整合到DBUtils工具类中
连接池底层是由一个个连接组成,连接池的使用使得获取连接时不要获取连接的同时就立马关闭连接,避免了繁琐
Spring-JDBC
一个由Spring团队开发的JDBC的工具类。作用和DBUtils一样,是目前代替DBUtils的产物。
使用步骤
-
导包
-
创建JdbcTemplate工具
-
使用JdbcTemplate完成CRUD操作
JdbcTemplate事务管理
Lombok
可以帮助我们省略set,get,toString这些代码,还提供了日志,异常等功能
使用步骤
1.安装Lombok插件
2.导包
3.使用
Lombok是idea中的插件,可用性不大,容易出现错误