【JDBC】JDBC的Statement版,PreparedStatement版,并且含有取消自动提交事务的方法与最后的封装JDBC的方法

前言:

JDBC开发前的准备工作,先从官网下载对应的驱动jar包,比如MySQL的

一、JDBC是什么?本质是什么?

Java DataBase Connectivity(Java语言连接数据库)

JDBC是SUN公司制定的一套接口(interface)
         java.sql.*; (这个软件包下有很多接口。)
接口都有调用者和实现者。
面向接口调用、面向接口写实现类,这都属于面向接口编程。

为什么要面向接口编程?
         解耦合:降低程序的耦合度,提高程序的扩展力。
         多态机制就是非常典型的:面向抽象编程。(不要面向具体编程)
         建议:
                  Animal a = new Cat();
                  Animal a = new Dog();
         // 喂养的方法
         public void feed(Animal a){ // 面向父类型编程。

         }

不建议:
         Dog d = new Dog();
         Cat c = new Cat();

思考:为什么SUN制定一套JDBC接口呢?
         因为每一个数据库的底层实现原理都不一样。
         Oracle数据库有自己的原理。
         MySQL数据库也有自己的原理。
         MS SqlServer数据库也有自己的原理。
         …
         每一个数据库产品都有自己独特的实现原理。

JDBC的本质到底是什么?
一套接口。

在这里插入图片描述

二、JDBC编程六步!!!

  • 第一步:注册驱动(作用:告诉Java程序,即将要连接的是哪个品牌的数据库)

  • 第二步:获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,重量级的,使用完之后一定要关闭通道。)

  • 第三步:获取数据库操作对象(专门执行sql语句的对象)

  • 第四步:执行SQL语句(DQL DML…)

  • 第五步:处理查询结果集(只有当第四步执行的是select语句的时候,才有这第五步处理查询结果集。)

  • 第六步:释放资源(使用完资源之后一定要关闭资源。Java和数据库属于进程间的通信,开启之后一定要关闭。)

三、Statement创建连接

import com.mysql.jdbc.Driver;
import com.mysql.jdbc.Statement;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;

//有安全隐患
//sql注入!!
/*
导致sql注入的根本原因是什么
用户输入的信息中含有sql语句的关键字,并且这些关键子参与了sql语句的编译过程
导致sql语句的愿意被扭曲,进而达到sql注入。
 */
public class JDBCtext06 {
    public static void main(String[] args) {

        //初始化一个界面
        Map<String,String> userLoginInfo = initUI();

        //验证用户名和密码
        boolean loginSuccess = login(userLoginInfo);

        //最后输出结果
        System.out.println(loginSuccess ? "登录成功" : "登陆失败");
    }

