JDBC的使用

JDBC概念

JDBC(Java DateBase Connectivity),java语言连接数据库。

JDBC是SUN公司制定的一套接口,用来连接不同的数据库。

jdbc编程六步

1、注册驱动

2、连接数据库

3、创建数据库操作对象

4、执行SQL语句

5、查询结果集

6、关闭连接

注册驱动

 		Driver  driver = new com.mysql.jdbc.Driver();//创建mysql数据库驱动对象
           DriverManager.registerDriver(driver);//注册驱动

现在已经不用该种方式注册驱动,因为数据库java文件中com.mysql.jdbc.Driver这个这个类已经通过静态代码块自动注册了驱动。

当我们使用Class.forName()方法获取这个类时,com.mysql.jdbc.Driver类会自动加载静态代码块注册驱动。

 Class.forName("com.mysql.jdbc.Driver");

连接数据库

 Connection conn =DriverManager.getConnection
     ("jdbc:mysql://localhost:3306/jdbc","root","123456");

创建数据库操作对象

Statement stmt = conn.createStatement();

执行SQL语句

String sql="select ename,deptno from emp;";
ResultSet rs = stmt.executeQuery(sql);

查询结果集

 while (rs.next()){
                String s1 = rs.getString(1);//获取第一个查询字段,ename
                String s2 = rs.getString(2);//获取第二个查询字段,deptno
                System.out.println(s1+" "+s2);
            }

关闭连接

finally {
        if (rs != null) {//关闭ResultSet结果集
            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();
            }
        }
        }

以上六步是正常的JDBC执行流程。

但是此种书写步骤可能会造成sql注入,因为用户可以参与sql语句的编写。

在用户传入编写的语句后,程序才会编译sql语句并执行。

SQL注入

用户参与编写sql语句,导致sql注入。

import java.sql.*;
import java.util.HashMap;
import java.util.Scanner;

public class JDBCTest2 {
    public static void main(String[] args) {
        HashMap<String,String> initui = initui();
        String admin = initui.get("user");
        String password = initui.get("password");
        jdbcConnection(admin,password);
    }

    private static HashMap initui() {//初始化用户界面,让用户输入参数
        System.out.println("------------------用户登录界面--------------------");
        Scanner s = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String user = s.nextLine();
        System.out.println("请输入密码:");
        String password = s.nextLine();
        HashMap<String, String> hashMap = new HashMap<>();//将用户输入的参数存入到map集合
        hashMap.put("user",user);
        hashMap.put("password",password);
        return hashMap;
    }

    private static void jdbcConnection(String user, String password){//用JDBC连接数据库
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc","root","123456");
------------------------------------------------------------------------------      //先进行sql语句的书写,再进行编译,造成sql注入      
             stmt = conn.createStatement();
            String sql="select*from user_login where user='"+user+"' and password='"+password+"'";
            System.out.println(sql);
                    rs = stmt.executeQuery(sql);
------------------------------------------------------------------------------                    
            if(rs.next())
                System.out.println("登陆成功");
            else
            System.out.println("登录失败");

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

    }

}

 /* ------------------用户登录界面--------------------sql注入演示
            请输入用户名:
            ad
            请输入密码:
            ad' or 'ad'='ad
            select*from user_login where user='ad' and password='ad' or 'ad'='ad'
            登陆成功*/

此时我们可以使用prepareStatement对象来预防这种情况。PreparedStatement对象允许数据库预编译SQL语句,然后再让用户传值。

import java.sql.*;
import java.util.HashMap;
import java.util.Scanner;

public class JDBCTest3 {
    public static void main(String[] args) {
        HashMap<String,String> initui = initui();
        String admin = initui.get("user");
        String password = initui.get("password");
        jdbcConnection(admin,password);
    }

    private static HashMap initui() {//初始化用户界面,让用户输入参数
        System.out.println("------------------用户登录界面--------------------");
        Scanner s = new Scanner(System.in);
        System.out.println("请输入用户名:");
        String user = s.next();
        System.out.println("请输入密码:");
        String password = s.next();
        HashMap<String, String> hashMap = new HashMap<>();//将用户输入的参数存入到map集合
        hashMap.put("user",user);
        hashMap.put("password",password);
        return hashMap;
    }

