zoukankan      html  css  js  c++  java
  • 4.JDBC编程

    01.JDBC_Java程序和MySQL的关系:
        1).Java程序跟其它MySQL客户端一样,就是一个"客户端",用于"封装SQL语句"并发送给MySQL服务器,
           MySQL服务器会直接返回结果给我们的程序。
      
      (上面的命令行就是黑窗口,它与 SQLYog、JAVA程序一样,同级)
    02.JDBC_驱动的概念:
        由数据库厂商为每种编程语言提供的一个程序包。有两种语言组成:前端:所面向的编程语言;后端:数据库本身的语言。
        它可以使各种编程语言直接访问本语言,就可以访问数据库软件,方便操作。
        JDBC物理上由一组类和接口组成(通过工具类进行具体操作,JDBC接口实现类),随JDK一起发放。
    03.JDBC_JDBC的概念:
        由SUN公司提出的Java连接数据库的规范,它规范了Java连接各种数据库所遵循的步骤和数据类型。它要求各数据库厂商的驱动程序必须遵守这套规范,也需要Java程序员直接学习这套规范,这样可以使得Java程序员访问各种数据库都使用同样的步骤和数据类型。

    04.JDBC_JDBC的四个核心类:
        1).DriverManager(类) : 驱动管理器。 用于连接数据库的"驱动程序",并通过驱动程序去连接数据库软件,向程序返回一个"连接通道(Connection对象)"。
        2).Connection(接口) : "连接"对象。代表了程序和数据库之间的一个"连接通道"。
        3).Statement(接口) : SQL执行器。用于执行SQL语句。
        4).ResultSet(接口) : 结果集。当Statement执行"查询"语句时,会返回此对象。
    05.JDBC_JDBC的开发步骤:
        1).下载MySQL的Java驱动包,并复制到项目目录下,并添加到构建路径:
            mysql-connector-java-5.1.37-bin.jar
        2).开发步骤:
            1.注册驱动
            2.获取连接
            3.获取SQL执行器
            4.执行SQL,并获取结果集(查询)
            5.解析结果集
            6.关闭资源
    /*
     * 1.注册驱动
     * 2.获取连接
     * 3.获取SQL执行器
     * 4.执行SQL,并获取结果集(查询)
     * 5.解析结果集
     * 6.关闭资源
     */
    public class Demo {
        public static void main(String[] args) throws Exception {
            //1.注册驱动     // 数据库.jdbc.驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1", "root", "root");
            //3.获取SQL执行器
            Statement stmt = conn.createStatement();
            //4.执行SQL,并获取结果集(查询)
            String sql = "select * from product";
            ResultSet rs = stmt.executeQuery(sql);
            //5.解析结果集
            while(rs.next()){
                System.out.println(rs.getInt("pid") + "	" +
                                    rs.getString("pname") + "	" +
                                    rs.getInt("price") + "	" +
                                    rs.getInt("cid"));
            }
            //6.关闭资源
            rs.close();
            stmt.close();
            conn.close();
        }
        @Test
        public void delete() throws Exception{
            Class.forName("com.mysql.jdbc.Driver");
            Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root");
            Statement stmt = conn.createStatement();
            String sql = "delete from product where pid = 6";
            int row = stmt.executeUpdate(sql);
            System.out.println("删除影响的行数:" + row);
            stmt.close();
            conn.close();
        }
    }
    06.JDBC_关于Statement的常用方法:
        1).public int executeUpdate(String sql):用于执行添加(insert)、修改(update)、删除(delete)语句的。
                            返回值:int,影响的行数。
        2).public ResultSet executeQuery(String sql):用于执行查询(select) 
                            返回值:ResultSet结果集。
        注意:两种不能混用。不能用executeUpdate()执行查询语句,反之也不可以。
     
    07.JDBC_关于ResultSet的使用:
        1).ResultSet就类似于之前的"迭代器"
            迭代器:while(it.hasNext()) {           结果集:while(rs.next()) {
                              it.next();                                          rs.get数据类型(String 列名)
      }                                                         或者
                                            rs.get数据类型(int 列索引)
     
                                            大招:
                                            rs.getObject(String 列名)
                                            rs.getObject(int 列索引)
                                         }

     08.JDBC_使用JDBC实现增删改查:

    public class Demo {
       @Test
    public void add() throws Exception{ //1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); //3.获取SQL执行器 Statement stmt = conn.createStatement(); //4.执行SQL语句 String sql = "insert into product values(null,'钢琴',28000,1)"; int row = stmt.executeUpdate(sql); System.out.println("添加影响的行数:" + row); //5.释放资源 stmt.close(); conn.close(); }
       @Test
    public void update() throws Exception{ //1.注册驱动 Class.forName("com.mysql.jdbc.Driver"); //2.获取连接 Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); //3.获取SQL执行器 Statement stmt = conn.createStatement(); //4.执行SQL String sql = "update product set price = 38000 where pid = 7"; int row = stmt.executeUpdate(sql); System.out.println("修改影响的行数:" + row); //5.释放资源 stmt.close(); conn.close(); }
       @Test
    public void delete() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); Statement stmt = conn.createStatement(); String sql = "delete from product where pid = 7"; int row = stmt.executeUpdate(sql); System.out.println("删除影响的行数:" + row); stmt.close(); conn.close(); } @Test public void findAll() throws Exception{ Class.forName("com.mysql.jdbc.Driver"); Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root"); Statement stmt = conn.createStatement(); String sql = "select * from product"; ResultSet rs = stmt.executeQuery(sql); while(rs.next()){ System.out.println(rs.getInt("pid") + " " + rs.getString("pname") + " " + rs.getInt("price") + " " + rs.getInt("cid")); } rs.close(); stmt.close(); conn.close(); } }

    09.JDBC_JDBC工具类的制作:

        public class JDBCUtils {
            //1.获取Connection对象--代码重用的目的 --静态方法
            public static Connection getConnection() throws Exception{     //前两步 定义了一个静态方法
                Class.forName("com.mysql.jdbc.Driver");
                Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/testdb_1","root","root");
                return conn;
            }
            //2.关闭资源
            public static void closeAll(ResultSet rs,Statement stmt,Connection conn) throws SQLException{
                if(rs != null){
                    rs.close();
                }
                if(stmt != null){
                    stmt.close();
                }
                if(conn != null){
                    conn.close();
                }
            }
        }

    升级版:

    import导包;
    //定义一个数据库工具类JdbcUtil,用来简化数据库操作出现的重复代码。
    //创建类JdbcUtil包含3个方法:
    //1) 可以把几个字符串定义成常量
    //2) public static Connection getConnection() 得到数据库的连接
    //3) 在静态代码块中注册驱动,只需注册一次即可。无需放在getConnection()方法中
    //4) public static void close(Connection conn,Statement stmt,ResultSet rs) 关闭所有打开的资源
    //5)public static void close(Connection conn,Statement stmt) 关闭没有结果集的资源,可以调用上面的方法。
    public class JDBCUtils {
         private static String driver = "com.mysql.jdbc.Driver";
         private static String url = "jdbc:mysql:///testdb2";
         private static String user = "root";
         private static String password = "root";
         static{
               try {
                    Class.forName(driver);
               } catch (Exception e) {
                    throw new RuntimeException(e) ;
               }
         }
         public static Connection getConnection() throws Exception{
               Connection conn = DriverManager.getConnection(url, user, password);
               return conn;
         }
         public static void close(Connection conn,Statement stmt,ResultSet rs){
               if (rs != null) {
                    try {
                         rs.close();
                    } catch (SQLException e) {
                    }
               }
               if (stmt != null) {
                    try {
                         stmt.close();
                    } catch (SQLException e) {
                    }
               }
               if (conn != null) {
                    try {
                         conn.close();
                    } catch (SQLException e) {
                    }
               }
         }
         public static void close(Connection conn,Statement stmt){
               if (stmt != null) {
                    try {
                         stmt.close();
                    } catch (SQLException e) {
                    }
               }
               if (conn != null) {
                    try {
                         conn.close();
                    } catch (SQLException e) {
                    }
               }
         }
    }

    10.JDBC_SQL语句的封装:

        public class Demo {
            public static void main(String[] args) throws Exception {
                Scanner sc = new Scanner(System.in);
                System.out.println("请输入商品名称:");
                String pname = sc.next();//海尔冰柜
                System.out.println("价格:");
                int price = sc.nextInt();//2300
                System.out.println("类别ID:");
                int cid = sc.nextInt();//1
    
                //1.获取连接对象
                Connection conn = JDBCUtils.getConnection();
                //2.获取SQL执行器
                Statement stmt = conn.createStatement();
                //3.【封装SQL语句】
                //先想象,封装后的SQL语句:"insert into product values(null,'海尔冰柜',2300,1)"
                String sql = "insert into product values(null,'" + pname +
                                    "'," + price + "," +
                                    cid + ")";
                System.out.println(sql);
    
                //4.执行SQL语句
                int row = stmt.executeUpdate(sql);
                System.out.println("添加影响的行数:" + row);
                //5.释放资源
                JDBCUtils.closeAll(null, stmt, conn);
            }
        }

    11.JDBC_关于SQL注入的问题:

        1).什么是SQL注入:是指在用户的数据中,包含了一些SQL的格式化符号,例如:)或者(或者,或者',如果程序接收后,不加以判断直接封装到SQL语句中会导致SQL语句的错误。这种现象就叫:SQL注入。
        2).SQL注入的登录演示:
    import 导包;
    public class Demo {
        public static void main(String[] args) throws Exception {
            Scanner sc = new Scanner(System.in);
            System.out.println("请输入登录名:");     //sfasdfg
            String loginName = sc.nextLine();       
            System.out.println("输入密码:");        //asfsadf ' or '1=1    //(后者1=1 恒成立,显示登录成功,所以有bug)
            String loginPwd = sc.nextLine();
            //1.获取连接对象
            Connection conn = JDBCUtils.getConnection();
            Statement stmt = conn.createStatement();
            String sql = "select * from users where uname = '" + loginName +
                            "' and password = '" + loginPwd + "'";
            System.out.println(sql);
            ResultSet rs = stmt.executeQuery(sql);
            if(rs.next()){
                System.out.println("欢迎:" + loginName + " 登录系统!");
            }else{
                System.out.println("用户名或密码错误!!");
            }
            //2.释放资源
            JDBCUtils.closeAll(rs, stmt, conn);
        }
    }
        3).怎样解决SQL注入的问题:
            不用Statement,改用它的子接口:PreparedStatement--预处理的SQL执行器
            PreparedStatement:它可以严格的区分出"SQL语句"和"数据",不会将数据中的SQL的格式化符号解析为SQL格式化符号,而认为就是数据。

    12.JDBC_使用PreparedStatement解决SQL注入的问题:

        Scanner sc = new Scanner(System.in);
        System.out.println("请输入登录名:");
        String loginName = sc.nextLine();
        System.out.println("输入密码:");
        String loginPwd = sc.nextLine();
    
        Connection conn = JDBCUtils.getConnection();
        //1.先封装SQL语句,数据部分要用?号占位,任何数据类型不需要单引号
        String sql = "select * from users where uname = ? and password = ?";             //红色 就是改过的区别
        //2.获取PreparedStatemet对象
        PreparedStatement ps = conn.prepareStatement(sql);
        //3.填充数据
        ps.setString(1, loginName);     //这个1代表第一个?号
        ps.setString(2, loginPwd);       //这个2代表第二个?号
    
        //4.执行
        ResultSet rs = ps.executeQuery();//注意:不要再传SQL语句了,因为之前已经有SQL语句了(ps中已传入数据了)
        if(rs.next()){
            System.out.println("欢迎:" + loginName + " 登录系统!");
        }else{
            System.out.println("用户名或密码错误!!");
        }
        //2.释放资源
        JDBCUtils.closeAll(rs, ps, conn);

    13.JDBC_使用PreparedStatement完成增删改查(CRUD)--(增删改查之前一定要确定JDBCUtils工具类 中操作的表格是否在该数据库下)

      public void add() throws Exception{
            //1.获取连接对象
            Connection conn = JDBCUtils.getConnection();
            //2.获取预处理对象
            String sql = "insert into product values(null,?,?,?)";
            PreparedStatement ps = conn.prepareStatement(sql);
            //3.填充数据
            ps.setString(1, "奔驰");
            ps.setInt(2, 440000);
            ps.setInt(3, 1);
            //4.执行SQL
            int row = ps.executeUpdate();
            System.out.println("添加影响的行数:" + row);
            //5.释放资源
            JDBCUtils.closeAll(null, ps, conn);          //记得,别忘了关闭资源
        }
        public void update() throws Exception{
            //1.获取连接对象
            Connection conn = JDBCUtils.getConnection();
            //2.获取预处理对象
            String sql = "update product set pname = ? , price = ? where pid = ?";     //所以的数据都 用? 替换掉(set在表名后)
            PreparedStatement ps = conn.prepareStatement(sql);
            //3.填充数据
            ps.setString(1, "奔驰E级");
            ps.setInt(2, 420000);
            ps.setInt(3, 9);
            //4.执行SQL
            int row = ps.executeUpdate();
            System.out.println("修改影响的行数:"  + row);
            //5.释放资源
            JDBCUtils.closeAll(null, ps, conn);
        }
        public void delete() throws Exception{
            Connection conn = JDBCUtils.getConnection();
            String sql = "delete from product where pid = ?";          //删除没有 * 号,切记
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setInt(1, 9);
            int row = ps.executeUpdate();
            System.out.println("删除影响的行数:" + row);
            JDBCUtils.closeAll(null, ps, conn);
        }
        public void findAll() throws Exception{          //查找所有 ,不需要填充数据
            Connection conn = JDBCUtils.getConnection();
            String sql = "select * from product";
            PreparedStatement ps = conn.prepareStatement(sql);
    
            ResultSet rs = ps.executeQuery();
            while(rs.next()){                                   //查询所有用 while
                System.out.println(rs.getInt("pid") + "	" + rs.getString("pname") + "	"
                                + rs.getInt("price") + "	" + rs.getInt("cid"));
            }
            JDBCUtils.closeAll(rs, ps, conn);
        }
        @Test
        public void findById() throws Exception{
            Connection conn = JDBCUtils.getConnection();
            String sql = "select * from product where pid = ?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setInt(1, 1);
    
            ResultSet rs = ps.executeQuery();
            if(rs.next()){                    //切记查找一个,需要用if
                System.out.println(rs.getInt("pid") + "	" + rs.getString("pname") + "	"
                                            + rs.getInt("price") + "	" + rs.getInt("cid"));
            }
    
            JDBCUtils.closeAll(rs, ps, conn);
    
        }
    注意点:
    查询所有用while;查询某个用if. 而且封装的对象或集合 要放在while或if判断语句内!
    查询,格式:
    String sql = "select name, sal from table where name like ?"
    String sql = "select * from table where id = ?";
    删除,格式:
    String sql = "delete from table where id = ?";
    修改,格式:
    String sql = "update table set sal =  ?  where id = ? ";
    增加,格式:
    String sql = "insert into table values(null,?,?,?)";
     
     
     
  • 相关阅读:
    驾驶细节
    python 字符串前面加u,r,b,f的含义
    pandas dataframe指定列字符串转成数字的方法
    python 休息随机秒
    Windows搭建ffmpeg推流服务端 sky
    在golang中如何正确判断接口是否为nil
    快速了解一门技术的学习方法
    TortoiseGit使用教程(图文详细版)
    centos7升级安装openssl版本
    CentOS7防火墙,开放端口配置
  • 原文地址:https://www.cnblogs.com/zs-notes/p/9319110.html
Copyright © 2011-2022 走看看