ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

2022-08-19 第八组 卢睿 学习心得

2022-08-19 21:32:58  阅读:164  来源: 互联网

标签:rs 19 08 score 2022 sql import conn pstmt


目录

JDBC

Statement的不足

  1. 大量的字符串拼接,代码可读性降低。
  2. sql注入

SQL注入

bug
通过字符串的拼接,可以得到一个恒等的sql语句,可以跳过某些判断


import com.util.JDBCUtil;
import org.junit.Test;

import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Scanner;

public class Ch01 {

    public static void main(String[] args) {
        login("zxcvzxcvzxcv","b' or '1' = '1");
    }


    public static void login(String username,String password) {
        Scanner sc = new Scanner(System.in);
        // 1.获取连接
        Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            conn = JDBCUtil.getConnection();
            stmt = conn.createStatement();
//            System.out.println("请输入用户名:");
//            String username = sc.next();
//            System.out.println("请输入密码:");
//            String password = sc.next();

            String sql = "select * from user where username = '"
                    + username + "' and password = '" +  password + "'";
//            StringBuilder strb = new StringBuilder("select * from user where username = ");
//            strb.append("'").append(username).append("'").append(" and password = '")
//                            .append(password).append("'");
//            String sql = strb.toString();
            System.out.println("sql:" + sql);
            rs = stmt.executeQuery(sql);
            if(rs.next()){
                System.out.println("登录成功,欢迎回来:" + username);
            }else {
                System.out.println("账号或密码错误!");
            }

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,stmt,rs);
        }
    }

}

PreparedStatement:预编译(预加载)接口

  1. 通过coon获取的对象
  2. 是Statement接口的子接口
  3. sql语句中可以传参。用?占位,通过setXXX方法来给?赋值
  4. 提高性能
  5. 避免sql注入
package com.morning_teacher;

import com.util.JDBCUtil;
import org.junit.Test;

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

public class Ch02 {

    @Test
    public void test03() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            conn = JDBCUtil.getConnection();

            String sql = "select * from user where username = ? and password = ?";

            pstmt = conn.prepareStatement(sql);
            pstmt.setString(1,"aaa");
            pstmt.setString(2,"b' or '1' = '1");

            rs = pstmt.executeQuery();
            if(rs.next()) {
                System.out.println("登录成功...");
            }else {
                System.out.println("账号或密码错误...");
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,pstmt,rs);
        }
    }

    @Test
    public void test02() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            conn = JDBCUtil.getConnection();

            String sql = "select * from scores where s_id = ?";

            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,7);

            rs = pstmt.executeQuery();
            while(rs.next()) {
                int sId = rs.getInt("s_id");
                int score = rs.getInt("score");
                int cId = rs.getInt("c_id");
                System.out.println("学号:" + sId + ",分数:" + score + ",科目号:" + cId);
            }
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,pstmt,rs);
        }
    }

    @Test
    public void test01() {

        Connection conn = null;
        PreparedStatement pstmt = null;

        try {
            conn = JDBCUtil.getConnection();
            String sql = "update teacher set name = ? where id = ?";
            // 预编译
            pstmt = conn.prepareStatement(sql);
            // 给占位符赋值,根据位置
            pstmt.setString(1,"JJ");
            pstmt.setInt(2,6);

            // 正式执行sql
            int i = pstmt.executeUpdate();
            System.out.println(i);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,pstmt);
        }

    }
}

案例

需求:查询学生姓名,分数,科目名
利用面向对象的思想
得到一个集合。
所有的查询和拼装集合的操作都在Dao类中去做
我们在Demo这个类中只做测试。

StudentScoreCourse类

public class StudentScoreCourse {

    private String sname;
    private Integer score;
    private String cname;

    public StudentScoreCourse() {
    }

    public StudentScoreCourse(String sname, Integer score, String cname) {
        this.sname = sname;
        this.score = score;
        this.cname = cname;
    }

    public String getSname() {
        return sname;
    }

    public void setSname(String sname) {
        this.sname = sname;
    }

    public Integer getScore() {
        return score;
    }

