JDBC
JDBC编程六步
第一步:注册驱动(作用:告诉Java程序,即将要连接的是哪个品牌的数据库) 第二步:获取连接(表示JVM的进程和数据库之间的通道打开了,这属于进程之间的通信,使用完之后一定要关闭通道) 第三步:获取数据库操作对象(专门执行sql语句的对象) 第四步:执行SQL语句(DQL DML..) 第五步:处理查询结果(只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集) 第六步:释放资源(使用完资源后一定要关闭资源,Java和数据库属于进程之间的通信,开启之后一定要关闭)
五个例子
package com.cedric.JDBC;
import java.sql.*;
/*
JDBC编程六步
*/
public class JDBCTest01 {
public static void main(String[] args) {
Statement statement = null;
Connection connection = null;
try{
//1.注册驱动
Driver driver = new com.mysql.cj.jdbc.Driver();
DriverManager.registerDriver(driver);
//2.获取连接
/*
URL:统一资源定位符(网络中某个资源的绝对路径)
URL中包括:
协议
IP
PORT
资源名
jdbc:mysql://127.0.0.1:3306/cedric
jdbc:mysql:// 协议
127.0.0.1 IP地址
3306 mysql数据库端口号
cedric 具体的数据库实例名
localhost和127.0.0.1都是本机ip地址
*/
String url = "jdbc:mysql://127.0.0.1:3306/cedric";
String user = "root";
String password = "111";
connection = DriverManager.getConnection(url,user,password);
//com.mysql.cj.jdbc.ConnectionImpl@731a74c
System.out.println("数据库连接对象" + connection);
//3.获取数据库操作对象(Statement专门执行sql语句的)
statement = connection.createStatement();
//4.执行sql
String sql = "insert into dept2(DEPTNO,DNAME,LOC) values (30,'ACCOUNTING','SHANGHAI')";
// 专门执行DML语句的(insert delete update)
// 返回值是“影响数据库中的记录条数”
int count = statement.executeUpdate(sql);
System.out.println(count == 1 ? "保存成功" : "保存失败");
//5.处理查询结果集
}catch(SQLException e){
e.printStackTrace();
}finally{
//6.释放资源
// 为了保证资源一定释放,在 finally语句块中关闭资源
// 并且要遵循从小到大依次关闭
// 分别对其try ... catch
if(statement != null){
try{
statement.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
package com.cedric.JDBC;
import java.sql.*;
/*
JDBC完成delete update
*/
public class JDBCTest02 {
public static void main(String[] args) {
Statement statement = null;
Connection connection = null;
try{
// 1.注册驱动
Driver driver = new com.mysql.cj.jdbc.Driver();
DriverManager.registerDriver(driver);
// 2.获取连接
String url = "jdbc:mysql://localhost:3306/cedric";
String user = "root";
String password = "111";
connection = DriverManager.getConnection(url,user,password);
System.out.println("数据库连接对象" + connection);
// 3.获取数据库操作对象
statement = connection.createStatement();
// 4.执行SQL语句
//String sql = "delete from dept2 where DNAME = 'SALES'"; //删除dept2表中部门名称为SALES的部门信息
// JDBC中的sql语句不需要提供分号结束
String sql = "update dept2 set deptno = 40, dname = 'SALES' , loc = 'BEIJING' ";
int count = statement.executeUpdate(sql);
//System.out.println(count != 0 ? "删除成功" : "删除失败");
System.out.println(count != 0 ? "修改成功" : "修改失败");
}catch(SQLException e){
e.printStackTrace();
}finally{
// 6.释放资源
if(statement != null){
try{
statement.close();
}catch(SQLException e){
e.printStackTrace();
}
}
if(connection != null){
try{
connection.close();
}catch(SQLException e){
e.printStackTrace();
}
}
}
}
}
package com.cedric.JDBC;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
/*
注册驱动的另一种方式(这种方式常用)
*/
public class JDBCTest03 {
public static void main(String[] args) {
try {
// 注册驱动
// 注册驱动的第一种方式
// com.mysql.cj.jdbc.ConnectionImpl@5a8e6209
// DriverManager.registerDriver(new com.mysql.cj.jdbc.Driver());
//注册驱动的第二种方式:常用的
// 为什么这种方式常用?因为参数是一个字符串,字符串可以写到xxx.properties文件中
// 以下方法不需要返回值,因为我们只是想用它类加载的动作
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取连接
Connection connection = DriverManager.getConnection("jdbc:mysql://","root","admin1114");
System.out.println(connection);
} catch (SQLException e) {
e.printStackTrace();
} catch(ClassNotFoundException e){
e.printStackTrace();
}
}
}
package com.cedric.JDBC;
/*
实际开发中不建议把连接数据库的信息写死到java程序中,可以放到xxx.properties的文件中
*/
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ResourceBundle;
public class JDBCTest04 {
public static void main(String[] args) {
ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
String driver = resourceBundle.getString("driver");
String url = resourceBundle.getString("url");
String user = resourceBundle.getString("user");
String password = resourceBundle.getString("password");
Connection connection = null;
Statement statement = null;
try {
// 1.注册驱动
Class.forName(driver);
// 2.获取连接
connection = DriverManager.getConnection(url,user,password);
// 3.获取数据库操作对象
statement = connection.createStatement();
// 4.执行SQL语句
// String sql = "insert into dept2(DEPTNO,DNAME,LOC) values (30,'Manager','CHANGSHA')";
String sql = "update dept2 set deptno='40',dname='销售部',loc='湖南' where deptno = 20";
int count = statement.executeUpdate(sql);
System.out.println(count != 0 ? "修改成功" : "修改失败");
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch(SQLException e){
e.printStackTrace();
} finally{
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
package com.cedric.JDBC;
import java.sql.*;
import java.util.ResourceBundle;
/*
处理查询结果集
*/
public class JDBCTest05 {
public static void main(String[] args) {
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
ResourceBundle resourceBundle = ResourceBundle.getBundle("jdbc");
String driver = resourceBundle.getString("driver");
String url = resourceBundle.getString("url");
String user = resourceBundle.getString("user");
String password = resourceBundle.getString("password");
try{
// 1.注册驱动
Class.forName(driver);
// 2.获取连接
connection = DriverManager.getConnection(url,user,password);
// 3.获取数据库操作对象
statement = connection.createStatement();
// 4.执行sql
String sql = "select empno,ename,sal from emp";
// int executeUpdate(insert/delete/update)
// ResultSet executeQuery(select)
resultSet = statement.executeQuery(sql); // 专门执行DQL语句的方法
// 5.处理查询结果集
boolean flag = true;
//System.out.println(flag); //true
while(resultSet.next()){
/*
String empno = resultSet.getString(1); // JDBC中所有下标从1开始,不是从0开始
String ename = resultSet.getString(2);
String sal = resultSet.getString(3);
System.out.println(empno + "," + ename + "," + sal);
*/
/*
// 这个不是以列的下标获取,是以列的名字获取
String empno = resultSet.getString("empno"); // 注意:列名称不是表中的列名称,是查询结果集的列名称
String ename = resultSet.getString("ename");
String sal = resultSet.getString("sal");
System.out.println(empno + "," + ename + "," + sal);
*/
// 除了可以以String类型取出之外,还可以以特定类型取出
int empno = resultSet.getInt(1); // 注意:列名称不是表中的列名称,是查询结果集的列名称
String ename = resultSet.getString("ename");
double sal = resultSet.getDouble(3);
System.out.println(empno + "," + ename + "," + (sal + 200));
}
/* if(flag){
// 光标指向的行有数据
// 取数据
String empno = resultSet.getString(1); // JDBC中所有下标从1开始,不是从0开始
String ename = resultSet.getString(2);
String sal = resultSet.getString(3);
System.out.println(empno + "," + ename + "," + sal);
}*/
}catch(Exception e){
e.printStackTrace();
} finally{
// 6.释放资源
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
package com.cedric.JDBC;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/*
实现功能:
1.模拟用户功能的实现
2.业务描述
程序运行的时候,提供一个输入的入口,可以让用户输入用户名和密码
用户输入用户名和密码后提交信息,java程序收集到用户信息
Java程序验证连接数据库验证用户名和密码是否合法
合法:登录成功
不合法:登录失败
存在问题
SQL注入现象
用户名:fdas
密码:fdas' or '1'='1
登录成功
导致SQL注入的原因:
用户输入的信息中含有sql关键字,并且这些关键字参与sql语句的编译过程
导致sql语句的原意被扭曲,进而达到sql注入7
*/
public class JDBCTest06 {
public static void main(String[] args) {
// 初始化一个界面
Map<String,String> userLoginInfo = initUI();
// 验证用户名和密码
boolean loginSuccess = login(userLoginInfo);
// 最后输出结果
System.out.println(loginSuccess ? "登录成功" : "登录失败");
}
/**
* 用户登录
* @param userLoginInfo 用户登录信息
* @return false表示失败,true表示成功
*/
public static boolean login(Map<String,String> userLoginInfo){
// 标记
boolean loginSuccess = false;
// 单独定义变量
String loginName = userLoginInfo.get("loginName");
String loginPwd = userLoginInfo.get("loginPwd");
//JDBC代码
Connection connection = null;
Statement statement = null;
ResultSet resultSet = null;
try {
// 1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.获取连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/cedric","root","admin1114");
// 3.获取数据库操作对象
statement = connection.createStatement();
// 4.执行sql
String sql = "select * from t_user where login_name = '"+ loginName+"'and login_pwd = '" + loginPwd + "'";
resultSet = statement.executeQuery(sql);
// 5.处理结果集
if(resultSet.next()){
// 登录成功
loginSuccess = true;
}
} catch (Exception e) {
e.printStackTrace();
} finally{
// 6.释放资源
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return loginSuccess;
}
/**
* 初始化用户界面
* @return 用户输入的用户名和密码等信息
*/
public static Map<String,String> initUI() {
Scanner s = new Scanner(System.in);
// 获取用户名
System.out.print("用户名:");
String loginName = s.nextLine();
// 获取密码
System.out.print("密码:");
String loginPwd = s.nextLine();
// 将获取到的用户名和密码组装到Map中
Map<String,String> userLoginInfo = new HashMap<>();
userLoginInfo.put("loginName",loginName);
userLoginInfo.put("loginPwd",loginPwd);
return userLoginInfo;
}
}
package com.cedric.JDBC;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
/**
* 解决SQL注入问题
* 只要用户提供的信息不参与SQL语句的编译过程,问题就解决了
* 即使用户提供的信息中含有SQL语句的关键字,但是没有参与编译,不起作用
* 要想用户信息不参与SQL语句的编译,那么必须使用java.util.PreparedStatement
* PreparedStatement接口继承了java.sql.Statement
* PreparedStatement是属于预编译的数据库操作对象
* PreparedStatement的原理是:预先对SQL语句的框架进行编译,然后再给SQL传“值”
*
* 测试结果
* 用户名:fdas
* 密码:fdas' or '1'='1
* 登录失败
*/
public class JDBCTest07 {
public static void main(String[] args) {
// 初始化一个界面
Map<String,String> userLoginInfo = initUI();
// 验证用户名和密码
boolean loginSuccess = login(userLoginInfo);
// 最后输出结果
System.out.println(loginSuccess ? "登录成功" : "登录失败");
}
/**
* 用户登录
* @param userLoginInfo 用户登录信息
* @return false表示失败,true表示成功
*/
public static boolean login(Map<String,String> userLoginInfo){
// 标记
boolean loginSuccess = false;
// 单独定义变量
String loginName = userLoginInfo.get("loginName");
String loginPwd = userLoginInfo.get("loginPwd");
//JDBC代码
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
// 1.注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 2.获取连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/cedric","root","admin1114");
// 3.获取数据库操作对象
// SQL语句的框架,其中一个?,表示一个占位符,将来一个?接受一个“值”,注意:占位符不能使用单引号括起来
String sql = "select * from t_user where login_name = ? and login_pwd = ?";
// 程序执行到此处,会发送一个sql语句的框架给DBMS,然后DBMS进行sql语句的预先编译
preparedStatement = connection.prepareStatement(sql);
// 给占位符?传值(第一个问号下标是1,第二个问号下标是2,JDBC中所有下标从1开始)
preparedStatement.setString(1,loginName);
preparedStatement.setString(2,loginPwd);
// 4.执行sql
resultSet = preparedStatement.executeQuery();
// 5.处理结果集
if(resultSet.next()){
// 登录成功
loginSuccess = true;
}
} catch (Exception e) {
e.printStackTrace();
} finally{
// 6.释放资源
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(preparedStatement != null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
return loginSuccess;
}
/**
* 初始化用户界面
* @return 用户输入的用户名和密码等信息
*/
public static Map<String,String> initUI() {
Scanner s = new Scanner(System.in);
// 获取用户名
System.out.print("用户名:");
String loginName = s.nextLine();
// 获取密码
System.out.print("密码:");
String loginPwd = s.nextLine();
// 将获取到的用户名和密码组装到Map中
Map<String,String> userLoginInfo = new HashMap<>();
userLoginInfo.put("loginName",loginName);
userLoginInfo.put("loginPwd",loginPwd);
return userLoginInfo;
}
}
package com.cedric.JDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/*
PreparedStatement完成insert delete update
*/
public class JDBCTest08 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
// 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/cedric","root","admin1114");
// 获取预编译的数据库操作对象
/*
// insert
String sql = "insert into dept2(deptno,dname,loc) values (?,?,?)";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,70);
preparedStatement.setString(2,"人事部");
preparedStatement.setString(3,"上海");
*/
/*
// update
String sql = "update dept2 set dname = ?,loc = ? where deptno = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"后勤部");
preparedStatement.setString(2,"天津");
preparedStatement.setInt(3,70);
*/
//delete
String sql = "delete from dept2 where deptno = ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setInt(1,40);
// 执行SQL
int count = preparedStatement.executeUpdate();
System.out.println(count);
} catch (Exception e) {
e.printStackTrace();
} finally{
// 释放资源
if(preparedStatement != null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
package com.cedric.JDBC;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;
/**
* JDBC中的事务是自动提交机制
* 只要执行一条任意一条DML语句,就提交一次
*
* connection.setAutoCommit(false); //自动、手动提交事务
* connection.commit; //手动提交事务
* connection.rollback; // 事务回滚
*/
public class JDBCTest09 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
try {
// 注册驱动
Class.forName("com.mysql.cj.jdbc.Driver");
// 获取连接
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/cedric","root","admin1114");
// 将自动提交机制修改为手动提交
connection.setAutoCommit(false); // 开启事务
// 获取预编译的数据库操作对象
String sql = "update t_act set balance = ? where actno = ?";
preparedStatement = connection.prepareStatement(sql);
// 给 ?传值
preparedStatement.setDouble(1,10000);
preparedStatement.setInt(2,111);
int count = preparedStatement.executeUpdate();
//String s = null;
// s.toString();
preparedStatement.setDouble(1,10000);
preparedStatement.setInt(2,222);
count += preparedStatement.executeUpdate();
System.out.println(count == 2 ? "转账成功" : "转账失败");
// 程序能走到这说明以上程序没有异常,事物结束,手动提交数据
connection.commit(); // 提交事务
} catch (Exception e) {
// 回滚事物
if(connection != null){
try {
connection.rollback();
} catch (SQLException throwables) {
throwables.printStackTrace();
}
}
e.printStackTrace();
} finally{
if(preparedStatement != null){
try {
preparedStatement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}
package com.cedric.JDBC.utils;
import java.sql.*;
public class DBUtil {
// 封装一个工具类
private DBUtil(){}
// 静态代码块在类加载的时候执行一次,并且只执行一次
static{
try {
Class.forName("com.mysql.cj.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接对象
* @return 连接对象
* @throws SQLException
*/
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection("jdbc:mysql://localhost:3306/cedric","root","admin1114");
}
/**
*
* @param connection 连接对象
* @param statement 数据库操作对象
* @param resultSet 结果集
*/
public static void close(Connection connection, Statement statement, ResultSet resultSet){
if(resultSet != null){
try {
resultSet.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(statement != null){
try {
statement.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(connection != null){
try {
connection.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
package com.cedric.JDBC;
import com.cedric.JDBC.utils.DBUtil;
import java.sql.*;
/*
模糊查询
*/
public class JDBCTest10 {
public static void main(String[] args) {
Connection connection = null;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
try {
connection = DBUtil.getConnection();
String sql = "select ename from emp where ename like ?";
preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1,"_A%");
resultSet = preparedStatement.executeQuery();
while(resultSet.next()){
System.out.println(resultSet.getString("ename"));
}
} catch (SQLException e) {
e.printStackTrace();
} finally{
// 释放资源
DBUtil.close(connection,preparedStatement,resultSet);
}
}
}