JDBC

JDBC

我的第一个JDBC程序

package com.wan.lesson01;

import java.sql.*;

public class Demo01 {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
      //  DriverManager.registerDriver(new com.mysql.jdbc.Driver());  原本的写法
        Class.forName("com.mysql.jdbc.Driver"); //固定写法,加载驱动
        //2.用户信息和url
        //useUnicode=true&characterEncoding=utf8&&useSSL=true
        String url = "jdbc:mysql://localhost:3306/新思路例会分享?useUnicode=true&characterEncoding=utf8&&useSSL=true";
        String username = "root";
        String password="654321";
        //3.链接成功,数据库对象 Connection 代表数据库
        Connection connection = DriverManager.getConnection(url, username, password);
        //4.执行sql的对象
        Statement statement = connection.createStatement();
        //5.查看所有结果
        String sql = "SELECT * FROM `student_table`";

        ResultSet resultSet = statement.executeQuery(sql); //返回的结果集,封装了全部的查询结果

        while (resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("number="+resultSet.getObject("number"));
            System.out.println("name="+resultSet.getObject("name"));
            System.out.println("birthday="+resultSet.getObject("birthday"));
            System.out.println("sex="+resultSet.getObject("sex"));
            System.out.println("--------------------------------------");
        }
        //6.释放连接
        connection.close();
        statement.close();
        resultSet.close();
    }
}

运行结果:

id=1
number=B190901
name=小王

birthday=1995-01-01
sex=0
--------------------------------------
id=2
number=B190902
name=小张

birthday=1994-03-06
sex=1
--------------------------------------
id=3
number=B190903
name=小李

birthday=1995-02-07
sex=1
--------------------------------------
id=4
number=B190904
name=小红

birthday=1997-08-22
sex=0
--------------------------------------
id=5
number=B190905
name=新思路

birthday=2001-03-12
sex=2
--------------------------------------
id=6
number=B190906
name=新思路java

birthday=
sex=2
--------------------------------------
id=7
number=B190905
name=mysql

birthday= 
sex=2
--------------------------------------
id=8
number=B190907
name=mysql

birthday= 
sex=2
--------------------------------------

步骤总结:

  1. 加载驱动
  2. 连接数据库 DriverManager
  3. 获得执行sql的对象 Statement
  4. 获得返回的结果
  5. 释放连接

DriverManager

//1.加载驱动
//  DriverManager.registerDriver(new com.mysql.jdbc.Driver());  原本的写法
Class.forName("com.mysql.jdbc.Driver"); //固定写法,加载驱动

String username = "root";
String password="654321";

URL

//2.用户信息和url
//useUnicode=true&characterEncoding=utf8&&useSSL=true
String url = "jdbc:mysql://localhost:3306/新思路例会分享?useUnicode=true&characterEncoding=utf8&&useSSL=true";

//mysql 默认端口 -- 3306
// 协议://主机:端口号/数据库名?参数1&参数2&参数3

//oracle 默认端口 -- 1521
// jdbc:oracle:thin:@localhost:1521:sid

Connection

//3.链接成功,数据库对象 Connection 代表数据库
Connection connection = DriverManager.getConnection(url, username, password);

//        数据库设置自动提交
//        connection.setAutoCommit(true);
//        事务提交
//        connection.commit();
//        事务回滚
//        connection.rollback();

statement执行SQL对象,PrepareStatement执行SQL的对象

String sql = "SELECT * FROM `student_table`";
statement.executeQuery();//查询操作返回ResultSet
statement.execute();//可以执行任何操作,效率低
statement.executeUpdate();//更新,插入,删除都用这个,返回一个受影响的行数

ResultSet:查询的结果集,封装了所有的结果

        //在不知道类型的情况下使用
        resultSet.getObject(12);
        resultSet.getObject("新思路");
        //在知道类型的情况下使用
        resultSet.getString("");
        resultSet.getInt(001);
        resultSet.getLong("");
        //更多方法在API帮助文档方法区去查看

获得指定的数据类型:

ResultSet resultSet = statement.executeQuery(sql); //返回的结果集,封装了全部的查询结果
resultSet.getObject();//在不知道的情况下使用
resultSet.getString()//如果知道列的类型,就是用指定的类型
resultSet.getInt();
resultSet.getFloat();
resultSet.getDate();

遍历,指针:

resultSet.beforeFirst();//移动到最前面
resultSet.afterLast();//移动到最后面一个
resultSet.next();//移动到下一行
resultSet.previous();//移动到上一行
resultSet.absolute(3);//移动到指定行