    public void setScore(Integer score) {
        this.score = score;
    }

    public String getCname() {
        return cname;
    }

    public void setCname(String cname) {
        this.cname = cname;
    }

    @Override
    public String toString() {
        return "StudentScoreCourse{" +
                "sname='" + sname + '\'' +
                ", score=" + score +
                ", cname='" + cname + '\'' +
                '}';
    }
}

StudentScoreCourseDao类

package com.morning_teacher.test;

import com.util.JDBCUtil;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class StudentScoreCourseDao {

    private final Connection conn;
    {
        try {
            conn = JDBCUtil.getConnection();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 查询的方法
     * 查询学生姓名,分数,科目名
     */
    public List<StudentScoreCourse> getAll() {
        List<StudentScoreCourse> stus = new ArrayList<>(16);
        String sql = "select s.name sname,r.score,c.name cname " +
                "from student s " +
                "left join scores r on s.id = r.s_id " +
                "left join course c on  c.id = r.c_id";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while(rs.next()){
                String sname = rs.getString("sname");
                int score = rs.getInt("score");
                String cname = rs.getString("cname");
                StudentScoreCourse ssc = new StudentScoreCourse(sname,score,cname);
                stus.add(ssc);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,pstmt,rs);
        }

        return stus;
    }

    /**
     * 查询某一个学生的分数
     */
    public List<StudentScoreCourse> getById(Integer sid) {
        List<StudentScoreCourse> stus = new ArrayList<>(16);
        String sql = "select s.name sname,r.score,c.name cname " +
                "from student s " +
                "left join scores r on s.id = r.s_id " +
                "left join course c on c.id = r.c_id where s_id = ?";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,sid);
            rs = pstmt.executeQuery();
            while(rs.next()){
                String sname = rs.getString("sname");
                int score = rs.getInt("score");
                String cname = rs.getString("cname");
                StudentScoreCourse ssc = new StudentScoreCourse(sname,score,cname);
                stus.add(ssc);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,pstmt,rs);
        }

        return stus;
    }


    /**
     * 查询某一个学生的某一科的分数
     */
    public StudentScoreCourse getBySidAndCid(Integer sid,Integer cid) {

        PreparedStatement pstmt = null;
        ResultSet rs = null;

        StudentScoreCourse ssc = null;
        String sql = "select s.name sname,r.score,c.name cname " +
                "from student s " +
                "left join scores r on s.id = r.s_id " +
                "left join course c on  c.id = r.c_id where s_id = ? and c_id = ?";
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,sid);
            pstmt.setInt(2,cid);
            rs = pstmt.executeQuery();
            while(rs.next()){
                String sname = rs.getString("sname");
                int score = rs.getInt("score");
                String cname = rs.getString("cname");
                ssc = new StudentScoreCourse(sname,score,cname);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,pstmt,rs);
        }

        return ssc;
    }

    /**
     * 查询某一个学生的总分
     */
    public Integer getCount(Integer id) {

        Integer score = 0;

        String sql = "select sum(score) score " +
                "from scores  " +
                "GROUP BY s_id HAVING s_id = ?";
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1,id);
            rs = pstmt.executeQuery();
            while (rs.next()) {
                score = rs.getInt("score");
            }

        } catch (SQLException e) {
            throw new RuntimeException(e);
        }finally {
            JDBCUtil.close(conn,pstmt,rs);
        }

        return score;
    }

    /**
     * 查询某一个学生的平均分
     */

    /**
     * 按照总分排序
     */
    public List<Integer> getOrderScore() {

        PreparedStatement pstmt = null;
        ResultSet rs = null;

        List<Integer> scores = new ArrayList<>();

        String sql = "select sum(score) score " +
                "from scores  " +
                "GROUP BY s_id ORDER BY score desc,s_id asc";

        try {
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();
            while(rs.next()) {
                int score = rs.getInt("score");
                scores.add(score);
            }
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }

        return scores;
    }

}

测试类

package com.morning_teacher.test;

import org.junit.Test;

import java.util.List;

