• MySQLJDBC


    MySQL 之 JDBC

    一、JDBC是什么?

    Java DataBase Connectivity(Java语言连接数据库)

    二、JDBC的本质是什么?

    JDBC是SUN公司制定的一套接口(interface)。

    接口都有调用者和实现者。

    面向接口调用、面向接口写实现类,这都属于面向接口编程。

    三、为什么要面向接口编程?

    解耦合:降低程序的耦合度,提高程序的扩展力。

    多态机制就是非常典型的:面向抽象编程。(不要面向具体编程)

    (这里需要画图带大家理解。。。)

    四、为什么SUN制定一套JDBC接口呢?

    因为每一个数据库产品都有自己独特的实现原理

    五、JDBC编程六步(需要背会)

    1.注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)

    2.获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。

    3.获取数据库操作对象(专门执行sql语句的对象)

    4.执行SQL语句(DQL,DML…)

    5.处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)

    6.释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)

    六、IDEA编写JDBC连接MySQL

    6.1 mysql-connector-java的不同版本对比

    MySQL Connector / J 5.1
    5.1版本支持java5及其以上的版本,支持5.6、5.7、8.0版本的mysql数据库,支持3.0、4.0、4.1、4.2版本的jdbc。在5.1中,Driver的实现类的全路径名是com.mysql.jdbc.Driver。

    MySQL Connector / J 8.0
    8.0版本支持java8及其以上的版本,支持5.6、5.7、8.0版本的mysql数据库,支持4.2版本的jdbc。在8.0中,Driver的实现类的全路径名是com.mysql.cj.jdbc.Driver。

    下图是官网上mysql-connector-java的版本对应的mysql版本和jdk的版本。

    6.2 下载驱动jar包 mysql-connector-java

    要使用mysql连接器,就要先下载它。如果是一般的项目,那我们需要下载jar包,然后放到项目的lib目录下。如果使用maven构建的项目,我们可以通过maven直接安装。不同的下载方式有不同的操作,常见的有直接官网下载和maven下载(下周讲解maven)。
    下载jar包最直接的方式是从官网下载,官网地址是:https://dev.mysql.com/downloads/connector/j/。直接点链接进入mysql官网,选择所需的版本和操作系统(要下载jar包就要选:Platform Independent),然后点击download按钮就可以下载了。为java提供的连接器是Connector / J,也就是mysql-connector-java,它分为5.1版本和8.0版本。Connector / J实现了JDBC,为使用java开发的程序提供连接,方便java程序操作数据库。

    2、从maven安装
    使用maven安装mysql-connector-java就简单很多,直接打开maven的中央仓库地址,输入mysql-connector-java就可以找到不同版本的依赖。地址:https://mvnrepository.com/artifact/mysql/mysql-connector-java

    6.3 IDEA导入jar包

    先检查jar包位置:在目录里新建一个文件夹 libs,把jar包复制进去

    然后右键选择新建文件夹libs转成library

    然后就可以写代码啦!

    根据六步编写代码:先不写处理代码

    6.4 JDBC连接mysql 程序编写

    6.5.1 第一种注册驱动方式
    package com.wyh.jdbc;
    
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    
    /*
            jdbc连接mysql,程序编写6个步骤:
            1.注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
            2.获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
            3.获取数据库操作对象(专门执行sql语句的对象)
            4.执行SQL语句(DQL,DML…)
            5.处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
            6.释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)
     */
    public class JDBCTest1 {
        public static void main(String[] args) {
            Connection conn = null;
            Statement stmt = null;
    
            try {
                //1、注册驱动方式1:使用jdk自带的一个类DriverManager中静态方法
                //static void registerDriver(Driver driver)
                //注册与给定的驱动程序 DriverManager 。
                DriverManager.registerDriver(new com.mysql.jdbc.Driver());
                //2、建立JVM与mysql数据库进程之间的连接
                //static Connection getConnection(String url, String user, String password)
                //尝试建立与给定数据库URL的连接。
                /*
                     url:统一资源定位符(网络中某个资源的完整路径)
                     http://  or  https://  是通信协议,通信协议是通信之前就定义好的数据传输格式,数据包具体怎么传数据,都是体现定义好的
                     IP地址:192.168.40.110 就是mysql服务器IP地址
                     端口:8080
                     index.html/index.jsp  服务器上资源的名字
                 */
                //MySQL 5.5.45+, 5.6.26+ and 5.7.6+这些版本的数据库,不建议不使用服务器身份与数据建立连接,必须默认建立SSL连接,
                String url = "jdbc:mysql://192.168.40.110:3306/bigdata17?useUnicode=true&characterEncoding=utf8&useSSL=false";
                String user = "root";
                String password = "123456";
                conn = DriverManager.getConnection(url, user, password);
                System.out.println("数据库连接的对象是:" + conn);
                //3、获取数据库操作对象(专门执行sql语句的对象)
                //Statement createStatement()
                //创建一个 Statement对象,用于将SQL语句发送到数据库。  (statement是专门执行sql语句的)
                stmt = conn.createStatement();
                //4、执行sql
                //int executeUpdate(String sql)
                //执行给定的SQL语句,这可能是 INSERT , UPDATE ,或 DELETE语句,或者不返回任何内容,如SQL DDL语句的SQL语句。
                String sql = "insert into dept(deptno,dname,loc) values(50,'教学部','合肥')";
                int count = stmt.executeUpdate(sql); // 返回值是'影响数据库中的记录条数'  Affected rows: 1
                if(count==1){
                    System.out.println("数据保存成功!!");
                }else {
                    System.out.println("数据保存失败!!");
                }
    
    
            } catch (SQLException e) {
                e.printStackTrace();
            }finally {
                //6、释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)
                //为了保证最后资源一定会释放掉,所以我们在finally中进行释放资源
                //要遵循从小到大依次关闭
                if(stmt!=null){
                    try {
                        stmt.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
    
                if(conn!=null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
    
    
        }
    }
    
    
    6.5.2 第二种注册驱动方式
    package com.wyh.jdbc;
    
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLExc
        eption;
    import java.sql.Statement;
    
    /*
            jdbc连接mysql,程序编写6个步骤:
            1.注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
            2.获取连接(表示JVM的进程和数据库进程之间的通道打开了,这属于进程之间的通信,使用完后记得关闭通道)。
            3.获取数据库操作对象(专门执行sql语句的对象)
            4.执行SQL语句(DQL,DML…)
            5.处理查询结果集 (只有当第四步执行的是select语句的时候,才有本步)
            6.释放资源(使用完资源后一定要关闭资源,Java和数据库之间属于进程间的通信,开启之后一定要记得关闭)
     */
    public class JDBCTest2 {
        public static void main(String[] args) {
            Connection conn = null;
            Statement stmt = null;
            try {
                //注册驱动的另一种方式(最常用的方式)
                //1、注册驱动(告诉Java程序,即将连接的是哪个品牌的数据库)
    //            DriverManager.registerDriver(new com.mysql.jdbc.Driver());
                //注册驱动的第二种写法:
                //但是今后我们实际开发的时候,驱动包可能不太一样,今天我们连接mysql可能后天我们连接redis,所以这里的类不是一定的
                //将来我们开发好一个程序后,这里的参数是不允许随意改动的,更希望传一个字符串,方便我们后期做配置文件传参
                //通过反射可以获取一个字节码文件对象中的功能
                Class.forName("com.mysql.jdbc.Driver");
                //2、获取连接
                String url = "jdbc:mysql://192.168.40.110/bigdata17?useUnicode=true&characterEncoding=utf8&useSSL=false";
                String user = "root";
                String password = "123456";
                conn = DriverManager.getConnection(url, user, password);
                System.out.println("数据库的连接对象是:" + conn);
    
                //3、获取专门操作数据库的对象
                stmt = conn.createStatement();
    
                //4、执行sql
                //executeUpdate(String sql)方法是专门执行DML语句的(insert,delete,update)
                String sql = "insert into dept(deptno,dname,loc) values(60,'人事部','数加')";
                int count = stmt.executeUpdate(sql);
    //            if(count==1){
    //                System.out.println("数据保存成功!!");
    //            }else {
    //                System.out.println("数据保存失败!!");
    //            }
                System.out.println(count == 1 ? "数据保存成功!!" : "数据保存失败!!");
    
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (stmt != null) {
                    try {
                        stmt.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
    
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
    
    
        }
    }
    
    
    6.5.3 将连接数据库的所有信息配置到配置文件中
    package com.wyh.jdbc;
    
    import java.io.FileNotFoundException;
    import java.io.FileReader;
    import java.io.IOException;
    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;
    import java.util.Properties;
    
    /*
            在实际开发中不建议把连接数据库的参数信息直接写死在数据库中
            所以我们就应该利用配置文件,然后使用程序读取该配置文件,得到对应的参数
     */
    public class JDBCTest3 {
        public static void main(String[] args) {
            Properties prop = null;
            FileReader fr = null;
            Connection conn = null;
            Statement stmt = null;
    
            try {
                //利用java中的Properties类读取配置文件
                prop = new Properties();
                fr = new FileReader("E:\\projects\\IdeaProjects\\jdbc-mysql\\datas\\jdbc.properties");
                prop.load(fr);
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String username = prop.getProperty("username");
                String password = prop.getProperty("password");
    
                //1、加载驱动连接
                Class.forName(driver);
                //2、获取与数据库服务的连接
                conn = DriverManager.getConnection(url, username, password);
                //3、获取执行sql的对象
                stmt = conn.createStatement();
                //4、执行sql
                //删除数据
    //            String sql = "delete from dept where deptno=60";
    //            int count = stmt.executeUpdate(sql);
    //
    //            if(count==1){
    //                System.out.println("数据成功删除一行!");
    //            }else {
    //                System.out.println("删除失败!");
    //            }
    
                //插入数据
    //            String sqlInsert = "insert into dept(deptno,dname,loc) values(50,'教学部','合肥')";
    //            String sqlInsert2 = "insert into dept(deptno,dname,loc) values(60,'人事部','数加')";
    //            int count1 = stmt.executeUpdate(sqlInsert);
    //            int count2 = stmt.executeUpdate(sqlInsert2);
    //            if(count1!=1 || count2!=1){
    //                System.out.println("插入失败!!");
    //            }else {
    //                System.out.println("插入成功!!");
    //            }
    
                //更改数据
                String updateSql = "update dept set deptno=70 where dname='教学部'";
                int count3 = stmt.executeUpdate(updateSql);
                if(count3==1){
                    System.out.println("数据更新成功!!");
                }else {
                    System.out.println("更新失败!");
                }
    
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (fr != null) {
                    try {
                        fr.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
    
                if(stmt!=null){
                    try {
                        stmt.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
    
                if(conn!=null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
    
    
        }
    }
    
    
    6.5.4 处理查询结果集
    package com.wyh.jdbc;
    
    import java.io.FileReader;
    import java.io.IOException;
    import java.sql.*;
    import java.util.Properties;
    
    /*
            查询数据并做处理
     */
    public class JDBCTest4 {
        public static void main(String[] args) {
            Properties prop = null;
            Connection conn = null;
            Statement stmt = null;
            try {
                prop = new Properties();
                prop.load(new FileReader("E:\\projects\\IdeaProjects\\jdbc-mysql\\datas\\jdbc.properties"));
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String username = prop.getProperty("username");
                String password = prop.getProperty("password");
    
                //1、加载驱动包
                Class.forName(driver);
                //2、获取与数据库的连接
                conn = DriverManager.getConnection(url, username, password);
                //3、获取执行sql的对象
                stmt = conn.createStatement();
                //4、执行sql语句
                //注意:如果要查询一张表中的所有字段的话,不能使用*,建议把每一个字段叫什么详细写出
                String sql = "select ename as a ,job,mgr,hiredate,sal,comm,deptno,empno from emp";
                //ResultSet executeQuery(String sql)  是专门执行DQL语句的方法
                //执行给定的SQL语句,该语句返回单个 ResultSet对象。
                ResultSet resultSet = stmt.executeQuery(sql);
                //5、处理查询结果
                //boolean next()
                //将光标从当前位置向前移动一行。
                boolean b = resultSet.next();
    //            System.out.println(b); //如果这里的返回值是true,说明我们已经查到数据了,至少是有一行数据的
    
                //获取一行中对应的数据
                //String getString(int columnIndex)
                //这个检索的当前行中指定列的值 ResultSet对象为 String的Java编程语言。
    //            if(b){
    //                //光标指向的是行数据
    //                //取数据的时候,是一列一列取的
    //                //getString()方法的特点是,不管数据库中字段数据是什么类型的,取出来都是String类型
    //                //这里方法中的参数是int类型数据,1,2,3等代表的是第几列
    //                String empno = resultSet.getString(1); //JDBC中所有的下标都是从1开始
    //                String ename = resultSet.getString(2);
    //                String job = resultSet.getString(3);
    //                String mgr = resultSet.getString(4);
    //                String hiredate = resultSet.getString(5);
    //                String sal = resultSet.getString(6);
    //                String comm = resultSet.getString(7);
    //                String deptno = resultSet.getString(8);
    //
    //                System.out.println(empno+","+ename+","+job+","+mgr+","+hiredate+","+sal+","+comm+","+deptno);
    //            }
    
                //由于不知道有多少行,所以使用while循环改进
                while (resultSet.next()){
                    //光标指向的是行数据
                    //取数据的时候,是一列一列取的
                    //getString()方法的特点是,不管数据库中字段数据是什么类型的,取出来都是String类型
                    //这里方法中的参数是int类型数据,1,2,3等代表的是第几列
    //                String empno = resultSet.getString(1); //JDBC中所有的下标都是从1开始
    //                String ename = resultSet.getString(2);
    //                String job = resultSet.getString(3);
    //                String mgr = resultSet.getString(4);
    //                String hiredate = resultSet.getString(5);
    //                String sal = resultSet.getString(6);
    //                String comm = resultSet.getString(7);
    //                String deptno = resultSet.getString(8);
    
                    //String getString(String columnLabel)
                    //这个检索的当前行中指定列的值 ResultSet对象为 String的Java编程语言。
                    //直接根据列名获取对应字段的值
                    //不仅获取是字符串的,还可以根据实际情况来获取对应数据类型的列,比如getInt()
    //                String empno = resultSet.getString("empno");
                    int empno = resultSet.getInt("empno");
    //                String ename = resultSet.getString("ename");
                    String ename = resultSet.getString("a");  //加入sql中有别名,查询的是以别名进行查找
                    String job = resultSet.getString("job");
                    String mgr = resultSet.getString("mgr");
                    String hiredate = resultSet.getString("hiredate");
                    String sal = resultSet.getString("sal");
                    String comm = resultSet.getString("comm");
                    String deptno = resultSet.getString("deptno");
    
    
                    System.out.println(empno+","+ename+","+job+","+mgr+","+hiredate+","+sal+","+comm+","+deptno);
                }
    
    
    
    
    
            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                if (stmt != null) {
                    try {
                        stmt.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
    
                if (conn != null) {
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
    }
    
    
    6.5.5 编写一个场景引入有安全隐患的程序(解决sql注入问题
    package com.wyh.jdbc;
    
    /*
            需求:使用java程序模拟用户的注册登录功能
    
            需求分析:
                1、程序运行的时候,需要提供一个输入用户名和密码的入口,可以让用户输入
                2、输入完毕后,如果用户名和密码已经存在了数据库中,并且正确,即表示登录成功
                3、如果用户名和密码不对,提示用户是否需要进行注册
    
            当我们程序写完后,发现了一个十分严重的bug
            用户:wt
            密码:wqe' or '1'='1
            登录成功!获取表中的所有数据
            这种现象叫做SQL注入(安全隐患)(早期黑客经常使用)
            导致这个问题的原因是什么?
            用户输入的信息中存在着sql语法的关键字,并且这些关键字参与了sql语句的编译过程
            导致原本的sql语句的意思发生的变化,进而达到sql注入。
     */
    
    import java.io.FileReader;
    import java.io.IOException;
    import java.sql.*;
    import java.util.Properties;
    import java.util.Scanner;
    
    public class JDBCTest5 {
        //初始化一些变量
        private static Properties prop = null;
        private static Connection conn = null;
        private static Statement stmt = null;
        private static ResultSet resultSet = null;
        private static String username = null;
        private static String password = null;
        private static boolean flag = false;
        private static Scanner sc = null;
    
        public static void main(String[] args) {
            body();
        }
    
    
        //编写登录方法
        public static boolean login() {
            //创建键盘录入对象
            sc = new Scanner(System.in);
            System.out.println("===================欢迎进入xiaohu婚介所网站!!===================");
            System.out.println("请输入您的用户名:");
            username = sc.nextLine();
            System.out.println("请输入密码:");
            password = sc.nextLine();
            //利用配置文件获取连接数据库的参数
            try {
                //3、获取执行sql语句的对象
                stmt = conn.createStatement();
                //4、执行sql语句
                String loginSql = "select username,password from user where username='" + username + "' and password='" + password + "'";
                System.out.println(loginSql); //select username,password from user where username='wt' and password='wqe' or '1'='1'
                resultSet = stmt.executeQuery(loginSql);
                //5、判断结果数据
                if (resultSet.next()) {
    //                System.out.println(username+"用户登录成功,正在跳转至主页面....");
                    flag = true;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return flag;
        }
    
        public static int register() {
            boolean flag2 = true;
            int count = 0;
            while (flag2) {
                System.out.println("欢迎注册用户!!");
                System.out.println("请输入您的用户名:");
                String username2 = sc.next();
                System.out.println("请输入您的密码:");
                String password2 = sc.next();
                System.out.println("请再次确认密码:");
                String password2Again = sc.next();
                if (!password2.equals(password2Again)) {
                    System.out.println("密码不一致,请重新填写注册信息!!");
                } else {
                    flag2 = false;
                    //开始将注册的信息写入到数据库中
                    //利用配置文件获取连接数据库的参数
                    try {
                        //3、获取执行sql语句的对象
                        stmt = conn.createStatement();
                        //4、执行sql语句
                        String registerSql = "insert into user(username,password) values('" + username2 + "','" + password2 + "')";
                        count = stmt.executeUpdate(registerSql);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return count;
        }
    
        public static void quit() {
            //释放资源
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
    
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
    
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
        public static void index(){
    
            try {
                prop = new Properties();
                prop.load(new FileReader("E:\\projects\\IdeaProjects\\jdbc-mysql\\datas\\jdbc.properties"));
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String user = prop.getProperty("username");
                String pwd = prop.getProperty("password");
    
                //1、加载驱动
                Class.forName(driver);
                //2、获取与数据库的连接
                conn = DriverManager.getConnection(url, user, pwd);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        public static void body() {
            //方法封装欢迎界面
            index();
            boolean b = login();
            if (b) {
                System.out.println(username + "用户登录成功,正在跳转至主页面....");
            } else {
                System.out.println(username + " 该用户不存在!!");
                System.out.println("请先前往注册界面进行注册!!(Y/N)");
                String b2 = sc.next();
                if ("Y".equalsIgnoreCase(b2)) {
                    int count = register();
                    if (count == 1) {
                        System.out.println("用户注册成功!!!,正在切换登录页面....");
                        boolean b3 = login();
                        if(b3){
                            System.out.println(username + "用户登录成功,正在跳转至主页面....");
                        }else {
                            System.out.println("用户名和密码错误,登录失败!!");
                        }
                    } else {
                        System.out.println("用户注册失败!!");
                    }
                } else {
                    System.out.println("欢迎下次继续使用!!");
                }
            }
            quit();
    
        }
    
    }
    
    
    6.5.6 解决sql注入问题
    package com.wyh.jdbc;
    
    /*
            解决sql注入的问题
            只要用户提供的信息不参与sql语句编译过程就好了,这样的话问题就得到解决
            java中提供了另外一个接口给我们使用java.sql.PreparedStatement
            这个接口继承自原本Statement接口
            表示预编译的SQL语句的对象。
            SQL语句已预编译并存储在PreparedStatement对象中。 然后可以使用该对象多次有效地执行此语句。
            综上所述:大部分情况下,使用PreparedStatement,有些情况下使用statement,如果将来需要手动输入升序或者降序的时候
     */
    
    import java.io.FileReader;
    import java.sql.*;
    import java.util.Properties;
    import java.util.Scanner;
    
    public class JDBCTest6 {
        //初始化一些变量
        private static Properties prop = null;
        private static Connection conn = null;
        private static Statement stmt = null;
        private static ResultSet resultSet = null;
        private static String username = null;
        private static String password = null;
        private static boolean flag = false;
        private static Scanner sc = null;
    
        public static void main(String[] args) {
            body();
        }
    
    
        //编写登录方法
        public static boolean login() {
            //创建键盘录入对象
            sc = new Scanner(System.in);
            System.out.println("===================欢迎进入xiaohu婚介所网站!!===================");
            System.out.println("请输入您的用户名:");
            username = sc.nextLine();
            System.out.println("请输入密码:");
            password = sc.nextLine();
            //利用配置文件获取连接数据库的参数
            try {
                //3、获取执行sql语句的对象
    //            stmt = conn.createStatement();
    
                //4、执行sql语句
                //这里问号相当于一个占位符,将来需要传值的
                String loginSql = "select username,password from user where username=? and password=?";
                PreparedStatement prepStmt = conn.prepareStatement(loginSql);
                // 给占位符 ? 进行传值,(第一个问号下标是1,第二个问号下标是2,依次类推)
                prepStmt.setString(1,username);
                prepStmt.setString(2,password);
    
                resultSet = prepStmt.executeQuery();
                //5、判断结果数据
                if (resultSet.next()) {
    //                System.out.println(username+"用户登录成功,正在跳转至主页面....");
                    flag = true;
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
            return flag;
        }
    
        public static int register() {
            boolean flag2 = true;
            int count = 0;
            while (flag2) {
                System.out.println("欢迎注册用户!!");
                System.out.println("请输入您的用户名:");
                String username2 = sc.next();
                System.out.println("请输入您的密码:");
                String password2 = sc.next();
                System.out.println("请再次确认密码:");
                String password2Again = sc.next();
                if (!password2.equals(password2Again)) {
                    System.out.println("密码不一致,请重新填写注册信息!!");
                } else {
                    flag2 = false;
                    //开始将注册的信息写入到数据库中
                    //利用配置文件获取连接数据库的参数
                    try {
                        //3、获取执行sql语句的对象
                        stmt = conn.createStatement();
                        //4、执行sql语句
                        String registerSql = "insert into user(username,password) values('" + username2 + "','" + password2 + "')";
                        count = stmt.executeUpdate(registerSql);
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            }
            return count;
        }
    
        public static void quit() {
            //释放资源
            if (resultSet != null) {
                try {
                    resultSet.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
    
            if (stmt != null) {
                try {
                    stmt.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
    
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    
    
        public static void index(){
    
            try {
                prop = new Properties();
                prop.load(new FileReader("E:\\projects\\IdeaProjects\\jdbc-mysql\\datas\\jdbc.properties"));
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String user = prop.getProperty("username");
                String pwd = prop.getProperty("password");
    
                //1、加载驱动
                Class.forName(driver);
                //2、获取与数据库的连接
                conn = DriverManager.getConnection(url, user, pwd);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    
    
        public static void body() {
            //方法封装欢迎界面
            index();
            boolean b = login();
            if (b) {
                System.out.println(username + "用户登录成功,正在跳转至主页面....");
            } else {
                System.out.println(username + " 该用户不存在!!");
                System.out.println("请先前往注册界面进行注册!!(Y/N)");
                String b2 = sc.next();
                if ("Y".equalsIgnoreCase(b2)) {
                    int count = register();
                    if (count == 1) {
                        System.out.println("用户注册成功!!!,正在切换登录页面....");
                        boolean b3 = login();
                        if(b3){
                            System.out.println(username + "用户登录成功,正在跳转至主页面....");
                        }else {
                            System.out.println("用户名和密码错误,登录失败!!");
                        }
                    } else {
                        System.out.println("用户注册失败!!");
                    }
                } else {
                    System.out.println("欢迎下次继续使用!!");
                }
            }
            quit();
    
        }
    
    }
    
    

    JDBC事物机制:
    1.JDBC中的事务自动提交的,什么是自动提交?
    只要执行任意一条 DML语句,则自动提交一次。这是JDBC默认的事务行为。
    但是在实际的业务中,通常都是N条DML语句共同联合才能完成,必须
    保证这些DML语句在同一个事务中同时成功或者同时失败
    解决方案:三行重要的代码
    conn.setAutoCommit(false);//手动提交事务
    conn.commit();//提交事务
    conn.rooback;当发生异常时或者程序错误时,进行回滚。

    6.5.7 工具类封装
    package com.wyh.util;
    
    import java.io.FileReader;
    import java.sql.*;
    import java.util.Properties;
    
    /**
     * JDBC工具类,简化JDBC编程
     */
    public class DBUtil {
        // 工具类中的构造方法都是私有化的,所有工具类中的方法都是静态公共的
        // 不需要new对象
        private DBUtil() {
        }
    
        public static Connection getConnection() {
            Properties prop = null;
            Connection conn = null;
            try {
                prop = new Properties();
                prop.load(new FileReader("E:\\projects\\IdeaProjects\\jdbc-mysql\\datas\\jdbc.properties"));
                String driver = prop.getProperty("driver");
                String url = prop.getProperty("url");
                String user = prop.getProperty("username");
                String pwd = prop.getProperty("password");
    
                //1、加载驱动
                Class.forName(driver);
                //2、获取与数据库的连接
                conn = DriverManager.getConnection(url, user, pwd);
    //            return DriverManager.getConnection(url, user, pwd);
            } catch (Exception e) {
                e.printStackTrace();
            }
            return conn;
        }
    
        public static void close(Connection conn, Statement statement, ResultSet... rs) {
            //释放资源
            if (rs[0] != null) {
                try {
                    rs[0].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();
                }
            }
        }
    
    
    }
    
    

    工具类使用

    package com.wyh.jdbc;
    
    import com.wyh.util.DBUtil;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    public class JDBCTest7 {
        public static void main(String[] args) {
            Connection conn = DBUtil.getConnection();
            //获取执行sql对象
            try {
                PreparedStatement preStmt = conn.prepareStatement("select username,password from user where username=? and password=?");
                preStmt.setString(1,"xiaohu");
                preStmt.setString(2,"123456");
                ResultSet resultSet = preStmt.executeQuery();
                if(resultSet.next()){
                    System.out.println("数据查找成功!!");
                }else {
                    System.out.println("数据查找失败!!");
                }
                DBUtil.close(conn,preStmt,resultSet);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    
    6.5.8 JDBC实现模糊查询
    package com.wyh.jdbc;
    
    import com.wyh.util.DBUtil;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    /*
            JDBC实现模糊查询
     */
    public class JDBCTest8 {
        public static void main(String[] args) {
            Connection conn = DBUtil.getConnection();
    
            //错误写法
    //        String sql = "select ename from emp where ename like '_?%'";
    
            //正确写法
            String sql = "select ename from emp where ename like ?";
            try {
                PreparedStatement preStemt = conn.prepareStatement(sql);
    //            preStemt.setString(1, "A");
                preStemt.setString(1, "_A%");
                ResultSet resultSet = preStemt.executeQuery();
                while (resultSet.next()) {
                    String ename = resultSet.getString("ename");
                    System.out.println(ename);
                }
                DBUtil.close(conn, preStemt, resultSet);
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    

    6.5 悲观锁和乐观锁的概念

    事务1–>读取到版本号1.1
    事务2—>读取到版本号1.1

    其中事务1先修改了,修改之后看了版本号是1.1 ,于是提交修改的数据,将版本号修改为1.2
    其中事务2后修改的,修改之后准备提交的时候,发现版本号是1.2 ,和它最初读的版本号不一致。回滚。

    悲观锁:事务必须排队执行。数据锁住了,不允许并发。 (行级锁: select后面添加for update )
    乐观锁:支持并发,事务也不需要排队,只不过需要一个版本号。

    6.6 演示索引的效率

  • 相关阅读:
    用Python构建你自己的推荐系统
    相似度算法之余弦相似度
    python(五)常用模块学习
    Linux系统CPU核数等信息查看
    【SSH网上商城项目实战28】使用Ajax技术局部更新商品数量和总价
    【SSH网上商城项目实战27】域名空间的申请和项目的部署及发布
    【SSH网上商城项目实战26】完成订单支付后的短信发送功能
    【SSH网上商城项目实战25】使用java email给用户发送邮件
    【SSH网上商城项目实战24】Struts2中如何处理多个Model请求
    【SSH网上商城项目实战23】完成在线支付功能
  • 原文地址:https://www.cnblogs.com/atao-BigData/p/16260786.html
Copyright © 2020-2023  润新知