JDBC---java 数据库连接 通过Java代码来操作数据库表中的记录(增删改查) sql注入安全问题

JDBC下载(百度MySQL驱动)

Java属于什么语言? ---- OOP面向对象的语言

数据库属于什么语言? ----SQL语言:结构化查询语言

上面会因为语言不同,带来沟通问题?

如果是你如何解决java和数据库之间的沟通? -- 找个翻译官

1.Java连接MySQL数据库 

步骤:

1.创建一个Java工程

2.在工程下创建一个目录lib ---->放jar的 

3.把该jar进行解压---->一定要在程序中完成

 4.写程序

(1)加载驱动
   Class.forName("com.mysql.cj.jdbc.Driver"); 
   
(2)获取连接对象
    String url="jdbc:mysql://ip:port/数据库名?serverTimezone=Asia/Shanghai";
    String user="root"
    String password="密码"
    Connection connection=DriverManager.getConnection(url,user,password);
(3)获取执行sql语句的对象
    Statement st=connection.createStatement();
 
 (4)执行sql语句 增删改
    st.executeUpdate(sql);

 1.1.增删改功能

package com.demo;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;


public class Test01 {
    public static void main(String[] args)throws Exception {
        //1.加载驱动---理解为引用翻译
        Class.forName("com.mysql.cj.jdbc.Driver");
        //2.获取连接对象
        //       String url, 数据库的路径  mysql5.7以后
        //       协议:数据的种类://ip:端口号/数据库名?serverTimezone=Asia/Shanghai
        //       jdbc:mysql://
        //        String user,账号
        //        String password 密码
        String url="jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user="root";
        String password="root";
        Connection connection= DriverManager.getConnection(url,user,password);

        //3.获取执行sql语句的对象。
        Statement statement=connection.createStatement();

        //4.执行sql语句。增删改
        String sql="delete from t_student where id=1";
        statement.executeUpdate(sql);
    }
}

总结:

1. 加载驱动 Class.forName("com.mysql.cj.jdbc.Driver");
2. 获取连接对象 Connection connection=DriverManager.getConnection(url,u,pass);
3. 获取执行sql语句的对象. Statement statement=connection.createStatement();
4. 执行sql语句: statement.executeUpdate(sql);

public class TestJdbc {

    //测试添加功能---往数据库中添加
    @Test
    public void testInsert() throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");

        String url="jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user="root";
        String password="root"; //这里的密码要和你自己的对照
        Connection connection = DriverManager.getConnection(url,user,password);

        Statement statement = connection.createStatement();

        String sql="insert into t_student values(null,'王五',16,'北京')";
        statement.executeUpdate(sql);

    }

    @Test
    public void testUpdate() throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");

        String url="jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user="root";
        String password="root"; //这里的密码要和你自己的对照
        Connection connection = DriverManager.getConnection(url,user,password);

        Statement statement = connection.createStatement();

        String sql="update t_student set name='闫克起',age=18,address='香港' where id=2";
        statement.executeUpdate(sql);

    }
}

出现的错误有哪些?

1.Class---->别写为class

2.驱动类找不到

原因: (1)类写错了 (2)没有把驱动jar包放入工程中并解压。

 3.没有写时区或者写错了。?serverTimezones=Asia/Shanghai

4.数据库的账号或密码错误。

 5.sql语句有错。 应该把sql放到数据库中执行一下

1.2.查询功能---查询数据库表中记录

@Test  //理解为main函数。可以独立运行。
    public void testQuery() throws Exception { //抛出异常只是为了操作方便。真正在开发时应该try--catch
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "root");

        Statement statement = conn.createStatement();

        String sql = "select id,name,age,address from t_student";
        //执行查询sql语句 并把数据库表中记录返回到ResultSet对象中进行保存。
        ResultSet rs = statement.executeQuery(sql);

        //取出ResultSet中表的记录。rs.next() 判断指针是否可以移动。如果可以移动则返回true,否则返回false
        while (rs.next()) {
            int id = rs.getInt("id"); //指针移动并获取指定列的值。
            String name = rs.getString("name");
            String address=rs.getString("address");
            int age=rs.getInt("age");
            System.out.println("id:"+id+";name:"+name+";age:"+age+";address:"+address);
        }

    }

分析查询:

 容易出现的错误:

 查询时没有查找names该列。

1.3.根据条件查询

//根据条件查询数据库
    @Test
    public void testQueryByCondition() throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "root");

        Statement statement = conn.createStatement();
        String sql="select * from t_student where id=3";
        ResultSet rs = statement.executeQuery(sql);
        while (rs.next()){
            int id = rs.getInt("id"); //指针移动并获取指定列的值。
            String name = rs.getString("name");
            String address=rs.getString("address");
            int age=rs.getInt("age");
            System.out.println("id:"+id+";name:"+name+";age:"+age+";address:"+address);
        }

    }

1.4.sql注入安全问题

sql注入: sql中存在特殊字符时 则sql会按照特殊字符来解析。

演示sql注入的安全问题:

