jdbc基础1

2021-07-01 19:30发布

DAY09

Demo01_jdbc入门案例

package com.ujiuye.demo;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.SQLException;

import java.sql.Statement;

 

/**

 * 1、导入jar包

 * 2、加载驱动

 * 3、获取连接

 * 4、创建sql执行器和编写sql

 * 5、执行sql返回结果集

 * 6、释放资源

 *

 * 涉及的API(java.sql.* 或 javax.sql.*)

 *   1. DriverManager类  管理不同的驱动

 *   2. Connection 接口  应用和数据库的连接

 *   3. Statement 接口   用于执行sql语句

 *   4. ResultSet 接口   保存查询的结果

 */

public class Demo01 {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {

    // 加载驱动

        Class.forName("com.mysql.cj.jdbc.Driver");

    // 获取连接

        String url = "jdbc:mysql:///day07?serverTimezone=UTC";

        String name = "root";

        String password = "root";

        Connection conn = DriverManager.getConnection(url,name,password);

        // 测试连接

        System.out.println(conn);

    // 创建sql执行器和编写sql

        String sql = "insert into users values(20,'王小二',20000)";

        Statement stat = conn.createStatement();

        // 运行执行器执行sql语句

        // 执行sql返回结果集

        // executeUpdate()方法返回受影响的行数

        // executeQuery() 返回resultSet结果集

        int i = stat.executeUpdate(sql);

        if (i > 0) {

            System.out.println("添加成功");

        }else {

            System.out.println("添加失败");

        }

 

    // 释放资源

        conn.close();

        stat.close();

 

    }

}

 

Demo02_jdbc查询

package com.ujiuye.demo;

import sun.applet.Main;

import java.sql.*;

 

public class Demo02_jdbc查询 {

    public static void main(String[] args) throws Exception {

       // 加载驱动

        //如果是jdbc5.0版本   com.mysql.jdbc.Driver

        Class.forName("com.mysql.cj.jdbc.Driver");

       // 获取连接

        //如果地址是localhost 端口号是默认的3306 使用下面简写的方式(将localhost:3306省略掉)

       String url = "jdbc:mysql:///day07?serverTimezone=UTC";

       String user = "root";

       String password = "root";

       Connection conn = DriverManager.getConnection(url,user,password);

       // 测试连接 输出地址为连接成功

        System.out.println("conn=" + conn);

        // 创建sql查询语句

        String sql = "select * from users";

        // 创建sql执行器

        Statement stat = conn.createStatement();

        // 执行执行器,返回结果集

        ResultSet rs = stat.executeQuery(sql);

        // 查询结果集 使用next()

        /**

         *  rs.next() 判断是否有下一条数据    有true  没有 false

         *  rs.getXXX(index/"字段名")   rs.getString()   rs.getInt()

         *  通过index或者字段名获取对应的数据

         */

        while(rs.next()) {

            System.out.println(rs.getInt(1) +" "

            + rs.getString("uname")+ " " +

            rs.getDouble(3));

        }

        conn.close();

        stat.close();

        rs.close();

 

    }

}

 

jdbc连接方法和关闭资源方法的封装

MyUtils工具类

import java.io.FileInputStream;

import java.io.IOException;

import java.sql.*;

import java.util.Properties;

 

/**

 *

 * 做jdbc的操作,每次都要写加载驱动、获取连接、释放资源,代码重复

 * 封装jdbc工具类

 * 工具类

 * 属性和行为 都是静态    构造私有法

 * 要封装的方法

 * 1、获取连接   封装成一个静态方法   getConnection()

 * 2、释放资源   封装成一个静态方法   close()

 */

public class MyUtils {

    private static Connection conn;

    private MyUtils(){}

 

    //在静态代码块中加载好连接对象

    static {

        Properties p = new Properties();

        try {

            // 读取配置文件

            p.load(new FileInputStream(("config.properties")));

            // 通过key值获取value值

            String className =  p.getProperty("className");

            String url =  p.getProperty("url");

            String user =  p.getProperty("user");

            String password =  p.getProperty("password");

            // 加载驱动

            Class.forName(className);

            // 获取连接

            conn = DriverManager.getConnection(url,user,password);

        } catch (Exception e) {

            e.printStackTrace();

        }

    }   // 获取连接方法

 

    public static Connection getConnection(){

        return conn;

    }

    // 释放资源方法