    private static boolean login(Map<String, String> userLoginInfo) {
        boolean flag = false;
        //JDBC
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;

        //1.注册驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","zzj1q2w3e");
            //3.获取数据库操作对象
            stmt = (Statement) conn.createStatement();
            //4.执行sql语句
            String sql = "select * from t_user where loginname = '"+userLoginInfo.get("loginName")+"' and loginpwd = " +
                    "'"+userLoginInfo.get("loginPwd")+"'";
            //5.处理结果集
            rs = stmt.executeQuery(sql);
            if (rs.next()){
                flag=true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            if (rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (stmt != null){
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }


        return flag;
    }

    private static Map<String, String> initUI() {
        Scanner scanner = new Scanner(System.in);

        System.out.println("用户名:");
        String loginName = scanner.nextLine();

        System.out.println("密码:");
        String loginPwd = scanner.nextLine();

        Map<String,String> userLoginInfo = new HashMap<>();
        userLoginInfo.put("loginName",loginName);
        userLoginInfo.put("loginPwd",loginPwd);

        return userLoginInfo;

    }
}

这种方式创建连接会存在安全隐患,sql注入问题

四、PreparedStatemen创建连接

解决了注入问题,因为PreparedStatemen是先确定框架编译完成后再传值,就不会出现吧用户输入的字符当成关键子去编译了

import com.mysql.jdbc.Statement;

import java.awt.*;
import java.sql.*;
import java.util.HashMap;
import java.util.Map;
import java.util.Scanner;
//解决sql注入的问题
public class JDBCtext07 {
    public static void main(String[] args) {

        //初始化一个界面
        Map<String,String> userLoginInfo = initUI();

        //验证用户名和密码
        boolean loginSuccess = login(userLoginInfo);

        //最后输出结果
        System.out.println(loginSuccess ? "登录成功" : "登陆失败");
    }

    private static boolean login(Map<String, String> userLoginInfo) {
        boolean flag = false;
        //JDBC
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        String loginName = userLoginInfo.get("loginName");
        String loginPwd = userLoginInfo.get("loginPwd");


        //1.注册驱动
        try {
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","zzj1q2w3e");
            //3.获取数据库操作对象
            String sql = "select * from t_user where loginname = ? and loginpwd = ?";//问号是占位符,以后要往问号的地方填值
            //千万不要用单引号括住,相当于sql语句的框架
            ps = conn.prepareStatement(sql);
            //给占位符传值,第一个问号下标是一,注意JDBC中所有下标从1开始
            ps.setString(1,loginName);
            ps.setString(2,loginPwd);

            //4.执行sql语句
            rs = ps.executeQuery();
            //5.处理结果集
            if (rs.next()){
                flag=true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //6.释放资源
            if (rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (ps != null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }


        return flag;
    }

    private static Map<String, String> initUI() {
        Scanner scanner = new Scanner(System.in);

        System.out.println("用户名:");
        String loginName = scanner.nextLine();

        System.out.println("密码:");
        String loginPwd = scanner.nextLine();

        Map<String,String> userLoginInfo = new HashMap<>();
        userLoginInfo.put("loginName",loginName);
        userLoginInfo.put("loginPwd",loginPwd);

        return userLoginInfo;

    }
}

这里要提示一行代码,就是再引号里输入变动的字符写法。

String sql = "select * from t_user where loginname = ? and loginpwd = ?";//问号是占位符,以后要往问号的地方填值
            //千万不要用单引号括住,相当于sql语句的框架
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

import java.sql.DriverManager;
import java.sql.SQLException;

public class JDBCText08 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;

        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","zzj1q2w3e");
            //获取预编译的数据库操作对象
            /*String sql = "insert into dept(deptno,dname,loc) values(?,?,?)";
            ps = (PreparedStatement) conn.prepareStatement(sql);
            ps.setInt(1,60);
            ps.setString(2,"销售部");
            ps.setString(3,"广州");*/

            /*String sql = "update dept set dname = ?, loc = ? where deptno = ?";
            ps = (PreparedStatement) conn.prepareStatement(sql);
            ps.setString(1,"研发一部");
            ps.setString(2,"北京");
            ps.setInt(3,60);*/

            String sql = "delete from dept where deptno = ?";
            ps = (PreparedStatement) conn.prepareStatement(sql);
            ps.setInt(1,60);
            //执行sql语句
            int count = ps.executeUpdate();
            System.out.println(count);


        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //释放资源
            if (ps != null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }

            if (conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
}

五、取消自动提交事务的方法

import com.mysql.jdbc.Connection;
import com.mysql.jdbc.PreparedStatement;

import java.sql.DriverManager;
import java.sql.SQLException;
/*
重点三行代码
  conn.setAutoCommit(false);将自动提交事务机制关闭
  conn.commit();手动提交
  conn.rollback();事务回滚
  */



public class JDBCText09 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;

        try {
            //注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //获取连接
            conn = (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","zzj1q2w3e");
            conn.setAutoCommit(false);
            //获取预编译的数据库操作对象
            String sql1 = "update t_act set balance = ? where actno = ?";
            ps = (PreparedStatement) conn.prepareStatement(sql1);
            //给?传值
            ps.setDouble(1,10000);
            ps.setInt(2,111);
            int count = ps.executeUpdate();

            //String a = null;
            //a.toString();
            //执行sql语句

            //给?传值
            ps.setDouble(1,10000);
            ps.setInt(2,222);
            count += ps.executeUpdate();

            System.out.println(count == 2 ? "转账成功" : "转账失败");

            //手动提交
            conn.commit();

        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            //释放资源

            if (conn != null){
                try {
                    conn.rollback();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (ps != null){
                try {
                    ps.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}


最重要是加入了这三行代码

重点三行代码
  conn.setAutoCommit(false);将自动提交事务机制关闭
  conn.commit();手动提交
  conn.rollback();事务回滚

六、封装方法

package utils;

import com.sun.jdi.connect.spi.Connection;

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

public class DBUtil {
    /*
    工具类的构造方法是私有的
    因为工具类当中的方法都是静态的,不需要new对象,直接用类名diaoyong
     */

    private DBUtil(){
    }
    //静态代码块在类加载时执行,并且执行一次
    static {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    /*
    获取数据库连接对象
    因为在后面调用方法时会有catch所以这里不用catch而用throw抛出异常
     */

    public static Connection getConnection() throws SQLException {
        return (Connection) DriverManager.getConnection("jdbc:mysql://localhost:3306/test","root","zzj1q2w3e");
    }

    public static void close(Connection conn , Statement ps , ResultSet rs){
        if (rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
            if (ps != null) {
                try {
                    ps.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

            if (conn != null) {
                try {
                    conn.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        }
    }
}



一些例子

插入例子

package com;

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

public class text3 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            conn = DBUtil.getConnection();

            String sql = "insert into t_user(id,loginName,loginPwd,realName) values (?,?,?,?)";
            ps = conn.prepareStatement(sql);
            ps.setInt(1,123);
            ps.setString(2,"qewqr");
            ps.setString(3,"134234");
            ps.setString(4,"rfrefrefe");

            int count = ps.executeUpdate();

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.closs(conn,ps,rs);
        }
    }
}

查询例子

package com;

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

public class TEST02 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;

        try {
            conn = DBUtil.getConnection();

            String sql = "select loginName from t_user where loginName like ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,"_A%");
            rs = ps.executeQuery();
            while (rs.next()){
                System.out.println(rs.getString("loginName"));

            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            DBUtil.closs(conn,ps,rs);
        }
    }
}

  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值