ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

Java之JDBC详谈(数据库)

2022-04-10 18:31:07  阅读:239  来源: 互联网

标签:username JDBC Java String resultSet sql 详谈 password conn


一、了解JDBC

  1. JDBC是什么?
    Java DataBase Connectivity(Java语言连接数据库)
  2. JDBC的本质
    JDBC是SUN公司制定的一套接口(interface)
    java.sql.*(这个软件包下有很多接口)
    开始面向接口编程,面向抽象编程,不要面向具体编程。
  3. JDBC编程六步(需要背会)
  • 第一步:注册驱动(告诉Java程序,即将要连接的是哪个数据库)
  • 第二步:获取连接
  • 第三步:获取数据库操作对象(专门执行sql语句的对象)
  • 第四步:执行SQL语句(DQL DML)
  • 第五步:处理查询结果集
  • 第六步:释放资源

二、连接数据库、实现用户登录

2.1前期准备

  • 还需要导入一个数据库驱动包,mysql-connector-java-5.1.47.jar
  • url:包括协议、IP、PORT(端口)、资源名
  • mysql的url:jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=false
    • jdbc:mysql:// 协议
    • localhost IP地址
    • 3306 mysql数据库端口号
    • smbms 具体的数据库实例名
public class JdbcTest {
    public static void main(String[] args) throws SQLException {
        try {
            //1、注册驱动
            DriverManager.registerDriver(new com.mysql.jdbc.Driver());//这是一种加载驱动方式
            //这是另外一种加载驱动方式,我们从文件中读信息
            FileInputStream file = new FileInputStream("db.properties");
            //创建Map集合对象
            Properties properties = new Properties();
            //将文件信息以键值对的形式加载出来
            properties.load(file);


            //还可以使用一个比较简便的
            ResourceBundle bundle = ResourceBundle.getBundle("文件名");
            String driver = bundle.getString("key");


            //获取文件信息
            String driver = properties.getProperty("driver");
            String url = properties.getProperty("url");
            String username = properties.getProperty("username");
            String password = properties.getProperty("password");
            //通过反射加载驱动
            Class.forName(driver);
            System.out.println(driver);
            //2、获取连接
            Connection connection = DriverManager.getConnection(url, username, password);
            System.out.println(connection);
            //3、获取执行sql的对象
            Statement statement = connection.createStatement();
            String sql = "select * from smbms_role";
            //4、执行sql语句5、返回结果集
            ResultSet resultSet = statement.executeQuery(sql);
            resultSet.next();
            System.out.println(resultSet.getInt("id"));
            //6、释放资源
            resultSet.close();
            statement.close();
            connection.close();
          //关闭资源时,必须从小到大按顺序关闭,并且每个都要try--catch
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
//多写几遍,多查看API文档,了解每个类具体干什么的,你就懂了,也就学会了。
  • 增删改用int executeUpdate(insert/delete/update)
  • 查询用ResulSet executeQurey(select)
  • 查询时用boolean result.next(),若当前有数据则返回true,若没有则false
  • JDBC的下标时从1开始,而不是0

2.2用户登录代码实现

public class LoginTest {
    public static void main(String[] args) {
        //1.获取用户登录信息
        Map<String,String> userInfo = userInfo();
        //2.验证用户密码是否正确
        boolean loginResult = userLogin(userInfo);
        System.out.println(loginResult?"登录成功" : "登录失败");
    }


    //获取用户登录信息
    public static Map<String,String> userInfo() {
        Scanner scan = new Scanner(System.in);
        System.out.println("输入用户名:");
        String username = scan.next();
        System.out.println("输入密码:");
        String password = scan.next();
        HashMap<String, String> user = new HashMap<>();
        user.put("username",username);
        user.put("password",password);
        return user;
    }
    //jdbc
    public static boolean userLogin(Map<String,String> userInfo) {
        boolean falg = false;
        Connection conn = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            String username = userInfo.get("username");
            String password = userInfo.get("password");
            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=false", "root", "200506lx");
            //3.获取操作对象
            statement = conn.createStatement();
            //4.执行sql
            //5.返回结果
            String sql = "select * from smbms_user where userCode = '"+username+"'and userPassword = '"+password+"'";
            resultSet = statement.executeQuery(sql);
            if(resultSet.next()) {
                falg = true;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            // 6.释放资源
            if(resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(statement != null) {
                try {
                    statement.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
        return falg;
    }
}

三、sql注入问题

  • asd'or'1'='1
  • 解决SQL注入问题
    • 只要用户提供的信息不参与SQL语句的编译过程,问题就解决了
    • 即使用户提供的信息中含有SQL语句的关键字,但是没有参与编译,不起作用。
    • 要想用户信息不参与SQL语句的编译,那么必须使用java.sql.PreparedStatement
    • PreparedStatement这个接口继承了java.sql.Statement
    • 属于预编译的数据库操作对象,预先对SQL语句的框架进行编译,然后再给SQL语句传值
public static boolean userLogin(Map<String,String> userInfo) {
        boolean falg = false;
        Connection conn = null;
        PreparedStatement ps = null;//将Statement换成PreparedStatement
        ResultSet resultSet = null;
        try {
            String username = userInfo.get("username");
            String password = userInfo.get("password");
            //1.加载驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/smbms?useUnicode=true&characterEncoding=utf8&useSSL=false", "root", "200506lx");
            //3.获取操作对象
            //一个?就是一个占位符,接受一个值
            String sql = "select * from smbms_user where userCode = ? and userPassword = ?";
            ps = conn.prepareStatement(sql);
            ps.setString(1,username); //1代表第一个?,给他设置值username
            ps.setString(2,password); //JDBC下标从1开始
            //4.执行sql
            //5.返回结果
            resultSet = ps.executeQuery();
            if(resultSet.next()) {
                falg = true;
            }
        }
}
  • 这样我们就解决了SQL注入问题

四、对比Statement和PreparedStatement

  • Statement存在sql注入问题,PreparedStatement解决了sql注入问题
  • Statement是编译一次执行一次,PreparedStatement是编译一次,可执行n次,效率较高。
  • PreparedStatement会在编译阶段做类型检查
  • 但是也有Statement用的地方。

五、JDBC事务演示

  • JDBC中只要执行任意一条DML语句,就提交一次
  • 记住三行代码搞定
  • conn.setAutoCommit(false)//将自动提交机制修改为手动提交机制,开启事务
  • conn.commit();//提交事务
  • conn.rollback();//事务回滚

六、JDBC工具类的封装

public class DButil {
    /*
    工具类中的构造方法都是私有的
    因为工具类中的代码都是静态的,不需要new对象,直接采用类名调用
     */
    private DButil(){
    }
    private static final String driver;
    private static final String url;
    private static final String username;
    private static final String password;
    //静态代码块随着类的加载而加载,并且只加载一次
    static {
        ResourceBundle rb = ResourceBundle.getBundle("db.properties");
        driver = rb.getString("driver");
        url = rb.getString("url");
        username = rb.getString("username");
        password = rb.getString("password");
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
    }

    //获取数据库的连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }
    //数据库资源关闭
    public static  void closeResource(Connection conn, PreparedStatement ps, ResultSet rs) {
        if(conn != null) {
            try {
                conn.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(ps != null) {
            try {
                ps.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if(rs != null) {
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

七、结尾

  • 对于数据库的JDBC内容就总结这么多,若想深入学习等待后续更新,基础部分掌握这些足矣。如果有不足之处,希望大家多多包涵,多多支持。如果有不懂的地方可以直接私信问我,欢迎来访!
  • 我将会继续更新关于Java的学习知识,感兴趣的小伙伴可以关注一下。
  • 文章写得比较走心,用了很长时间,绝对是copy过来的!
  • 尊重每一位学习知识的人,同时也尊重每一位分享知识的人。
  • 标签:username,JDBC,Java,String,resultSet,sql,详谈,password,conn
    来源: https://www.cnblogs.com/lx-meteor/p/16120233.html

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

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

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

ICode9版权所有