美文网首页
Java篇-JDBC

Java篇-JDBC

作者: TianTianBaby223 | 来源:发表于2018-07-29 10:05 被阅读18次

一 JDBC是什么

java Data Base Connectivity java数据库连接 是一种用于执行SQL语句的Java API,可以为多种关系数据库提供统一访问,它由一组用Java语言编写的类和接口组成。是Java访问数据库的标准规范.

也就是说,JDBC ,定义了很多功能接口,具体的实现交给数据库生产商去实现,JDBC提供了一种基准,据此可以构建更高级的工具和接口,使数据库开发人员能够编写数据库应用程序.

Java提供访问数据库规范称为JDBC,而生产厂商提供规范的实现类称为驱动。

JDBC是接口,驱动是接口的实现,没有驱动将无法完成数据库连接,从而不能操作数据库!每个数据库厂商都需要提供自己的驱动,用来连接自己公司的数据库,也就是说驱动一般都由数据库生成厂商提供。

二 连接数据库及操作

  • 导入生产上提供的实现工具jar包

创建lib目录,用于存放当前项目需要的所有jar包
选择jar包,右键执行build path / Add to Build Path

1.png
  • 连接进行增(删改)操作
public static void main(String[] args)throws ClassNotFoundException,SQLException{
        //1.注册驱动 反射技术,将驱动类加入到内容
        // 使用java.sql.DriverManager类静态方法 registerDriver(Driver driver)
        // Diver是一个接口,参数传递,MySQL驱动程序中的实现类
        //DriverManager.registerDriver(new Driver());
        //驱动类源代码,注册2次驱动程序
        Class.forName("com.mysql.jdbc.Driver");
        
        //2.获得数据库连接  DriverManager类中静态方法
        //static Connection getConnection(String url, String user, String password)  
        //返回值是Connection接口的实现类,在mysql驱动程序
        //url: 数据库地址  jdbc:mysql://连接主机IP:端口号//数据库名字
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username="root";
        String password="123";
        Connection con = DriverManager.getConnection(url, username, password);
        
        //3.获得语句执行平台, 通过数据库连接对象,获取到SQL语句的执行者对象
        // con对象调用方法   Statement createStatement() 获取Statement对象,将SQL语句发送到数据库
        // 返回值是 Statement接口的实现类对象,,在mysql驱动程序
        Statement stat = con.createStatement();
        //  4.执行sql语句
        // 通过执行者对象调用方法执行SQL语句,获取结果
        // int executeUpdate(String sql)  执行数据库中的SQL语句, insert delete update
        // 返回值int,操作成功数据表多少行
        int row = stat.executeUpdate
                ("INSERT INTO sort(sname,sprice,sdesc) VALUES('汽车用品',50000,'疯狂涨价')");
        System.out.println(row);
        
        //6.释放资源  
        stat.close();
        con.close();
    }

思路分析 : 首先 注册驱动,因为sql生产商的实现类中已经实现了registerDriver()注册方法,所以为了避免二次注册与硬编码不易扩展的问题,采用了反射技术.
Connection 获得数据库连接;
Statement获得语句执行平台

  • 连接进行查询操作

使用stat.executeQuery 方法进行查询

public static void main(String[] args) throws Exception{
        //1. 注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2. 获取连接对象
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username="root";
        String password="123";
        Connection con = DriverManager.getConnection(url, username, password);
        //3 .获取执行SQL 语句对象
        Statement stat = con.createStatement();
        // 拼写查询的SQL
        String sql = "SELECT * FROM sort";
        //4. 调用执行者对象方法,执行SQL语句获取结果集
        // ResultSet executeQuery(String sql)  执行SQL语句中的select查询
        // 返回值ResultSet接口的实现类对象,实现类在mysql驱动中
        ResultSet rs = stat.executeQuery(sql);
        //5 .处理结果集
        // ResultSet接口方法 boolean next() 返回true,有结果集,返回false没有结果集
        while(rs.next()){
            //获取每列数据,使用是ResultSet接口的方法 getXX方法参数中,建议写String列名
            System.out.println(rs.getInt("sid")+"   "+rs.getString("sname")+
                    "   "+rs.getDouble("sprice")+"   "+rs.getString("sdesc"));
        }
        
        rs.close();
        stat.close();
        con.close();
    }

三 注入攻击

其原理就是利于数据库的查询语句漏洞,bug,缺陷.
假设查询某一个用户的sql 语句为 SELECT * FROM 用户表 WHERE NAME = 用户输入的用户名 AND PASSWORD = 用户输的密码;

但是当用户输入的账号为XXX 密码为:XXX’ OR ‘a’=’a时,则真正执行的代码变为:
SELECT * FROM 用户表 WHERE NAME = ‘XXX’ AND PASSWORD =’ XXX’ OR ’a’=’a’;
无论用户名和密码怎么样,都登录成功了,这就是SQL的注入攻击.

四 预处理对象

