提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
安装环境
1.jdk17
2.MySQL8
一;JDBC
1.jdbc概述
JDBC指Java数据库连接,是一种标准Java应用编程接口(JAVA API),用来连接Java编程语言和广泛的数据库。 其实就是说,jdbc就是Java用来操作数据库的一个API。
2.常见的JDBC组件
JDBC的API提供了以下接口和类:
Driver接口: 表示java驱动程序接口。所有的具体的数据库厂商要来实现此接口。
Connection conn = driver.connect(url,properties);
connect(url, properties): 连接数据库的方法。
url: 连接数据库的URL
password: 数据库用户密码
DriverManager类: 驱动管理器类,用于管理所有注册的驱动程序
Class<?> aClass = Class.forName("com.mysql.cj.jdbc.Driver");
Driver dr = (Driver) aClass.newInstance();
String url = "jdbc:mysql://localhost:3306/h3?serverTimezone=UTC&useSSL=false";
String user = "root";
String password = "123456";
DriverManager.registerDriver(dr);
Connection connection = DriverManager.getConnection(url,user,password);
registerDriver(driver) : 注册驱动类对象
Connection getConnection(url,user,password): 获取连接对象
Connection接口: 表示java程序和数据库的连接对象。
Statement createStatement() : 创建Statement对象
PreparedStatement prepareStatement(String sql):创建PreparedStatement对象
CallableStatement prepareCall(String sql):创建CallableStatement对象
Statement接口: 用于执行静态的sql语句,就是说不可以注入参数
int executeUpdate(String sql) : 执行静态的更新sql语句(DDL,DML)
ResultSet executeQuery(String sql) :执行的静态的查询sql语句(DQL)
PreparedStatement接口:用于执行预编译sql语句,可以注入参数
//将sql语句放入批处理包
preparedStatement.addBatch();
//执行包里的sql语句
preparedStatement.executeBatch();
//清空一下
preparedStatement.clearBatch();
int executeUpdate() : 执行预编译的更新sql语句(DDL,DML)
ResultSet executeQuery() : 执行预编译的查询sql语句(DQL)
ResultSet接口:用于封装查询出来的数据
//和数据库中的类型一一匹配
resultSet.getObject(); // 不知道列类型的情况下使用
// 如果知道列的类型就使用指定的类型
resultSet.getString();
resultSet.getDate();
resultSet.getInt();
resultSet.getDouble();
resultSet.next() // 移动到下一个
3.实例
MySQL配置文件.properties
user=root
password=123456
//serverTimezone=UTC 修改时区
//rewriteBatchedStatements=true 添加批量操作的功能
//useSSL=false 是说是否使用SSL连接,我们这里选false
url=jdbc:mysql://localhost:3306/h3?serverTimezone=UTC&useSSL=false&rewriteBatchedStatements=true
//不同的版本的driver可能不一样,比如说低版本的可能是com.mysql.jdbc.Driver
//你要是不确定你的版本,可以两种都试一下
driver=com.mysql.cj.jdbc.Driver
JDBCutils方法类
import java.io.FileInputStream;
import java.io.IOException;
import java.sql.*;
import java.util.Properties;
//工具类完成mysql的连接与释放
public class JDBCUtils {
private static String user;
private static String password;
private static String url;
private static String driver;
static {
Properties properties =new Properties();
try {
//这里使用properties配置文件对user,url等进行赋值
properties.load(new FileInputStream("src\\mysql.properties"));
user = properties.getProperty("user");
password = properties.getProperty("password");
url = properties.getProperty("url");
//driver = com.mysql.cj.jdbc.Driver
//但是不同的MySQL版本有不同的写法我这个版本是这么写
//但是低的版本可能是com.mysql.jdbc.Driver
driver = properties.getProperty("driver");
//第一步:加载驱动
//固定写法
Class.forName(driver);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
public static Connection getConnection(){
try {
//第二步获取连接
return DriverManager.getConnection(url,user,password);
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
public static void close(ResultSet set, Statement statement,Connection connection){
try{
if(set != null){
//关闭结果集的连接
set.close();
}
if(statement !=null){
//关闭statement连接
statement.close();
}
if(connection !=null){
//关闭连接
connection.close();
}
}catch (SQLException e){
throw new RuntimeException(e);
}
}
}
JDBCtest测试类
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Properties;
public class JDBCUtils_use {
public static void main(String args[]){
JDBCUtils_use h = new JDBCUtils_use();
h.test();
}
public void test(){
Connection connection = null;
String sql = "update actor set name = ? where id = ?";
PreparedStatement preparedStatement = null;
try{
//获取链接
connection = JDBCUtils.getConnection();
//预加载sql语句
preparedStatement = connection.prepareStatement(sql);
//向sql语句注入值
preparedStatement.setString(1,"周星驰");
//向sql语句注入值
preparedStatement.setInt(2,3);
//执行dml操作
preparedStatement.executeUpdate();
}catch (SQLException e){
e.printStackTrace();
}finally {
//关闭连接
JDBCUtils.close(null, preparedStatement,connection );
}
}
}
二.preparedstament和statement的区别
Statement:直接操作sql,不进行预编译,不带参数;
PreparedStatement:进行预编译,可带参数,还可以批量处理;
下面这张图就可以很好的解释statement不可以带参数的问题,statement要执行的sql语句必须是完整的。
还有一个好处就是preparedstatement可以预防SQL注入的问题
假如登录SQL为select * from user where name='zs' and password='123' ,如果在登录框密码处输入 “123 or 1=1”,那么SQL就成为了select * from user where name='zs and password='123' or 1=1 ,这个时候因为or 后面是1=1,所以不管别人输入什么命令他都会登入成功,比如说你再输入“123456 or 1=1”,他也能够登入成功。但是但我们使用preparedstatement的时候,无论我们往占位符里输入什么,他都会被认为是sql语句之外的东西,比如说继续向上面一样输入 “123 or 1=1”,他就会被识别为passward=”123 or 1=1“,而不是 password='123' or 1=1。
三.批量处理
可以使用preparedstatement对sql语句进行批处理
注意:批处理的时候,你的url后面一定要加rewriteBatchedStatements=true 去添加批量操作的功能,不然是无法执行的。
import java.sql.Connection;
import java.sql.PreparedStatement;
public class pilian {
public static void main(String args[]) throws Exception {
pilian h = new pilian();
h.batch();
}
public void batch() throws Exception{
Connection connection = JDBCUtils.getConnection();
String sql = "insert into sallary values (?,?,?)";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
long start =System.currentTimeMillis();
for(int i = 0;i < 5000;i++){
preparedStatement.setInt(1,i);
preparedStatement.setString(2,"梅艳芳"+i);
preparedStatement.setInt(3,1000);
//将sql语句放入批处理包
preparedStatement.addBatch();
if((i +1) % 1000 ==0){//每满一千条执行一次
preparedStatement.executeBatch();
//清空一下
preparedStatement.clearBatch();
}
}
long end = System.currentTimeMillis();
System.out.println("批量耗时"+(end - start));
JDBCUtils.close(null,preparedStatement,connection);
}
}
四.事务提交控制
如果我们不设置connection.setAutoCommit(false)的话,我们每执行一次sql语句就会提交一次,当我们设置之后,我们可以选择提交的时候,比如说这里,只有当sql1和sql2都成功执行的时候才可以提交 connection.commit()(就是要我们手动提交)。
package SQL1.SQL11;
import SQL1.utils.JDBCUtils;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;
public class transaction {//事务解决
public static void main(String args[]){
transaction h = new transaction();
h.notr();
}
public void notr(){
Connection connection = null;
String sql1 = "update sallary set wealth = wealth -100 where id = 1";
String sql2 = "update sallary set wealth = wealth +100 where id = 2";
PreparedStatement preparedStatement = null;
try{
connection = JDBCUtils.getConnection();
connection.setAutoCommit(false);//不会自动提交
preparedStatement = connection.prepareStatement(sql1);
preparedStatement.executeUpdate();
// int i = 1/0;
preparedStatement = connection.prepareStatement(sql2);
preparedStatement.executeUpdate();
connection.commit();//手动提交
}catch (SQLException e){
try {
//默认回滚到开始状态
connection.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
e.printStackTrace();
}finally {
JDBCUtils.close(null, preparedStatement,connection );
}
}
}
最后
本次的实验就到这里了,如果有讲得不对的或者有所欠缺得地方,欢迎大家来指正与补充,创作不易,还请点个赞再走吧!后面我还会更新其他计算机方面的博客,咱们下篇博客再见!