    private static void jdbcConnection(String user, String password){//用JDBC连接数据库
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc","root","123456");
------------------------------------------------------------------------------  
 // 为防止sql注入,先编译sql语,再进行传值。'?'是占位符,调用操作对象的set方法,为其传值,1代表第一个占位符,2代表第二个占位符
           String sql="select*from user_login where user=? and password=?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,user);
            pstmt.setString(2,password);
            rs = pstmt.executeQuery();
 -----------------------------------------------------------------------------
            if(rs.next())
                System.out.println("登陆成功");
            else
                System.out.println("登录失败");

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

    }

}

prepareStatement对象优点在于能预编译sql语句,编译后,再让用户传值,可以有效防止用户进行sql注入。

statement对象优点在于用户能参与sql语句字符串拼接,但是要注意限制拼接的内容。否则会造成sql注入。

JDBC对数据库表进行增删改

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

public class JDBCTest4 {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection conn=null;
        PreparedStatement pstmt=null;
        try {
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbc","root","123456");
            /*
           System.out.println("-----------增--------------");
            String sql="insert into emp(id,name,dept) value(?,?,?)";
             pstmt = conn.prepareStatement(sql);
             pstmt.setInt(1,1);
            pstmt.setString(2,"wangwu");
            pstmt.setString(3,"策划部");
            pstmt.execute();*/
            /*System.out.println("----------改-----------------");
            String sql="update emp set name=?,dept=? where id =?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,"zhaosi");
            pstmt.setString(2,"研发部");
            pstmt.setInt(3,1);
           	pstmt.executeUpdate();
            */
            System.out.println("----------------删----------------------");
            String sql="delete from emp where id=?";
             pstmt = conn.prepareStatement(sql);
             pstmt.setInt(1,1);
             pstmt.execute();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
        }

    }
}

JDBC对数据库事务处理

JDBC默认自动提交事务。

当我们需要关闭事务的自动提交时,使用conn.setAutoCommit(false)。

当我们的事务执行完成,使用conn.commit(),提交事务。

在抛出的异常中放置 conn.rollback(),确保出现异常可以回滚。

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

public class JDBCTest5 {
    public static void main(String[] args) {
        try {
            Class.forName("com.mysql.jdbc.Driver");
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        Connection conn = null;
        PreparedStatement pstmt = null;
        try {
             conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/jdbc","root","123456");
             conn.setAutoCommit(false);//将事务的自动提交置为flase
             String sql = "update account set balance=? where actno=?";
             pstmt = conn.prepareStatement(sql);
             pstmt.setInt(1,30000);
             pstmt.setString(2,"1");
            int i = pstmt.executeUpdate();
            Thread.sleep(1000*10);//模拟网络延迟
            pstmt.setInt(1,20000);
             pstmt.setString(2,"2");
            i+= pstmt.executeUpdate();//判断是否更新了两次
            if(i==2)
                System.out.println("转账成功");
            conn.commit();
        } catch (SQLException e) {
            e.printStackTrace();
            try {
                if (conn != null) {
                    conn.rollback();//如果抛出异常要进行回滚
                }
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            if (pstmt != null) {
                try {
                    pstmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }

    }
}

JDBCUtil工具类

JDBCUtil可以将我们经常重复写的代码进行封装,提升编程效率。

JDBC编程六步(使用Util工具类后),大大简化了代码。

import utils.DBUtil;

import java.sql.*;

public class JDBCTest6 {
    public static void main(String[] args) {
        Connection conn = null;
        PreparedStatement pstmt =null;
        ResultSet rs=null;
        try {
             conn = DBUtil.connection();//调用工具类注册驱动,连接数据库
            String sql="select actno,balance from account";
             pstmt = conn.prepareStatement(sql);
             rs = pstmt.executeQuery();
             while(rs.next()){
                 System.out.println(rs.getString(1)+","+rs.getInt(2));
             }
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
                DBUtil.close(rs,pstmt,conn);//关闭连接
        }

    }
}

JDUCUtil工具类

package utils;

import java.sql.*;
import java.util.ResourceBundle;

public class DBUtil {
    private  DBUtil(){}
    private   static   ResourceBundle bundle = ResourceBundle.getBundle("Resourse//jdbc");//从配置文件中获取数据库相关信息

    static {//注册驱动
        try {
            Class.forName(bundle.getString("Driver"));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }


    public static Connection connection() throws SQLException {//创建连接
        Connection  conn = DriverManager.getConnection(bundle.getString("url"),bundle.getString("user"),bundle.getString("password"));
        return conn;//返回连接
    }

    public static void close(ResultSet rs,Statement stmt,Connection conn){//关闭所有连接
        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();
            }
        }
    }

}

properties配置文件

Driver=com.mysql.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/jdbc
user=root
password=123456
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值