//演示sql注入的安全问题
    public static void main(String [] args) throws Exception{
        Scanner scanner=new Scanner(System.in); //Scanner类有没有讲过。
        System.out.print("请输入账号:");
        String username = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine(); //你输入的账号和密码 nextLine() 可以输入空格 回车任认为结束  next()输入空格后认为输入结束。
        boolean b = sqlSafe(username, password);
    }

    //根据name查询数据 abc  演示的根据账号和密码查询数据库表记录 如果能查询表示登录成功 否则登录失败
    private static boolean sqlSafe(String name,String password) throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "root");

        Statement statement = conn.createStatement();
        //这里的admin 是不是一个死数据  123456 也是一个死数据
        String sql="select * from t_user where username='"+name+"' and password='"+password+"'";
        System.out.println(sql);
        ResultSet rs = statement.executeQuery(sql);

        while (rs.next()){
            System.out.println("登录成功");
            return true;
        }

        System.out.println("登录失败");
        return false;

    }

可以发现: 你的账号可以随便输入 你的密码也可以随便输入 但是 在输入密码时 or '4'='4 只要这个条件成立,那么你就能登录成功。 这个就是sql注入的安全问题。只要根据条件做sql。那么就会出现sql注入安全问题。

如何解决sql安全注入问题:

1. 前端做校验: --只防君子 防不了小人。
2. 后端也做校验:--难道以后每次写功能都进行校验吗? 代码变得复杂了。
3. 执行sql的类Statement出现了问题,后期PreparedStatement该类来解决sql注入安全问题。

Statement和PreparedStatement区别?
  Statement会出现sql注入安全问题。Preparedstatement不会出现sql注入安全问题。
  Preparedstatement是Statement的子类。就是因为早期使用Statement发现该类出现问题,后期维护人员创建Statement的子类来解决这个问题。注意:维护人员不会再原类上做维护

1.5.使用PreparedStatement来解决sql注入的问题

因为Statement类导致了sql注入的危险!

如何解决:-----演变出一个Statement的子类----->PreparedStatement[重写相应的方法]

 //演示sql注入的安全问题
    public static void main(String [] args) throws Exception{
        Scanner scanner=new Scanner(System.in); //Scanner类有没有讲过。
        System.out.print("请输入账号:");
        String username = scanner.nextLine();
        System.out.print("请输入密码:");
        String password = scanner.nextLine(); //你输入的账号和密码 nextLine() 可以输入空格 回车任认为结束  next()输入空格后认为输入结束。
        boolean b = sqlSafe02(username, password);
    }

    private static boolean sqlSafe02(String name,String password) throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection conn = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai", "root", "root");

        //使用PrepareStatement 这里的? 是占位符。
        String sql="select * from t_user where username=? and password=?";
        PreparedStatement ps = conn.prepareStatement(sql);//预编译sql
        //为占位符赋值。根据占位符的类型使用不同的方法来赋值
        ps.setString(1,name); //1表示第一个占位符  name:表示第一个占位符的值
        ps.setString(2,password);

        //执行sql语句
        ResultSet rs = ps.executeQuery();
        while (rs.next()){
            System.out.println("登录成功");
            return true;
        }
        System.out.println("登录失败");
        return false;
    }

PreparedStatement和Statement这两个类在代码上的区别?

 以后都使用PreparedStatement这个类。

 表示没有为占位符赋值。

1.6.使用PreparedStatement完成增删改查

@Test   //增
    public void insert() throws Exception{
    //抛出异常只是为了操作方便。真正在开发时应该try--catch
        //加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        //获取连接对象
        Connection connection = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/myaa?serverTimezone=Asia/Shanghai","root","123456");
        //获取执行sql语句
        String sql = "insert into t_user values(null,'王','123456')";
        PreparedStatement ps = connection.prepareStatement(sql);//预编译
        int i = ps.executeUpdate();//返回受影响的行数
        System.out.println(i);
    }

@Test    //删
    public void testDelete() throws Exception {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url="jdbc:mysql://localhost:3306/mydb?serverTimezone=Asia/Shanghai";
        String user="root";
        String pwd="root";
        Connection connection = DriverManager.getConnection(url,user,pwd);
        String sql="delete from t_student where id=?";
        PreparedStatement ps = connection.prepareStatement(sql);
        //为占位符赋值.
        int id=5; //未来应该是传递过来的。
        ps.setObject(1,id); //数据库中如果是其他类型 也可以使用''
                                      //使用setObject
        //执行sql语句 executeUpdate方法
        ps.executeUpdate();

    }


 @Test   //改
    public void update() throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/myaa?serverTimezone=Asia/Shanghai","root","123456");
        String sql = "update t_user set id=6,username='9568',password='147258' where id=?";
        PreparedStatement ps = connection.prepareStatement(sql);//预编译
        //为占位符赋值
        int id = 3;
        ps.setInt(1,id);
        //执行sql语句
        ps.executeUpdate();
    }


    @Test //查
    public void select() throws Exception{
        Class.forName("com.mysql.cj.jdbc.Driver");
        Connection connection = DriverManager.getConnection
                ("jdbc:mysql://localhost:3306/myaa?serverTimezone=Asia/Shanghai","root","123456");
        String sql = "select * from t_user where id=?";
        PreparedStatement ps = connection.prepareStatement(sql);//预编译
        //为占位符赋值
        int id = 2;
        ps.setInt(1,id);
        //执行sql语句 把数据库表中记录返回到ResultSet对象中
        ResultSet rs = ps.executeQuery();
        //取出ResultSet中的记录 rs.next()判断指针是否可以移动 如果可以返回true 否则返回false
        while(rs.next()){
            int id1 = rs.getInt("id");//移动指针并获取指定列的值
            String username = rs.getString("username");
            String password = rs.getString("password");
            System.out.println(id1+"\t"+username+"\t"+password);
        }
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值