获取数据库连接的方式 & Statement操作数据库的弊端

1.获取数据库连接的方式

TestConnection

package com.aff.connection;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;
import org.junit.Test;

public class TestConnection {
    // 方式一
    @Test
    public void testConnection() throws SQLException {
        // 获取Driver的实现类对象
        Driver driver = new com.mysql.jdbc.Driver();
        // jdbc:mysql 协议
        // localhost ip地址
        // 3306 默认mysql端口号
        // test 数据库名
        String url = "jdbc:mysql://localhost:3306/test";
        // 用户名和密码封装在Properties
        Properties info = new Properties();
        info.setProperty("user", "root");
        info.setProperty("password", "123456");
        Connection conn = driver.connect(url, info);
        System.out.println(conn);
    }

    // 方式二:对方式一的迭代,,在如下的程序中不出现第三方的api,使得程序具有更好的可移植性
    @Test
    public void testConnection2() throws Exception {
        // 获取Driver实现类对象:使用反射
        Class clazz = Class.forName("com.mysql.jdbc.Driver");
        Driver driver = (Driver) clazz.newInstance();

        // 连接需要的数据库
        String url = "jdbc:mysql://localhost:3306/test";

        // 提供连接需要的用户名和密码
        Properties info = new Properties();
        info.setProperty("user", "root");
        info.setProperty("password", "123456");

        // 获取连接
        Connection conn = driver.connect(url, info);
        System.out.println(conn);
    }

    // 方式三: 使用DriverManager管理
    @Test
    public void testConnection3() throws Exception {
        // 获取Driver实现类的对象
        Class clazz = Class.forName("com.mysql.jdbc.Driver");
        Driver driver = (Driver) clazz.newInstance();

        // 提供三个连接的基本信息
        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";

        // 获取DriverManager的驱动
        // 注册驱动
        DriverManager.registerDriver(driver);

        // 获取连接
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
    }

    // 方式四:在三的基础上优化
    @Test
    public void testConnection4() throws Exception {
        // 1.提供三个连接的基本信息
        String url = "jdbc:mysql://localhost:3306/test";
        String user = "root";
        String password = "123456";

        // 2. 加载驱动,mysql的Driver的实现类中,注册过了驱动
        Class.forName("com.mysql.jdbc.Driver");

        // 3.获取连接
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
    }

    
    
    
    // 方式五:最终版,将数据库连接需要的4个信息声明在配置文件中,通过读取配置文件的方式连接数据库
    /*
     * 好处:1.实现了数据与代码的分离,实现了解耦
     *      2.如果需要修改配置信息,可以避免后程序重新打包
     */
    @Test
    public void testConnection5() throws Exception {
        // 1.读取配置文件中的4个基本信息,通过类加载器
        InputStream is = TestConnection.class.getClassLoader().getResourceAsStream("jdbc.properties");
        Properties pro = new Properties();
        // 加载is这个文件
        pro.load(is);
        // 读取其中的配置信息
        String user = pro.getProperty("user");
        String url = pro.getProperty("url");
        String password = pro.getProperty("password");
        String driverClass = pro.getProperty("driverClass");

        // 2.加载驱动
        Class.forName(driverClass);

        // 3.获取连接
        Connection conn = DriverManager.getConnection(url, user, password);
        System.out.println(conn);
    }
}

 

2.Statement操作数据库的弊端:需要拼写sql语句,并且存在SQL注入的问题

示例:testLogin

package com.aff.connection;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;
import java.util.Scanner;
import org.junit.Test;

public class StatementTest {

    // 使用Statement的弊端:需要拼写sql语句,并且存在SQL注入的问题
    @Test
    public void testLogin() {
        Scanner scan = new Scanner(System.in);

        System.out.print("用户名:");
        String userName = scan.nextLine();
        System.out.print("密   码:");
        String password = scan.nextLine();

         // SELECT user,password FROM user_table WHERE USER = '1' or ' AND
        // PASSWORD = '
        // ='1' or '1' = '1';
        String sql = "SELECT user,password FROM user_table WHERE user = '" + userName + "' AND PASSWORD = '" + password
                + "'";
        User user = get(sql, User.class);
        if (user != null) {
            System.out.println("登陆成功!");
        } else {
            System.out.println("用户名或密码错误!");
        }
    }

    // 使用Statement实现对数据表的查询操作
    public <T> T get(String sql, Class<T> clazz) {
        T t = null;

        Connection conn = null;
        Statement st = null;
        ResultSet rs = null;
        try {
            // 1.加载配置文件
            InputStream is = StatementTest.class.getClassLoader().getResourceAsStream("jdbc.properties");
            Properties pros = new Properties();
            pros.load(is);

            // 2.读取配置信息
            String user = pros.getProperty("user");
            String password = pros.getProperty("password");
            String url = pros.getProperty("url");
            String driverClass = pros.getProperty("driverClass");

            // 3.加载驱动
            Class.forName(driverClass);

            // 4.获取连接
            conn = DriverManager.getConnection(url, user, password);
            st = conn.createStatement();
            rs = st.executeQuery(sql);

            // 获取结果集的元数据
            ResultSetMetaData rsmd = rs.getMetaData();

            // 获取结果集的列数
            int columnCount = rsmd.getColumnCount();

            if (rs.next()) {

                t = clazz.newInstance();

                for (int i = 0; i < columnCount; i++) {
                    // //1. 获取列的名称
                    // String columnName = rsmd.getColumnName(i+1);

                    // 1. 获取列的别名
                    String columnName = rsmd.getColumnLabel(i + 1);

                    // 2. 根据列名获取对应数据表中的数据
                    Object columnVal = rs.getObject(columnName);

                    // 3. 将数据表中得到的数据,封装进对象
                    Field field = clazz.getDeclaredField(columnName);
                    field.setAccessible(true);
                    field.set(t, columnVal);
                }
                return t;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 关闭资源
            if (rs != null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (st != null) {
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return null;
    }
}
User 
package com.aff.connection;

public class User {
    private String user;
    private String password;

    public User() {
    }
    public User(String user, String password) {
        super();
        this.user = user;
        this.password = password;
    }
    @Override
    public String toString() {
        return "User [user=" + user + ", password=" + password + "]";
    }
    public String getUser() {
        return user;
    }
    public void setUser(String user) {
        this.user = user;
    }
    public String getPassword() {
        return password;
    }
    public void setPassword(String password) {
        this.password = password;
    }
}
All that work will definitely pay off
原文地址:https://www.cnblogs.com/afangfang/p/12671906.html