PreparedStatement预处理对象来避免注入攻击

public static void main(String[] args)throws Exception {
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username = "root";
        String password = "123";
        Connection con = DriverManager.getConnection(url, username, password);
        Scanner sc = new Scanner(System.in);
        String user = sc.nextLine();
        String pass = sc.nextLine();
        
        //执行SQL语句,数据表,查询用户名和密码,如果存在,登录成功,不存在登录失败
        String sql = "SELECT * FROM users WHERE username=? AND PASSWORD=?";
        //调用Connection接口的方法prepareStatement,获取PrepareStatement接口的实现类
        //方法中参数,SQL语句中的参数全部采用问号占位符
        PreparedStatement pst =  con.prepareStatement(sql);
        System.out.println(pst);
        //调用pst对象set方法,设置问号占位符上的参数
        pst.setObject(1, user);
        pst.setObject(2, pass);
        
        //调用方法,执行SQL,获取结果集
        ResultSet rs = pst.executeQuery();
        while(rs.next()){
            System.out.println(rs.getString("username")+"   "+rs.getString("password"));
        }
        
        rs.close();
        pst.close();
        con.close();
    }

PreparedStatement 更新操作

public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/mybase";
        String username="root";
        String password="123";
        Connection con = DriverManager.getConnection(url, username, password);  
        
        //拼写修改的SQL语句,参数采用?占位
        String sql = "UPDATE sort SET sname=?,sprice=? WHERE sid=?";
        //调用数据库连接对象con的方法prepareStatement获取SQL语句的预编译对象
        PreparedStatement pst = con.prepareStatement(sql);
        //调用pst的方法setXXX设置?占位
        pst.setObject(1, "汽车美容");
        pst.setObject(2, 49988);
        pst.setObject(3, 7);
        //调用pst方法执行SQL语句
        pst.executeUpdate();
        
        pst.close();
        con.close();
    }

五 : 工具类封装

  • 封装Connection,并返回其对象
public class JDBCUtils {
    private JDBCUtils(){}
    private static Connection con ;
    
    static{
        try{
            Class.forName("com.mysql.jdbc.Driver");
            String url = "jdbc:mysql://localhost:3306/mybase";
            String username="root";
            String password="123";
            con = DriverManager.getConnection(url, username, password);
        }catch(Exception ex){
            throw new RuntimeException(ex+"数据库连接失败");
        }
    }
    
    /*
     * 定义静态方法,返回数据库的连接对象
     */
    public static Connection getConnection(){
        return con;
    }
    
    
    public static void close(Connection con,Statement stat){
         
         if(stat!=null){
             try{
                 stat.close();
             }catch(SQLException ex){}
         }
         
         if(con!=null){
             try{
                 con.close();
             }catch(SQLException ex){}
         }
         
    }
    
    
    public static void close(Connection con,Statement stat , ResultSet rs){
         if(rs!=null){
             try{
                 rs.close();
             }catch(SQLException ex){}
         }
         
         if(stat!=null){
             try{
                 stat.close();
             }catch(SQLException ex){}
         }
         
         if(con!=null){
             try{
                 con.close();
             }catch(SQLException ex){}
         }
         
    }
}

测试工具类

public static void main(String[] args)throws Exception {
        Connection con = JDBCUtils.getConnection();
        PreparedStatement pst = con.prepareStatement("SELECT sname FROM sort");
        ResultSet rs = pst.executeQuery();
        while(rs.next()){
            System.out.println(rs.getString("sname"));
        }
        JDBCUtils.close(con, pst, rs);
    
    }

六 : 配置文件

为了避免硬编码,我们可以随时更换数据库密码,和库,我们用配置文件来动态的保存连接库的信息.

properties 建议

  • 文件位置:任意,建议src下
  • 文件名称:任意,扩展名为properties
  • 文件内容:一行一组数据,格式是“key=value”

文件内容

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mydb
user=root
password=root

工具类,动态的获取配置文件中的 账号密码,连接数据库

public class JDBCUtilsConfig {
    private static Connection con ;
    private static String driverClass;
    private static String url;
    private static String username;
    private static String password;
    
    static{
        try{
            readConfig();
            Class.forName(driverClass);
            con = DriverManager.getConnection(url, username, password);
        }catch(Exception ex){
            throw new RuntimeException("数据库连接失败");
        }
    }
    
    private static void readConfig()throws Exception{
        InputStream in = JDBCUtilsConfig.class.getClassLoader().getResourceAsStream("database.properties");
         Properties pro = new Properties();
         pro.load(in);
         driverClass=pro.getProperty("driverClass");
         url = pro.getProperty("url");
         username = pro.getProperty("username");
         password = pro.getProperty("password");
    }
    
    
    public static Connection getConnection(){
        return con;
    }
    
}

相关文章

网友评论

      本文标题:Java篇-JDBC

      本文链接:https://www.haomeiwen.com/subject/eyqlrftx.html