shell、JDBC操作数据库(包含SQL注入问题)

这一块的内容主要是有关shell和JDBC操作数据库的内容,JDBC占大部分

shell操作数据库

shell中写好一个脚本

在这里插入图片描述

四块内容,一个是MySQL以及登陆密码,一个是执行sql,由于脚本中不能切换数据库和表,就直接在脚本中写好数据库名和表名,写出结果集,输出结果集,直接sh执行即可

在这里插入图片描述

JDBC操作数据库

在ieda中导入需要的包

注意:
JDBC可以连接许多数据库,不止MySQL,我们可以说使用了JDBC连接MySQL数据库,但不能说MySQL数据库就是JDBC

我们如果使用Java代码操作数据库,需要写很多内容。
IP地址、端口、网络协议
这三个都需要一点点写好。

但我们如果使用第三方工具,就比较方便了,使用第三方工具,我们需要先导包(mysql-connector-java.5.1.17.jar),我的MySQL版本是5.x版本的
在这里插入图片描述

找到项目的Project Structure
再点击右侧的“+”号,找到自己本地的包路径,添加进去在这里插入图片描述

第一种JDBC操作数据库(执行器是createStatement)

查询操作

//MySQL的查询操作
public class mysqlSelect {
    public static void main(String[] args) throws Exception{
        //1.加载驱动
        //通过反射导入需要的第三方的包,第三方的工具类都已经再里面了,可以使用里面的方法了
        Class.forName("com.mysql.jdbc.Driver");

        //2.建立连接
        //(相当于MySQL的客户端)
        Connection conn = DriverManager.getConnection(
                //指定端口和操作的库
                "jdbc:mysql://master:3306/test1",
                "root",
                "123456"
        );

        //3.创建执行器(就开始使用客户端来使用执行器了),用来执行sql
        //3.1执行器createStatement
        String sql="select * from dept";
        Statement statement = conn.createStatement();
        //3.2执行器prepareStatement


        //4.执行sql语句
        //execute返回的结果是一个Boolean类型,只能判断是否执行
        //boolean execute = statement.execute(sql);
        //executeQuery返回的是一个结果集,用来输出
        ResultSet resultSet = statement.executeQuery(sql);
        while (resultSet.next()){
            //这里有三个字段,给它三个

            //这里getString中放入了整数,表示是哪个字段
//            System.out.println(resultSet.getInt(1));
//            System.out.println(resultSet.getString(2));
//            System.out.println(resultSet.getString(3));

            //这里给的是String类型,表示的是字段名称
            System.out.println(resultSet.getInt("deptno"));
            System.out.println(resultSet.getString("dname"));
            System.out.println(resultSet.getString("loc"));
        }

        //5.获取结果
        System.out.println(resultSet);
        //System.out.println(execute);

        //6.关闭
        resultSet.close();
        statement.close();
        conn.close();
    }
}

添加操作(特别注意键盘录入的拼接操作)

public class mysqlInsert {
    public static void main(String[] args) throws Exception{
        //直接插入信息
//        Class.forName("com.mysql.jdbc.Driver");
//        Connection conn = DriverManager.getConnection(
//                "jdbc:mysql://master:3306/test1",
//                "root",
//                "123456"
//        );
//        Statement statement = conn.createStatement();
//        String sql = "insert into dept values(50,'doctor','HuaiBei')";
//        int i = statement.executeUpdate(sql);
//        if(i!=0){
//            System.out.println("添加成功");
//        }else {
//            System.out.println("添加失败");
//        }
//        statement.close();
//        conn.close();


        //键盘录入信息
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入部门编号");
        Integer deptno = sc.nextInt();
        System.out.println("请输入部门职责");
        String dname = sc.next();
        System.out.println("请输入工作地点");
        String loc = sc.next();

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://master:3306/test1",
                "root",
                "123456"
        );
        Statement statement = conn.createStatement();
        String sql = "insert into dept values("
                    +deptno+","+
                    "\""+dname+"\"" + ","+
                    "\""+loc+"\")";
        System.out.println(sql);
        int i = statement.executeUpdate(sql);
        if(i!=0){
            System.out.println("录入成功");
        }else {
            System.out.println("录入失败");
        }
        statement.close();
        conn.close();
    }
}