释放资源:

connection.close();
statement.close();
resultSet.close();

statement对象

statement执行SQL对象,PrepareStatement执行SQL的对象

String sql = "SELECT * FROM `student_table`";
statement.executeQuery();//查询操作返回ResultSet
statement.execute();//可以执行任何操作,效率低
statement.executeUpdate();//更新,插入,删除都用这个,返回一个受影响的行数

API帮助文档:

public interface Statement
extends Wrapper, AutoCloseable用于执行静态SQL语句并返回其生成的结果的对象。 

默认情况下,每个Statement对象只能有一个ResultSet对象同时打开。 因此,如果一个ResultSet对象的读取与另一个对象的读取交错,则ResultSet对象必须由不同的Statement对象生成。 在所有执行方法Statement接口隐式关闭当前ResultSet声明的对象,如果一个开放的存在。 

jdbc中的Statement对象用于向数据库发送SQL语句,想完成对数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。 ==

Statement对象中的executeUpdata方法,用于向对象发送增删改的sql语句,executeUpdata方法执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)。

Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet对象。

新建一个配置文件 mew file

新建一个工具类

package statement对象.utils;

import java.io.IOException;
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;
    //获取配置文件,src目录下可以通过反射拿到
    static {
        try{
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            //读入流
            Properties properties = new Properties();
            properties.load(in);

             driver = properties.getProperty("driver");
             url = properties.getProperty("url");
             username = properties.getProperty("username");
             password = properties.getProperty("password");
            //1.加载驱动
            Class.forName(driver);


        /*} catch (IOException | ClassNotFoundException e) {
            e.printStackTrace();
        }*/
        //可以使用最大的异常捕获
        } catch (Exception  e) {
            e.printStackTrace();
        }
    }
    //2.获取连接
   /* public static void getConnection() throws SQLException {
        DriverManager.getConnection(url, username, password);
    }*/
    public static Connection getConnection() throws SQLException {
      return   DriverManager.getConnection(url, username, password);
    }
    //3.释放资源
    public static void release(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();
            }
        }
        //到此,工具类就写完了
    }
}

insert

package statement对象;

