JDBC---使用 Statement 和ResultSet执行操作

版权声明:本文为小斑马伟原创文章,转载请注明出处!
Statement:通过调用 Connection 对象的 createStatement 方法创建该对象。该对象用于执行静态的 SQL 语句,并且返回执行结果。Statement 接口中定义了下列方法用于执行 SQL 语句:

  • ResultSet excuteQuery(String sql)
  • int excuteUpdate(String sql)

ResultSet:通过调用 Statement 对象的 excuteQuery() 方法创建该对象。ResultSet 对象以逻辑表格的形式封装了执行数据库操作的结果集,ResultSet 接口由数据库厂商实现。ResultSet 对象维护了一个指向当前数据行的游标,初始的时候,游标在第一行之前,可以通过 ResultSet 对象的 next() 方法移动到下一行
。ResultSet 接口的常用方法:
boolean next()
getString()


通过 JDBC 向指定的数据表中插入一条记录.

  @Test
   public void testStatement() throws Exception{
    //1. 获取数据库连接
    Connection conn = null;
    Statement statement = null;
    
    try {
        conn = getConnection2();
        
        //3. 准备插入的 SQL 语句
        String sql = null;
        
       //sql = "INSERT INTO customers (NAME, EMAIL, BIRTH) " +
            //"VALUES('XYZ', 'xyz@atguigu.com', '1990-12-12')";
      //sql = "DELETE FROM customers WHERE id = 1";
        sql = "UPDATE customers SET name = 'TOM' " +
                "WHERE id = 4";
        System.out.println(sql);
        
        //4. 执行插入. 
        //1). 获取操作 SQL 语句的 Statement 对象: 
        //调用 Connection 的 createStatement() 方法来获取
        statement = conn.createStatement();
        
        //2). 调用 Statement 对象的 executeUpdate(sql) 执行 SQL 语句进行插入
        statement.executeUpdate(sql);
    } catch (Exception e) {
        e.printStackTrace();
    } finally{
        try {
            //5. 关闭 Statement 对象.
            if(statement != null)
                statement.close();
        } catch (Exception e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } finally{
            //2. 关闭连接
            if(conn != null)
                conn.close();                           
        }
    }
   }

1. Statement: 用于执行 SQL 语句的对象
* 1). 通过 Connection 的 createStatement() 方法来获取。
* 2). 通过 executeUpdate(sql) 可以执行 SQL 语句。
* 3). 传入的 SQL 可以是 INSRET, UPDATE 或 DELETE. 但不能是 SELECT。
* 2. Connection、Statement 都是应用程序和数据库服务器的连接资源. 使用后一定要关闭.
* 需要在 finally 中关闭 Connection 和 Statement 对象。
* 3. 关闭的顺序是: 先关闭后获取的. 即先关闭 Statement 后关闭 Connection。

/**
 * 通用的更新的方法: 包括 INSERT、UPDATE、DELETE
 * 版本 1.
 */
public void update(String sql){
    Connection conn = null;
    Statement statement = null;
    
    try {
        conn = JDBCTools.getConnection();
        statement = conn.createStatement();
        statement.executeUpdate(sql);
    } catch (Exception e) {
        e.printStackTrace();
    } finally{
        JDBCTools.release(statement, conn);
    }
}

具体的getConnection2()数据库连接方式见

@Test
public void testResultSet(){
    //获取 id=4 的 customers 数据表的记录, 并打印
    
    Connection conn = null;
    Statement statement = null;
    ResultSet rs = null;
    
    try {
        //1. 获取 Connection
        conn = JDBCTools.getConnection();
        System.out.println(conn);
        
        //2. 获取 Statement
        statement = conn.createStatement();
        System.out.println(statement);
        
        //3. 准备 SQL
        String sql = "SELECT id, name, email, birth " +
                "FROM customers";
        
        //4. 执行查询, 得到 ResultSet
        rs = statement.executeQuery(sql);
        System.out.println(rs);
        
        //5. 处理 ResultSet
        while(rs.next()){
            int id = rs.getInt(1);
            String name = rs.getString("name");
            String email = rs.getString(3);
            Date birth = rs.getDate(4);
            
            System.out.println(id);
            System.out.println(name);
            System.out.println(email);
            System.out.println(birth);
        }
        
    } catch (Exception e) {
        e.printStackTrace();
    } finally{
        //6. 关闭数据库资源. 
        JDBCTools.release(rs, statement, conn);
    }
}