删除操作

public class mysqlDelete {
    public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://master:3306/test1",
                "root",
                "123456"
        );
        Statement statement = conn.createStatement();
        String sql = "delete from dept where deptno=10";
        int i = statement.executeUpdate(sql);
        if(i!=0){
            System.out.println("删除成功");
        }else{
            System.out.println("删除失败");
        }
        statement.close();
        conn.close();
    }
}

更新操作

public class mysqlUpdate {
    public static void main(String[] args) throws Exception{
        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://master:3306/test1",
                "root",
                "123456"
        );
        Statement statement = conn.createStatement();
        String sql = "update dept set loc='shanghai' where deptno=60";
        int i = statement.executeUpdate(sql);
        if(i!=0){
            System.out.println("更新成功");
        }else{
            System.out.println("更新失败");
        }
        statement.close();
        conn.close();
    }
}

createStatement和prapareStatement两个执行器的区别(SQL注入问题)

使用登录的例子来查看,来一张新表
在这里插入图片描述
我们来简单模仿一个登录验证的内容

public class Login1 {
    public static void main(String[] args) throws Exception{
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户");
        String username = sc.nextLine();
        System.out.println("请输入密码");
        String password = sc.next();

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://master:3306/test1",
                "root",
                "123456"
        );
        Statement statement = conn.createStatement();

        //SQL注入(参数传递时,参数里面的内容被当作关键字使用)
        //输入用户:123' or '1=1  密码:123456(密码正确),登陆成功
        //createStatement会把你输入的一整条sql语句给识别
        //也就是说,会把你输入的or(关键字)给识别成功,但实际上or应该被当作实参

        //1.通过用户名去MySQL中查找有没有这一条记录(存在:输入密码,不存在:报错)
        //2.存在之后,用查到的密码,匹配你输入的密码
        //判断用户是否存在:
        //1.(可以)
        String sql = "select * from user where username="+"'"+username+"'";
        System.out.println(sql);
        ResultSet resultSet = statement.executeQuery(sql);
//        while (resultSet.next()){
//            String username1 = resultSet.getString("username");
//            System.out.println(username1);
//        }
        //2.
        //if(resultSet==null)   if(resultSet.wasNull)   都出错
        //3.(如果没有下一条记录,那就失败)
        if(!resultSet.next()){
            System.out.println("用户输入错误");
        }else{//用户输入正确
            System.out.println("用户存在");
            //匹配密码
            String password1 = resultSet.getString("password");
//            if(password!=null && password.equals(password1)){
//                System.out.println("登陆成功");
//            }
            if(password==null || !password.equals(password1)){
                System.out.println("密码不匹配,登陆失败");
            }else {
                System.out.println("登陆成功");
            }
        }

        resultSet.close();
        statement.close();
        conn.close();
    }
}

SQL注入(将参数当作关键字)

我们可以看到,在这里面,我们把’123 or 1=1’当作一个username来进行验证,但实际上,我们的数据表中是没有这一条数据的,但是我们依然可以登陆成功,这里就牵扯到SQL注入问题,MySQL把or当作了一个关键字放到数据库进行识别,而不是当作一个参数进行验证。
在这里插入图片描述

SQL注入的解决办法

解决办法:
我们只要将整条sql当作一个模板,参数先找一个占位符;将这个内容传到MySQL中,之后再拿值来替换这个占位符即可,这也就是prepareStatement
在这里插入图片描述

第二种JDBC操作数据库(执行器是prepareStatement),同时解决SQL注入问题