import statement对象.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestInsert {
    public static void main(String[] args) {
        //finally获取不到,因此提升作用域
        Connection connection=null;
        Statement statement=null;
        ResultSet resultSet=null;

        //获取链接
        try {
             connection = JdbcUtils.getConnection(); //获取数据库连接
             statement = connection.createStatement();//获取SQL的执行对象
             String sql ="INSERT INTO `student`(`id`,`name`,`sex`,`birthday`,`address`,`email`)" +
                    "VALUES(2,'wan2','男',0916,'民大','943010372@qq.com' )";
            int i = statement.executeUpdate(sql);
            if(i>0){
                System.out.println("插入成功!");
            }else {
                System.out.println("插入失败!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
        //释放资源
           // JdbcUtils.release(connection,statement,resultSet);
            JdbcUtils.release(connection,statement, null);
        }
    }
}

delete

package statement对象;

import statement对象.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestDelete {
    public static void main(String[] args) {
        //finally获取不到,因此提升作用域
        Connection connection=null;
        Statement statement=null;
        ResultSet resultSet=null;

        //获取链接
        try {
            connection = JdbcUtils.getConnection(); //获取数据库连接
            statement = connection.createStatement();//获取SQL的执行对象
            String sql ="DELETE FROM `student` WHERE `id`=1";
            int i = statement.executeUpdate(sql);
            if(i>0){
                System.out.println("删除成功!");
            }else {
                System.out.println("删除失败!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //释放资源
            // JdbcUtils.release(connection,statement,resultSet);
            JdbcUtils.release(connection,statement, null);
        }
    }
}

update

package statement对象;

import statement对象.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestUpdate {
    public static void main(String[] args) {
        //finally获取不到,因此提升作用域
        Connection connection=null;
        Statement statement=null;
        ResultSet resultSet=null;

        //获取链接
        try {
            connection = JdbcUtils.getConnection(); //获取数据库连接
            statement = connection.createStatement();//获取SQL的执行对象
            String sql ="UPDATE `student` SET `name`='wan1'WHERE `id`=1";
            int i = statement.executeUpdate(sql);
            if(i>0){
                System.out.println("修改成功!");
            }else {
                System.out.println("修改失败!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //释放资源
            // JdbcUtils.release(connection,statement,resultSet);
            JdbcUtils.release(connection,statement, null);
        }
    }
}

select

package statement对象;

import statement对象.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestSelect {
    public static void main(String[] args) {
        Connection connection=null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
             connection = JdbcUtils.getConnection();
             statement = connection.createStatement();
        //执行SQL语句
             String sql="SELECT *FROM `student`WHERE `id`=1";
            ResultSet rs = statement.executeQuery(sql);
            while(rs.next()){
                System.out.println(rs.getString("name"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            JdbcUtils.release(connection,statement,null);
        }
    }
}

CRUD操作

使用Statement.executeQuery(String sql)完成数据添加操作,示例操作:

  //添加操作
        Statement statement1 = connection.createStatement();
//        String sql = "
" +
//                "INSERT INTO `student_table` (`number`,`name`,`birthday`,`sex`)
" +
//                "VALUES(`B190909`,`晚风花间寺中人`,`2020-3-28`,`2`);";
        String sql = "insert into user (...) value(...)";
        int i = statement1.executeUpdate(sql);
        if(i>0){
            System.out.println("插入成功!");
        }

删除操作,

 //删除操作
        Statement statement1 = connection.createStatement();

        String sql = "DELETE FROM `student_table` WHERE id =8;";
        int i = statement1.executeUpdate(sql);
        if(i>0){
            System.out.println("删除成功!");
        }

修改操作:

    //修改操作
        Statement statement1 = connection.createStatement();

        String sql = "UPDATE `student_table` SET `name`=`JDBC` WHERE `name`=`mysql`;";
        int i = statement1.executeUpdate(sql);
        if(i>0){
            System.out.println("修改成功!");
        }

查询操作:

 //查询操作操作
        Statement statement1 = connection.createStatement();

        String sql = "SELECT *FROM `student_table` WHERE `id`=7";
       // int i = statement1.executeUpdate(sql);
        ResultSet resultSet1 = statement1.executeQuery(sql);
       while ((resultSet1.next())){
           //根据获取列的数据类型,分别调用resultSet1的相应方法映射到java对象中
       }

SQL注入问题

存在漏洞,会被攻击导致数据泄露 SQL被拼接

百度百科

SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息。

 login("'or '1=1","民大");

SQL注入

package statement对象;

import statement对象.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SQL注入 {
    public static void main(String[] args) {
       // login("'or '1=1","民大");

       login("wan1","民大");
    }
    //定义一个登陆业务方法
    public static void login(String name,String address){

        Connection connection=null;
        Statement statement = null;
        ResultSet resultSet = null;

        try {
            connection = JdbcUtils.getConnection();
            statement = connection.createStatement();
            //执行SQL语句
            //SELECT *FROM `student`WHERE `name`='wan1'AND `address`='民大'
            String sql="SELECT *FROM `student`WHERE `name`='"+name+"'AND`address`='"+address+"'";
            ResultSet rs = statement.executeQuery(sql);
            while(rs.next()){
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("address"));
                System.out.println("=======================");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            JdbcUtils.release(connection,statement,null);
        }
    }

}

PreparedStatement对象

PreparedStatement可以防止SQL注入,效率更高

1.增加

package PreparedStatement对象;

import statement对象.utils.JdbcUtils;

import java.sql.*;

public class TestInsert {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        try{
            connection= JdbcUtils.getConnection();
            //区别
            //使用?占位符1代表参数
            String sql=" INSERT INTO `student`(`id`,`name`,`sex`,`birthday`,`address`,`email`)" +
                    "VALUES(?,?,?,?,?,?)";
            preparedStatement = connection.prepareStatement(sql);//预编译SQL,先写sql,然后不执行

            //手动给参数赋值
            preparedStatement.setInt(1,6);
            preparedStatement.setString(2,"wan6");
            preparedStatement.setString(3,"男");

            preparedStatement.setDate(4,new java.sql.Date(new Date(4).getTime()));
            preparedStatement.setString(5,"计科");
            preparedStatement.setString(6,"1008610086@qq.com");
        //执行
            int i = preparedStatement.executeUpdate();
            if (i>0){
                System.out.println("插入成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }


}

2.删除

package PreparedStatement对象;

import statement对象.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestDelete {

    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        try{
            connection= JdbcUtils.getConnection();
            //区别
            //使用?占位符1代表参数
            String sql="DELETE FROM `student` WHERE `id`=?";
            preparedStatement = connection.prepareStatement(sql);//预编译SQL,先写sql,然后不执行

            //手动给参数赋值
            preparedStatement.setInt(1,6);

            //执行
            int i = preparedStatement.executeUpdate();
            if (i>0){
                System.out.println("删除成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

3.更新

package PreparedStatement对象;

import statement对象.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class TestUpdate {
    public static void main(String[] args) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        try{
            connection= JdbcUtils.getConnection();
            //区别
            //使用?占位符1代表参数
            String sql="update `student` set`name`  =?  where`id`=? ;";
            preparedStatement = connection.prepareStatement(sql);//预编译SQL,先写sql,然后不执行

            //手动给参数赋值
            preparedStatement.setString(1,"万万");
            preparedStatement.setInt(2,6);

            //执行
            int i = preparedStatement.executeUpdate();
            if (i>0){
                System.out.println("更新成功!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

4.查询

package PreparedStatement对象;

import statement对象.utils.JdbcUtils;

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) {
        Connection connection=null;
        PreparedStatement preparedStatement=null;
        ResultSet resultSet=null;
        try{
            connection  = JdbcUtils.getConnection();
            String sql="select *from `student`where `id`=?";
           preparedStatement= connection.prepareStatement(sql);
           //传递参数
            preparedStatement.setInt(1,1);
            resultSet = preparedStatement.executeQuery();
            if (resultSet.next()){
                System.out.println(resultSet.getString("name"));
                System.out.println("查询成功!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            JdbcUtils.release(connection,preparedStatement,resultSet);

        }
    }
}

5.防止SQL注入(标记一下)

package PreparedStatement对象;

import statement对象.utils.JdbcUtils;

import java.sql.*;

public class SQL注入 {
    public static void main(String[] args) {
       // login("'or '1=1","民大"); //技巧

       login("wan1","民大");
    }
    //定义一个登陆业务方法
    public static void login(String name,String address){

        Connection connection=null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            connection = JdbcUtils.getConnection();
//            PreparedStatement 防止SQL注入的本质,把传递进来的参数当作字符

            String sql="SELECT *FROM `student`WHERE `name`=?AND `address`=?";

            st = connection.prepareStatement(sql);

            st.setString(1,name);
            st.setString(2,address);


            rs = st.executeQuery(sql);
            while(rs.next()){
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("address"));
                System.out.println("=======================");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
        finally {
            JdbcUtils.release(connection,st, null);
        }
    }


}

使用IDEA连接数据库

IDEA操作事务

事务

要么都成功,要么都失败

1.事务的基本要素(ACID)

  • 原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位。
  • 一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏 。
  • 隔离性(Isolation):同一时间,只允许一个事务请求同一数据,不同的事务之间彼此没有任何干扰。
  • 持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚。

2.隔离性会产生的问题

  • 脏读:一个事务读取了另一个没有提交的事务

  • 不可重复读:事务 A 多次读取同一数据,事务 B 在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致。

  • 虚读(幻读):用户A将数据库中所有学生的成绩从具体分数改为ABCDE等级,但是用户B就在这个时候插入了一条具体分数的记录,当修改A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫幻读。

3.操作步骤

  • 取消掉自动提交:每次执行数据库更新的时候实际上发出SQL命令之后就已经提交上去了。
  • 开始事务
  • 进行一系列操作
  • 如果操作一切合格,则提交事务
  • 如果发现一个地方有问题,则可以回滚

package jdbc;

import statement对象.utils.JdbcUtils;

import java.sql.*;

public class transaction {
    public static void main(String[] args) throws SQLException {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            //关闭数据库的自动提交,自动会开启事务.setAutoCommit方法,是指在事务当中,是否执行一条语句就自动提交一次。  如果想在一个事务里进行多个操作。就必然将setAutoCommit的参数设置成false,在多个操作的最后调用conn.commit()方法,进行手动提交
            conn.setAutoCommit(false);   //开启事务

            String sql1 = "UPDATE `account` set cash = cash-100 where name = 'A'";
            st = conn.prepareStatement(sql1);
            st.executeUpdate();

            String sql2 = "UPDATE `account` set cash = cash+100 where name = 'B'";
            st = conn.prepareStatement(sql2);
            st.executeUpdate();

            //业务完毕,提交事务
            conn.commit();
            System.out.println("成功");
        } catch (SQLException e) {
            conn.rollback();   //如果失败则回滚事务
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

原文地址:https://www.cnblogs.com/wanwanyuan/p/12740832.html