ResultSet: 结果集. 封装了使用 JDBC 进行查询的结果.

    1. 调用 Statement 对象的 executeQuery(sql) 可以得到结果集。
    1. ResultSet 返回的实际上就是一张数据表. 有一个指针指向数据表的第一样的前面. 可以调用 next() 方法检测下一行是否有效. 若有效该方法返回 true, 且指针下移. 相当于 Iterator 对象的 hasNext() 和 next() 方法的结合体。
    1. 当指针对位到一行时, 可以通过调用 getXxx(index) 或 getXxx(columnName) 获取每一列的值. 例如: getInt(1), getString("name")。
    1. ResultSet 当然也需要进行关闭.。
public static void release(ResultSet rs, 
        Statement statement, Connection conn) {
    if(rs != null){
        try {
            rs.close();
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
    
    
    if (statement != null) {
        try {
            statement.close();
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }

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

/**
 * 关闭 Statement 和 Connection
 * @param statement
 * @param conn
 */
public static void release(Statement statement, Connection conn) {
    if (statement != null) {
        try {
            statement.close();
        } catch (Exception e2) {
            e2.printStackTrace();
        }
    }

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

SQL 注入攻击:SQL 注入是利用某些系统没有对用户输入的数据进行充分的检查,而在用户输入数据中注入非法的 SQL 语句段或命令,从而利用系统的 SQL 引擎完成恶意行为的做法。对于 Java 而言,要防范 SQL 注入,只要用 PreparedStatement 取代 Statement 就可以了。

 /**
 * SQL 注入.
 */
@Test
public void testSQLInjection() {
    String username = "a' OR PASSWORD = ";
    String password = " OR '1'='1";

    String sql = "SELECT * FROM users WHERE username = '" + username
            + "' AND " + "password = '" + password + "'";

    System.out.println(sql);

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

    try {
        connection = JDBCTools.getConnection();
        statement = connection.createStatement();
        resultSet = statement.executeQuery(sql);

        if (resultSet.next()) {
            System.out.println("登录成功!");
        } else {
            System.out.println("用户名和密码不匹配或用户名不存在. ");
        }

    } catch (Exception e) {
        e.printStackTrace();
    } finally {
        JDBCTools.releaseDB(resultSet, statement, connection);
    }
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,402评论 6 499
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,377评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,483评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,165评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,176评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,146评论 1 297
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,032评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,896评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,311评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,536评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,696评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,413评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,008评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,659评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,815评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,698评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,592评论 2 353

推荐阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,072评论 25 707
  • 虽然没有看过银河护卫队1,但是在电影院看3D电影是我的喜爱,视觉上给我一种冲击,今天看了银河护卫队2后,感受最深的...
    諪諪_0c2f阅读 178评论 0 0
  • 唯一可以抱怨的,只是不够努力的自己 生活所带来的很多东西,有时候是我们能接受的,有时候是我们不能接受的 活着是需要...
    娇之语阅读 237评论 0 0
  • 第三天了,陪孩子做作业,让她进行学校作业之外的学习,她不抵触了,我的小火山控制的也很好!应该算是个进步吧?
    空空主义BIUBIU阅读 172评论 0 1
  • 前几天跟一个不是很相熟的朋友闲聊,问到家中兄弟姐妹,回答说,还有个妹妹,姐妹俩,朋友很诧异,一直念叨,农村里但凡是...
    月华缓缓阅读 402评论 0 0