1、第一个JDBC程序
步骤总结:
- 创建测试数据库
- 加载驱动,固定写法
- 连接数据库
- 获得执行SQL的对象statement
- 执行SQL对象去执行SQL
- resultset获得返回结果集
- 释放连接
import java.sql.*;public class Jdbc {public static void main(String args[]) throws ClassNotFoundException, SQLException {//1、加载数据库驱动,固定写法Class.forName("com.mysql.jdbc.Driver");//2、用户信息和url,连接数据库使用//注意:mysql8.0或以上必须在url加上serverTimezone=UTC,否则会出现时区异常,因为8.0加了新特性,安全性也增加了/*useUnicode=true characterEncoding=utf8serverTimezone=UTCuseSSL=true*/String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&&useSSL=true";String username="root";String password="123456";//3、连接数据库,数据库对象connection代表数据库Connection connection= DriverManager.getConnection(url,username,password);//4、执行SQL对象 StatementStatement statement=connection.createStatement();System.out.println("数据库连接成功");//5、执行SQL对象去执行SQL,可能存在结果,查看返回值String sql="SELECT * FROM student";ResultSet resultSet=statement.executeQuery(sql);//ResultSet是一个结果集,通常是一个列表while (resultSet.next()){System.out.println("id:"+resultSet.getObject("id"));System.out.println("name:"+resultSet.getObject("name"));System.out.println("age:"+resultSet.getObject("age"));System.out.println("===============");}//6、释放连接资源connection.close();statement.close();resultSet.close();}
}
2、JDBC对象详解
DriverManager
//DriverManager.registerDriver(new com.mysql.jdbc.Driver());//1、加载数据库驱动,固定写法Class.forName("com.mysql.jdbc.Driver");
//connection 代表数据库
//数据库设置自动提交
//事务提交
//事务回滚
connection.rollback();
connection.commit();
connection.setAutoCommit();
URL
String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC&&useSSL=true";
//mysql-3306
//协议:主机地址端口号/数据库名?参数1&参数2&参数3
//oracle--1521
//jdbc:oracle:thin:@localhost:1521:sid
Statement执行SQL对象
String sql="SELECT * FROM student";String findSql="";String insertSql="";String updateSql="";String delSql="";ResultSet resultSet=statement.executeQuery(sql);statement.executeQuery(findSql);//执行查询statement.executeUpdate(insertSql);//更新、插入、删除都是用这个statement.execute(delSql);//执行任何SQL//ResultSet是一个结果集,通常是一个列表
ResultSet查询的结果集:封装了我们的所有查询 结果
获得指定的数据类型
resultSet.getObject();//不知道列类型的情况下使用//如果知道列的类型就使用指定的类型resultSet.getString();resultSet.getInt();resultSet.getFloat();resultSet.getDate();resultSet.getObject();
遍历,指针
resultSet.beforeFirst();//移动到最前面resultSet.afterLast();//移动到最后面resultSet.next();//移动到下一个数据resultSet.previous();//移动到前一行resultSet.absolute(row);//移动到指定行
释放资源
//6、释放连接资源connection.close();statement.close();resultSet.close();
3、statement对象
jdbc中的statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象想数据库发送增删改查语句即可。
Statement对象的executeUpdate方法,用于向数据库发送增、删、改的sql语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)
Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结构的ResultSet对象
- 工具类
package com.test.util;import java.io.InputStream;
import java.sql.*;
import java.util.Properties;public class JdbcUtils {private static String driver=null;private static String url=null;private static String username=null;private static String password=null;static {try {//获取到配置文件流InputStream inputStream=JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");//用关键字new创建properties对象Properties properties= new Properties();//load方法将流加载进properties对象properties.load(inputStream);//调用方法获取相关属性driver=properties.getProperty("driver");url=properties.getProperty("url");username=properties.getProperty("username");password=properties.getProperty("password");Class.forName(driver);} catch (Exception e) {e.printStackTrace();}}public static Connection getConnection() throws SQLException {return DriverManager.getConnection(url,username,password);}public static void release(Connection connection, Statement statement, ResultSet resultSet){if (resultSet!=null){try {resultSet.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (statement!=null){try {statement.close();} catch (SQLException e) {throw new RuntimeException(e);}}if (connection!=null){try {connection.close();} catch (SQLException e) {throw new RuntimeException(e);}}}
}
- CRUD操作-insert
package com.test.util;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;import static com.test.util.JdbcUtils.*;public class JdbcInsert {public void insert() {Connection connection=null;Statement statement=null;ResultSet resultSet=null;try {//1、获取连接connection = JdbcUtils.getConnection();} catch (SQLException e) {throw new RuntimeException(e);}//2、获得执行SQL对象try {statement = connection.createStatement();String sqlInsert="INSERT INTO student(id,name,age) VALUES (6,'李白',99)";int i=statement.executeUpdate(sqlInsert);if (i>0){System.out.println("插入成功");}} catch (SQLException e) {throw new RuntimeException(e);}//3、关闭资源release(connection,statement,resultSet);}}
- CRUD操作-update
package com.test.util;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import static com.test.util.JdbcUtils.release;
public class JdbcUpdate {public void update() {Connection connection = null;Statement statement = null;ResultSet resultSet = null;try {connection = JdbcUtils.getConnection();} catch (SQLException e) {throw new RuntimeException(e);}try {statement=connection.createStatement();String sqlUpdate="UPDATE student SET name='杜甫' WHERE id=1";int i=statement.executeUpdate(sqlUpdate);if (i>0){System.out.println("更新成功");}} catch (SQLException e) {throw new RuntimeException(e);}release(connection,statement,resultSet);}}
CRUD操作-delete
package com.test.util;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;import static com.test.util.JdbcUtils.release;public class JdbcDel {public void del(){Connection connection=null;Statement statement=null;ResultSet resultSet=null;//1、调用工具类的方法获取连接try {connection=JdbcUtils.getConnection();} catch (SQLException e) {throw new RuntimeException(e);}try {statement=connection.createStatement();String sqlDel="DELETE FROM student WHERE id=3";int i=statement.executeUpdate(sqlDel);if (i>0){System.out.println("删除成功");}} catch (SQLException e) {throw new RuntimeException(e);}release(connection,statement,resultSet);}}
- CRUD操作-selecet
package com.test.util;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;public class JdbcSelect {public void select(){Connection connection=null;Statement statement=null;ResultSet resultSet=null;try {connection=JdbcUtils.getConnection();} catch (SQLException e) {throw new RuntimeException(e);}try {statement=connection.createStatement();} catch (SQLException e) {throw new RuntimeException(e);}String sqlSelect="SELECT * FROM student";try {resultSet=statement.executeQuery(sqlSelect);while (resultSet.next()){System.out.println("id:"+resultSet.getObject("id")+'\t');System.out.println("name:"+resultSet.getObject("name")+'\t');System.out.println("age:"+resultSet.getObject("age")+'\t');System.out.println();}} catch (SQLException e) {throw new RuntimeException(e);}}
}
4、SQL注入问题
sql存在漏洞,会被攻击冬至数据泄露,SQL会被拼接 or
5、PreparedStatement对象
PreparedStatement可以防止SQL注入,效率更高。
package com.test.util;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import static com.test.util.JdbcUtils.release;
public class JdbcPsDel {public void psDel() {Connection connection = null;PreparedStatement preparedStatement = null;ResultSet resultSet=null;try {connection=JdbcUtils.getConnection();//获得连接String sqlDel="DELETE FROM student WHERE id=?";//定义预编译SQL,参数用?代替preparedStatement=connection.prepareStatement(sqlDel);//预编译preparedStatement.setInt(1,3);//手动给参数值int i= preparedStatement.executeUpdate();//执行if (i>0){System.out.println("删除成功");}} catch (SQLException e) {throw new RuntimeException(e);}release(connection,preparedStatement,resultSet);//释放资源}}
6、JDBC操作事务
要么成功,要么失败
- ACID原则
原子性:要么全部完成,要么都不完成
一致性:总数不变
隔离性:多个进程互不干扰
持久性:一旦提交不可逆,持久化到数据库
隔离性问题:
脏读:一个事务读取了另一个没有提交的事务
不可重复读:在同一个事务内,重复读取表中的数据,表数据发生了改变
虚读(幻读):在一个事务内,读取到了别人插入的数据,导致前后读出来结果不一致