public class Demo {

    StudentScoreCourseDao dao = new StudentScoreCourseDao();

    @Test
    public void test01() {
        // 查询学生姓名,成绩,科目名
//        System.out.println(dao.getAll());
//        System.out.println(dao.getById(2));
//        System.out.println(dao.getBySidAndCid(2, 2));
//        System.out.println(dao.getCount(1));
        System.out.println(dao.getOrderScore());
    }

}

ResultSetMetaData(了解即可)


import com.util.JDBCUtil;
import org.junit.Test;

import java.io.IOException;
import java.sql.*;

public class Ch01 {

    @Test
    public void test03() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;

        try {
            conn = JDBCUtil.getConnection();

            String sql = "select * from user";

            pstmt = conn.prepareStatement(sql);

            rs = pstmt.executeQuery();

            // 获取元数据
            /*
                元数据:表格本身的数据
                    表格的列名,结果集的列名
             */
            ResultSetMetaData metaData = rs.getMetaData();
//            System.out.println(metaData.getColumnName(1));
//            System.out.println(metaData.getColumnName(2));
//            System.out.println(metaData.getColumnCount());
//            metaData.get
            for (int i = 1; i <= metaData.getColumnCount() ; i++) {
                metaData.getColumnName(i);
            }


            while (rs.next()) {
                int id = rs.getInt("id");
                String username = rs.getString("username");
                String password = rs.getString("password");
                System.out.println("id:" + id + ",username:" + username + ",password:" + password);
            }

        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,pstmt,rs);
        }
    }

}

数据库事务

是数据库的特性

Mysql的数据库引擎4

  1. 在MySQL中,只有使用了Innodb引擎的数据库才支持事务
  2. 事务处理可以用来维护数据的完整性。保证sql语句要么全部执行,要么全部不执行。
  3. 发生在DML中,增删改。

事务的四大特征ACID

原子性 A。

一个事务,要么全部完成,要么全部不完成。

一致性 C。

在事务开始之前和事务结束之后,数据库的完整性没有被破坏。

隔离性 Isolation

数据库允许多个事务同时对数据进行处理。每个事务之间是相互隔离。

持久性 D

事务结束以后,对数据的增删改是永久性的。

术语

提交事务,回滚事务(事务回滚)

  1. 事务一旦提交,就不可能回滚。
  2. 当一个连接对象被创建时,默认情况下自动提交事务。
  3. 关闭连接时,数据会自动提交事务。

操作事务的步骤

  1. 关闭事务的自动提交
  2. 当做出增删改操作,把变化发生在内存中,提交事务,才会真正提交给数据库。
package com.afternoon_teacher;

import com.util.JDBCUtil;
import org.junit.Test;

import java.io.IOException;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class Ch02 {

    @Test
    public void test01() {
        Connection conn = null;
        PreparedStatement pstmt1 = null;
        PreparedStatement pstmt2 = null;

        try {
            conn = JDBCUtil.getConnection();
            // 关闭事务的自动提交
            // true:开启(默认) false:关闭
            // 开启一个事务
            conn.setAutoCommit(false);
            // 把id为1的账户余额-1000
            String sql1 = "update bank set balance = balance - 1000 where id = 1";
            pstmt1 = conn.prepareStatement(sql1);
            pstmt1.executeUpdate();

            String sql2 = "update bank set balance = balance + 1000 where id = 2";
            pstmt2 = conn.prepareStatement(sql2);
            pstmt2.executeUpdate();

            int i = 10 / 0;

            // 提交事务
            conn.commit();

            System.out.println("转账成功...");

        } catch (Exception e) {
            try {
                // 事务回滚
                conn.rollback();
            } catch (SQLException ex) {
                throw new RuntimeException(ex);
            }
            throw new RuntimeException(e);
        } finally {
            JDBCUtil.close(conn,pstmt1);
            JDBCUtil.close(null,pstmt2);
        }
    }

}

标签:rs,19,08,score,2022,sql,import,conn,pstmt
来源: https://www.cnblogs.com/lurui711/p/16603343.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有