    public static void close(Connection conn, Statement stat, ResultSet rs){

        try {

            if(conn != null) {

                conn.close();

            }

 

        } catch (SQLException throwables) {

            throwables.printStackTrace();

        }

 

        try {

            if(stat != null) {

                stat.close();

            }

 

        } catch (SQLException throwables) {

            throwables.printStackTrace();

        }

 

        try {

            if(rs != null) {

                rs.close();

            }

        } catch (SQLException throwables) {

            throwables.printStackTrace();

        }

    }

}

配置文件config.properties

className=com.mysql.cj.jdbc.Driver

user=root

password=root

url=jdbc:mysql:///day07?serverTimezone=UTC

 

测试工具类

package com.ujiuye.demo;

import com.ujiuye.utils.MyUtils;

import java.sql.Connection;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

 

public class Demo03_测试jdbc工具类 {

    public static void main(String[] args) throws SQLException {

        Connection conn = MyUtils.getConnection();

        System.out.println("conn" + conn);

 

        String sql = "select * from users";

        Statement stat = conn.createStatement();

        ResultSet rs = stat.executeQuery(sql);

        while(rs.next()) {

            System.out.println(rs.getString("uname"));

        }

        MyUtils.close(conn,stat,null);

    }

}

 

sql注入原理

package com.ujiuye.demo;

import com.ujiuye.utils.MyUtils;

import java.sql.*;

import java.util.Scanner;

 

/**

 * CREATE TABLE user1(

 *   uid INT PRIMARY KEY,

 *   username VARCHAR(20),

 *   `password` VARCHAR(20)

 * )

 * 模拟登陆

 */

public class Demo04_sql注入 {

    public static void main(String[] args) throws SQLException {

        Scanner scanner = new Scanner(System.in);

        System.out.println("欢迎登录:");

        System.out.println("请输入账号:");

        String username = scanner.nextLine();

        System.out.println("请输入密码:");

        String password = scanner.nextLine();

 

        // 获取连接

        Connection conn  = MyUtils.getConnection();

 

        String sql = "select * from user1 where uname = '"+ username +"' and password = '"+ password +"'";

        System.out.println(sql);

        // 创建sql执行器

        Statement stat = conn.createStatement();

        // 执行sql

        ResultSet rs = stat.executeQuery(sql);

 

        // 密码如果为888' or '1' = '1

        //1=1是恒成立的,无论账号和密码输入的是多少 都能查询到数据

        System.out.println(rs.next() ? "登录成功" : "登录失败");

        MyUtils.close(conn,stat,rs);

    }

}

 

防止sql注入

package com.ujiuye.demo;

import com.ujiuye.utils.MyUtils;

import java.sql.Connection;

import java.sql.PreparedStatement;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.util.Scanner;

 

/**

 *   原因: sql可以识别关键字

 *   statement 这个sql执行器不安全  可以识别sql关键字

 *   preparedstatement sql执行器

 *   是statement的一个子接口,对参数使用占位符?进行占位,提前对sql进行预编译,

 *   在对占位符进行赋值,不能识别关键字的  极大程度上防止sql注入

 */

public class Demo05_防止sql注入 {

    public static void main(String[] args) throws SQLException {

        Scanner scanner = new Scanner(System.in);

        System.out.println("欢迎登陆:");

        System.out.println("请输入账号:");

        String username = scanner.nextLine();

        System.out.println("请输入密码:");

        String password = scanner.nextLine();

 

        Connection conn = MyUtils.getConnection();

        String sql = "select * from user1 where uname = ? and password = ?";

        // 创建sql执行器

        PreparedStatement ps = conn.prepareStatement(sql);

        // 对占位符进行赋值

        ps.setString(1,username);

        ps.setString(2,password);

 

        ResultSet rs = ps.executeQuery();

        System.out.println(rs.next()?"成功":"失败");

        MyUtils.close(conn,ps,rs);

    }

}

 

Junit单元测试

package com.ujiuye.demo;

 

import org.junit.After;

import org.junit.Before;

import org.junit.Test;

/*

    一个类中只有一个入口main方法,只能创建一个main方法,

    有了单元测试之后,一个类中可以创建多个测试方法,测试方法可以单独运行,

    简单理解为:在一个类中可以创建多个main方法

    @Before 在测试方法运行之前运行

    @Test 测试方法

    @After 在测试方法运行之后允许

 */

public class Demo06_单元测试 {

    @Test

    public void test01() {

        System.out.println("我是test01方法");

    }

    @Test

    public void test02() {

        System.out.println("我是test02方法");

    }

    @Before

    public void be() {

        System.out.println("我是before");

    }

    @After

    public void after() {

        System.out.println("我是after方法");

    }

 

}