zoukankan      html  css  js  c++  java
  • Javaweb入门 JDBC第一天

    JDBC的定义和作用

      DBC(Java DataBase Connectivity) Java数据库连接, 其实就是利用Java语言/程序连接并访问数据库的一门技术。

       之前我们可以通过cmd或者navicat等工具连接并访问数据库,但是在企业开发中,我们更多的是通过程序连接并访问数据库。如果通过Java程序访问数据库,就必须要使用JDBC这门技术!!

    JDBC访问数据库操作

      创建一个 jt_db 数据库,在库中创建一个account表,并插入三条记录,然后利用Java程序查询出account表中所有的记录,并打印在控制台上。

    快速人门程序了解:

    创建Java类并实现JDBC程序(大致分为六个步骤)

    package com.tedu;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.Statement;
    
    //JDBC快速入门程序
    public class JdbcDemo1 {
        public static void main(String[] args) throws Exception {
            /*
             * 通过Java程序查询jt_db.account表中的所有记录
             * 将查询的结果输出到控制台上
             */
    //        1.注册数据库
            Class.forName("com.mysql.jdbc.Driver");
    //        2.获取数据库连接
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/jt_db", 
                    "root", "root");
    //        3.获取传输器
            Statement stat = conn.createStatement();
    //        4.发送SQL语句到数据库执行,并返回执行结果
            String sql="select * from account";
            ResultSet r = stat.executeQuery(sql);
    //        5.处理结果
    //        r.next();判断是否指向记录,最开始指向表头的,用一次指向下一行记录,有记录返回true
            while (r.next()) {//进去循环,指向第一行数据,获取数据
                int id=r.getInt("id");
                String name=r.getString("name");
                double money=r.getDouble("money");
                System.out.println(id+", "+name+", "+money);
            }
    //        6.释放资源
            r.close();
            stat.close();
            conn.close();
        }
    }

    JDBC快速入门细节

    1.注册数据驱动

    //注册数据库驱动
    Class.forName("com.mysql.jdbc.Driver");

    上面这行代码是根据传入的类的全路径(包名+类名)加载一个类到内存中。

    在Driver类中有一个静态代码块,静态代码块中包含着注册驱动的代码。

    因此上面这行代码本身其实并不能注册驱动,但是可以让注册驱动的代码执行!

    2.获取数据库连接

    //获取数据库连接块
    Connection conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/jt_db", 
                    "root", "root");

    后面传入的两个参数分别是连接数据库的用户名和密码,这里不再过多描述

    第一个参数是连接数据库的url地址(描述连接的是哪一个位置的哪一个库)。其中URL地址的结构如下:

    jdbc:mysql://localhost:3306/jt_db

    ————  —————— -----------

      协议名     主机名+端口    数据库的名字

    其结构类似于平时访问的网址:

    http://www.baidu.com:80/index.html?user=zhangfei

    另外在URL后面可以通过问号拼接参数:

    jdbc:mysql:///jt_db?characterEncoding=utf-8

    characterEncoding=utf-8 可以预防JDBC乱码

    (可以避免通过JDBC往数据库插入中文数据时乱码

    同时也可以避免通过JDBC从数据库查询数据时出现中文乱码问题)

    3.Statement传输器对象

    Stat.executeQuery( sql ) – 执行查询类的SQL语句, 执行的结果是一个ResultSet对象, 其中包含了查询的结果

    Stat.executeUpdate( sql ) – 执行增删改类型的SQL语句, 执行的结果是一个int值, 表示影响的记录行数。

    4.ResultSet结果集对象

    ResultSet结果集其中包含了SQL查询后的结果, 该对象上提供了遍历数据的方法和获取数据的方法:

    (1)遍历数据行的方法

    Rs.next() – 将指向数据行的箭头往下挪动一行, 如果挪动一行后指向了一行记录, 方法将返回true, 否则返回false。

    (2)获取数据的方法

    Rs.getInt( colName )

    Rs.getString( colName )

    Rs.getDouble( colName )

    Rs.getObject( colName )

    ...

    5.释放资源

    Rs.close();

    Stat.close();

    Conn.close();

     

    释放时遵循一个顺序, 越晚获取的越先关闭!!

    JDBC增删改查

    1、新增:往account表中插入一条新的记录,name "john"money3000

    @Test
        
        public void add() throws Exception{
            /*
             * 新增:往account表中插入一条新纪录,name为"join",money为30000
             */
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/jt_db", 
                    "root", "root");
            Statement stat = conn.createStatement();
            String sql="insert into account values (null,'john',3000)";
            int r = stat.executeUpdate(sql);//返回影响的行数
            System.out.println("影响的行数:"+r);
            stat.close();
            conn.close();
        }

    2修改:修改account表中name "john" 的记录,将金额改为1500

    @Test
        public void update() throws Exception{
            /*
             * 修改account表中name为 "john" 的记录,将金额改为1500
             */
            Connection conn = JDBCUtil.getConn();
            Statement stat = conn.createStatement();
            String sql="Update account set money =1500 where     
                                     name='john' ";
            int r = stat.executeUpdate(sql);
            System.out.println("影响行数:"+r);
            JDBCUtil.close(conn, stat, null);
        }

    3删除:删除account表中name为 "john" 的记录

    @Test
        public void delete() throws Exception{
            /*
             * 删除:删除account表中name为 "john" 的记录
             */
            Connection conn = JDBCUtil.getConn();
            Statement stat = conn.createStatement();
            String sql="delete from account where name='John'";
            int r = stat.executeUpdate(sql);
            System.out.println("影响行数:"+r);
            JDBCUtil.close(conn, stat, null);
        }

    4、查询:查询account表中id1的记录

    @Test
        public void find() throws Exception{
            /*
             * 查询account表中id为1的记录
             */
            Connection conn = JDBCUtil.getConn();
            Statement stat = conn.createStatement();
            String sql="select * from account where id=1";
            ResultSet r = stat.executeQuery(sql);
    //        while (r.next()) {
    //            int id=r.getInt("id");
    //            String name=r.getString("name");
    //            double money=r.getDouble("money");
    //            System.out.println(id+","+name+","+money);
    //        }
            if(r.next()){
                int id=r.getInt("id");
                String name=r.getString("name");
                double money=r.getDouble("money");
                System.out.println(id+","+name+","+money);
            }
            JDBCUtil.close(conn, stat, r);
        }

    上面代码中调用了工具类中注册,连接数据库和释放资源的方法

    package com.tedu.util;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    /** JDBC工具类 */
    public class JDBCUtil {
        /**
         * 获取数据库连接对象并返回
         * @return Connection对象
         * @throws Exception 
         */
        public static Connection getConn() throws Exception{
            //1.注册驱动
            Class.forName( "com.mysql.jdbc.Driver" );
            //2.获取连接
            Connection conn = DriverManager.getConnection(
                    "jdbc:mysql:///jt_db?characterEncoding=utf-8", 
                    "root", 
                    "root");
            return conn;
        }
        
        /**
         * 释放JDBC程序中的资源
         * @param conn 连接对象
         * @param stat 传输器对象
         * @param rs 结果集对象
         */
        public static void close(Connection conn, 
                Statement stat, ResultSet rs){
            if(rs != null){
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally{
                    rs = null;
                }
            }
            if(stat != null){
                try {
                    stat.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally{
                    stat = null;
                }
            }
            if(conn != null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                } finally{
                    conn = null;
                }
            }
        }
    }

    模拟用户登录案例

    创建LoginUser类,提供mian方法和login方法

    public static void main(String[] args) {
    
        /* 提示用户在控制台输入用户名和密码,并接收用户名和密码
    
         * 根据用户名和密码查询user表, 如果查询到记录, 则证明
    
         * 用户名密码正确, 模拟登录, 否则提示用户名密码错误!!*/
    
       
    
        Scanner in = new Scanner( System.in );
    
        //1.提示用户输入用户名和密码,并接收
    
        System.out.println("请登录...");
    
        System.out.println("请输入用户名:");
    
        String user = in.nextLine();
    
        System.out.println("请输入密码:");
    
        String pwd = in.nextLine();
    
       
    
        //2.调用login方法, 传入用户名和密码进行登录操作
    
        login( user, pwd );
    
    }
    
    /**
    
     * 根据用户名和密码进行登录
    
     * @param user 用户名
    
     * @param pwd 密码
    
     */
    
    private static void login(String user, String pwd) {
    
        Connection conn = null;
    
        Statement stat = null;
    
        ResultSet rs = null;
    
        try {
    
           //1.注册驱动并获取连接
    
           conn = JdbcUtil.getConn();
    
           //2.获取传输器并执行sql语句
    
           stat = conn.createStatement();
    
           String sql =
    
                  "select * from user where username='"
    
                   +user+"' and password='"+pwd+"'";
    
           System.out.println( sql );
    
           rs = stat.executeQuery( sql );
    
           //3.处理结果
    
           if( rs.next() ) {//用户名密码正确
    
               System.out.println("恭喜您登录成功!!");
    
           }else {
    
               System.out.println("登录失败! 用户名或密码不正确!!");
    
           }
    
        } catch (Exception e) {
    
           e.printStackTrace();
    
        }
    
    }

    执行时输入:

    请登录...
    请输入用户名:
    张飞'#'
    请输入密码:
    
    select * from user where username='张飞'#'' and password=''
    恭喜您登录成功!!

    或输入:

    请登录...
    请输入用户名:
    张飞' or '1=1
    请输入密码:
    
    select * from user where username='张飞' or '1=1' and password=''
    恭喜您登录成功!!

    或输入:

    请登录...
    请输入用户名:
     
    请输入密码:
    ' or '2=2
    select * from user where username='' and password='' or '1=1'
    恭喜您登录成功!!

    以上在用户名或密码错误的情况下也能登录,就是SQL注入攻击

    SQL注入攻击是一种常见的网络攻击方式,其产生的原因是:

    由于后台的SQL语句是拼接而来的, 其中的参数是用户提交过来的, 如果用户在提交参数时, 在参数中添加了一些SQL关键字或者特殊符号, 就可能会导致SQL语句语义的改变,从而导致一些意外的操作,比如用户名或密码错误也能登录成功!

    解决方案:

    (1)通过正则对用户提交的用户名或密码进行检查, 如果其中包含

     SQL关键字或者特殊符号, 则提示用户名或密码输入不合法

    (2)通过PreparedStatement对象可以防止SQL注入攻击!

    防止SQL注入攻击

    PreparedStatement对象是如何防止SQL注入攻击的?

    先将SQL语句的骨架(包含问号占位符)发送给服务器, 让服务器编译并确定下来。

    再将SQL语句中的参数发送给服务器,由于前面服务器已经确定了SQL语句(一旦确定就不能被改变),因此参数中即使再包含SQL关键字或者特殊符号,也不会影响SQL语句的语义,只会被当做普通的文本来对待!

    /**
    
     * 根据用户名和密码进行登录
    
     * @param user 用户名
    
     * @param pwd 密码
    
     */
    
    private static void login(String user, String pwd) {
    
        Connection conn = null;
    
        PreparedStatement stat = null;
    
        ResultSet rs = null;
    
        try {
    
           //1.注册驱动并获取连接
    
           conn = JdbcUtil.getConn();
    
           //2.获取传输器并执行sql语句
    
           String sql = "select * from user where"
    
                  + " username=? and password=?";
    
           stat = conn.prepareStatement( sql );
    
           //设置sql参数(如果有?占位符)
    
           stat.setString( 1 ,  user );
    
           stat.setString( 2, pwd );
    
           //执行sql语句
    
           rs = stat.executeQuery( );//不要再传SQL语句!
    
     
    
           //3.处理结果
    
           if( rs.next() ) {//用户名密码正确
    
               System.out.println("恭喜您登录成功!!");
    
           }else {
    
               System.out.println("登录失败! 用户名或密码不正确!!");
    
           }
    
        } catch (Exception e) {
    
           e.printStackTrace();
    
        } finally {
    
           //4.释放资源
    
           JdbcUtil.close(conn, stat, rs);
    
        }
    
    }
  • 相关阅读:
    git push出现unpack failed: error Missing tree错误的解决方法
    Android N 分屏
    adb 查看最上层activity名字
    Ubuntu 切换JDK 版本
    Android的开机流程
    HTTP 协议中GET和POST到底有哪些区别(转)
    github爬虫100项目
    web攻击之xss(一)
    Kali-Dos洪水攻击之Hping3
    zipCrack-v1.1 工具介绍
  • 原文地址:https://www.cnblogs.com/kjs-1998/p/11272284.html
Copyright © 2011-2022 走看看