public class Login2 {
    public static void main(String[] args) throws Exception{
        Scanner sc = new Scanner(System.in);
        System.out.println("请输入用户");
        String username = sc.nextLine();
        System.out.println("请输入密码");
        String password = sc.next();

        Class.forName("com.mysql.jdbc.Driver");
        Connection conn = DriverManager.getConnection(
                "jdbc:mysql://master:3306/test1",
                "root",
                "123456"
        );

        String sql = "select * from user where username=? and password=?";
        PreparedStatement statement = conn.prepareStatement(sql);
        statement.setString(1,username);
        statement.setString(2,password);

        System.out.println(sql);
        ResultSet resultSet = statement.executeQuery();
        if(!resultSet.next()){
            System.out.println("用户输入错误");
        }else{//用户输入正确
            System.out.println("用户存在");
            //匹配密码
            String password1 = resultSet.getString("password");
            if(password==null || !password.equals(password1)){
                System.out.println("密码不匹配,登陆失败");
            }else {
                System.out.println("登陆成功");
            }
        }
        resultSet.close();
        statement.close();
        conn.close();
    }
}

第三种JDBC操作数据库(提取工具类)

public class MysqlUtil {
    private static String DRIVER="com.mysql.jdbc.Driver";
    private static String URL="jdbc:mysql://master3306/test1";
    private static String USERNAME="root";
    private static String PASSWORD="123456";
    private static Connection connection;
    private static PreparedStatement ps;
    private static ResultSet rs;

    //静态,使用的时候只加载一次
    static {
        try {
            Class.forName(DRIVER);
            try {
                connection=DriverManager.getConnection(URL,USERNAME,PASSWORD);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    public Connection getConnection(){
        return connection;
    }

    public PreparedStatement getPs(String sql) throws Exception{
        ps=connection.prepareStatement(sql);
        return ps;
    }

    public ResultSet select() throws Exception{
        rs=ps.executeQuery();
        return rs;
    }

    public int update() throws Exception{
        int i = ps.executeUpdate();
        return i;
    }

    public void close(Connection connection,PreparedStatement ps){
        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public void close(){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

第四种JDBC操作数据库(配置文件)

配置文件:Resources目录

在这里插入图片描述
先创建一个目录,让它变成一个resources目录
在这里插入图片描述

再创建一个配置文件
properties是一个类,专门用来操作配置文件
在这里插入图片描述
配置文件信息:

在这里插入图片描述

反射加载开头几步:

        //操作配置文件中的信息
        Properties properties = new Properties();
        //反射加载配置文件
        //test.class获取到当前类的class文件
        //获取反射加载类的对象getClassLoader,加载配置文件
        //通过流获取配置文件的配置信息
        //路径怕错就给全路径
        InputStream is = test.class.getClassLoader().getResourceAsStream("test.properties");

        //信息已经到is中了,接下来搞到properties中,来做操作
        properties.load(is);
        String driver = properties.getProperty("driver");
        String url = properties.getProperty("url");
        String username = properties.getProperty("username");
        String password = properties.getProperty("password");

完整的MySQLutil(里面方法都应该是静态的,忘记加上了)

public class MysqlUtil {
    private static String DRIVER;
    private static String URL;
    private static String USERNAME;
    private static String PASSWORD;
    private static Connection connection;
    private static PreparedStatement ps;
    private static ResultSet rs;

    //静态,使用的时候只加载一次
    static {
        //操作配置文件中的信息
        Properties properties = new Properties();
        //反射加载配置文件
        //test.class获取到当前类的class文件
        //获取反射加载类的对象getClassLoader,加载配置文件
        //通过流获取配置文件的配置信息
        //路径怕错就给全路径
        InputStream is = test.class.getClassLoader().getResourceAsStream("test.properties");

        //信息已经到is中了,接下来搞到properties中,来做操作
        try {
            properties.load(is);
        } catch (IOException e) {
            e.printStackTrace();
        }
        DRIVER= properties.getProperty("driver");
        URL= properties.getProperty("url");
        USERNAME= properties.getProperty("username");
        PASSWORD= properties.getProperty("password");
    }

    public Connection getConnection(){
        return connection;
    }

    public PreparedStatement getPs(String sql) throws Exception{
        ps=connection.prepareStatement(sql);
        return ps;
    }

    public ResultSet select() throws Exception{
        rs=ps.executeQuery();
        return rs;
    }

    public int update() throws Exception{
        int i = ps.executeUpdate();
        return i;
    }

    public void close(Connection connection,PreparedStatement ps){
        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    public void close(){
        if(rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(ps!=null){
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(connection!=null){
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

啊帅和和。

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值