zoukankan      html  css  js  c++  java
  • JDBC技术详解

    JDBC基础

    1.JDBC介绍

    JDBC是java访问[对象型数据库/关系型数据库]数据库的规则,是原SUN公司开发的.

    原来我们程序员需要针对具体的数据库操作,费时费力;
    自从有了JDBC规则后,程序员只需要针对JDBC规则编程,不用管底层具体数据库的实现,
    好处在于:写一份JDBC代码,可以在很多数据库在执行,即可移植性

    2.驱动的原理及使用

    就是JDBC规则,在具体数据库中的实现类,且用java书写(需要安装JDK)

    3.JDBC核心使用

    做jdbc代码,需要用到如下几个固定步骤,以查询为例:

    • 1_注册mysql数据库服务器的驱动,DriverManager
    • 2_获取mysql数据库服务器的连接,Connection
    • 3_获取封装sql语句的对象,Statement
    • 4_执行sql语句,并返回结果集合,ResultSet
    • 5_迭代这个结果集合,while(){}
    • 6_按轻到重的原则关闭连接对象,ResultSet-Statement-Connection,在必要情况下,Connection可重用

    4.DriverManager(类)、Connection(接口)、Statement(接口)、ResultSet(接口)详细使用

    • DriverManager:
      它是一个类,由原SUN公司提供,负责管理一个或一组访问具体数据库的驱动,
      即你想访问Oracle数据库服务器的话,就让DriverManager加载Oracle驱动,
      只需注册一次就行

    • Connection:
      是原SUN公司提供的接口,是属于重量级对象,建议少创建,要重用
      只要你想与数据库进行操作,必须获取连接对象

      jdbc:mysql://127.0.0.1:3306/mydb1","root","123"
      jdbc:主协议,你只要使用jdbc技术访问数据库,都是jdbc主协议
      mysql:子协议
      127.0.0.1:MySQL数据库服务器所在PC的IP地址或域名,建议用IP
      3306:MySQL数据库服务器所在的PC的端口号
      mydb1:访问数据库服务器中哪一个具体的数据库
      root:用户名
      123:密码,如果没有密码的话,也需要写""空字符串
      
    • Statement:
      负责封装SQL语句并执行的对象,是原SUN公司提供的接口

      SQL语句在JDBC中分为二大类
      1_静态SQL:SQL语句中无?符号,即select id,name from users where name = '张三'(上)
      2_动态SQL:SQL语句中有?符号,即select id,name from users where name = ?
                 ?号由程序在运行时动态设置的值
      
    • Statement常用的API:
    • 查询:executeQuery(参数为静态SQL),返回值为ResultSet
      增删改:executeUpdate(参数为静态SQL),返回值为Int,表示影响表格行数

    • ResultSet:
      负责装查询语句的结果,默认情况下,游标位于第一条记录的前边。
      next()方法就能向下移动一行,如果有结果,返回true

    5.jdbc的crud

    • 增删改:Statment.executeUpdate(),返回值为int,表示这次操作影响了表中的几条记录
    • 查询:Statment.executeQuery(),返回值为ResultSet,表示这次查询操作结果记录数形成的集合

    6.sql注入

    • 客户端利用jdbc-Statement的缺点,传入非法参数,从而让jdbc返回不合法的值,我们利用这种情况,通称为sql注入.
    • 现在项目中不直接使用Statement,使用PreparedStatement,PreparedStatement它除了具有Statement是所有功能外,还有动态sql处理能力,包括:程序执行时动态为?符设置值,安全检查,避免sql注入问题,预处理能力

    • ?表示占位符,只能出现在字段值的位置,不能替代表名,不能替代列名;
      ?表示的字段值,不管是什么类型,都不用加”符号

    • Statement和PreparedStatement的区别:
      Statement只能处理静态SQL;
      PreparedStatement既能处理静态sql也能处理动态sql,它继承了Statement的特点

    • 站在预处理角度:
      PreparedStatement适合做连续多次结构相同的sql语句,有优势.
      Statement适合做连续多次不同结构的sql语句,有优势.

    • 项目中,我们都用子接口,
      1_支持动态sql,也支持静态sql
      2_预处理

      ---相同结构的sql
      select id,name,from users where id=1;
      select id,name,gender from users where id=2;
      是不相同结构 
      ---不同结构的sql
      
    • 声明:
    • 静态sql也可以用PreparedStatement

    适合:
    静态sql—优先Statement;
    动态sql—优先PreparedStatement

    Statement代码实现:

        import java.sql.Connection;
        import java.sql.DriverManager;
        import java.sql.ResultSet;
        import java.sql.SQLException;
        import java.sql.Statement;
    
        /**
         * JDBC开发
         */
        public class Demo {
        static{
            //1)注册一个MySQL数据库驱动,因为你现在要访问的是MySQL数据库服务器,用反射
            //好处:只向DriverManager注册一次MySQL驱动
            //好处:无需导入MySQL具体的类名
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        /**
         * 查询所有用户
         */
        public void findAllUser() throws Exception{
            Connection conn = null;
            Statement stmt = null;
            ResultSet rs = null;
            try {
                //NO2)获取JavaApp与MySQL数据库服务器的连接
                conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/mydb1","root","123");
                //NO3)创建封装SQL语句的对象
                stmt = conn.createStatement();
                //NO4)执行SQL语句,返回结果集合,里面存放装SQL语句执行结果,即是四条记录
                rs = stmt.executeQuery("select id,username,gender,hiredate from users");
                //NO5)迭代结果集合,在默认情况下,游标指向第一条记录之前,通过next方法将游标下移一条,如果有记录存在,返回true;否则false
                while(rs.next()){
                    //获取一条中id列名对应的值
                    int id = rs.getInt("id");
                    String username = rs.getString("username");
                    String gender = rs.getString("gender");
                    //在与JDBC访问时,MySQL中的date,对应java中的java.sql.Date
                    java.sql.Date hiredate = rs.getDate("hiredate");
    
                    System.out.println(id+"#"+username+"#"+gender+"#"+hiredate);
                }
            } catch (SQLException e) {
                e.printStackTrace();
                //通知调用者,给前台用户提示,html/jsp
                throw e;
            } finally{
                //NO6)关闭上述用过的连接对象
                if(rs!=null){
                    try {
                        rs.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }finally{
                        //GC回收
                        rs = null;
                    }
                }
                if(stmt!=null){
                    try {
                        stmt.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }finally{
                        //GC回收
                        stmt = null;
                    }
                }
                //后期重用Connection
                if(conn!=null){
                    try {
                        conn.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }finally{
                        //GC回收
                        conn = null;
                    }
                }
            }
        }
    
        /**
         *  主方法
         */
        public static void main(String[] args) throws Exception{
            Demo dao = new Demo();
            dao.findAllUser();
        }
    }
    

    PreparedStatement完成对users表的CURD操作,代码实现:

        import java.sql.Connection;
        import java.sql.PreparedStatement;
        import java.sql.ResultSet;
        import cn.itheima.entity.User;
        import cn.itheima.utils.JdbcUtils;
    
        /**
         * 演示PreparedStatement完成对users表的CURD操作
         */
        public class Demo01 {
            /**
             * 增加用户 
             */
            public void add(User user){
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                String sql = "insert into users(username,gender,hiredate) values(?,?,?)";
                try{
                    conn = JdbcUtils.getConnection();
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setString(1,user.getUsername());
                    pstmt.setString(2,user.getGender());
                    pstmt.setDate(3,new java.sql.Date(user.getHiredate().getTime()));
                    int i = pstmt.executeUpdate();
                    System.out.println(i>0?"成功":"失败");
                }catch(Exception e){
                    e.printStackTrace();
                    throw new RuntimeException("增加用户失败");
                }finally{
                    JdbcUtils.close(rs);
                    JdbcUtils.close(pstmt);
                    JdbcUtils.close(conn);
                }
            }
            /**
             * 修改用户 
             */
            public void update(String oldUsername,String newUsername){
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                String sql = "update users set username = ? where username = ?";
                try{
                    conn = JdbcUtils.getConnection();
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setString(1,newUsername);
                    pstmt.setString(2,oldUsername);
                    int i = pstmt.executeUpdate();
                    System.out.println(i>0?"成功":"失败");
                }catch(Exception e){
                    e.printStackTrace();
                    throw new RuntimeException("增加用户失败");
                }finally{
                    JdbcUtils.close(rs);
                    JdbcUtils.close(pstmt);
                    JdbcUtils.close(conn);
                }
            }
            /**
             * 查询用户 
             * @param lastname 在这里表示姓
             * @param gender 性别
             */
            public void find(String lastname,String gender){
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                //String sql = "select * from users where username like '赵%' and gender = '男'";
                String sql = "select id,username,gender,hiredate from users where username like ? and gender = ?";
                try{
                    conn = JdbcUtils.getConnection();
                    pstmt = conn.prepareStatement(sql);
                    pstmt.setString(1,lastname+"%");
                    pstmt.setString(2,gender);
                    rs = pstmt.executeQuery();
                    while(rs.next()){
                        int id = rs.getInt("id");
                        String username = rs.getString("username");
                        gender = rs.getString("gender");
                        java.sql.Date hiredate = rs.getDate("hiredate");
                        System.out.println(id+"#"+username+"#"+gender+"#"+hiredate);
                    }
                }catch(Exception e){
                    e.printStackTrace();
                    throw new RuntimeException("查询用户 失败");
                }finally{
                    JdbcUtils.close(rs);
                    JdbcUtils.close(pstmt);
                    JdbcUtils.close(conn);
                }
            }
            /**
             * 批量删除用户 
             */
            public void delete(int... ids){
                Connection conn = null;
                PreparedStatement pstmt = null;
                ResultSet rs = null;
                StringBuffer sb = new StringBuffer("delete from users where id in (");
                for(int id : ids){
                    sb.append(id+",");
                }
                //删除最后一个逗号
                sb.deleteCharAt(sb.length()-1);
                //在最后拼接)
                sb.append(")");
                String sql = sb.toString();
                try{
                    conn = JdbcUtils.getConnection();
                    pstmt = conn.prepareStatement(sql);
                    int i = pstmt.executeUpdate();
                    System.out.println(i>0?"成功":"失败");
                }catch(Exception e){
                    e.printStackTrace();
                    throw new RuntimeException("批量删除用户失败");
                }finally{
                    JdbcUtils.close(rs);
                    JdbcUtils.close(pstmt);
                    JdbcUtils.close(conn);
                }
            }
    
    
    
    
            public static void main(String[] args) {
                Demo01 test = new Demo01();
                User user = new User();
                user.setUsername("张三");
                user.setGender("男");
                user.setHiredate(new java.util.Date());
                //test.add(user);
                //test.update("张三","李四");
                //test.find("赵","男");
                test.delete(1,6,7);
            }
        }

    摘自:https://blog.csdn.net/shuaicihai/article/details/53416045?ops_request_misc=%25257B%252522request%25255Fid%252522%25253A%252522160965081316780263098257%252522%25252C%252522scm%252522%25253A%25252220140713.130102334.pc%25255Fall.%252522%25257D&request_id=160965081316780263098257&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~first_rank_v2~rank_v29-2-53416045.pc_search_result_cache&utm_term=JDBC%E6%8A%80%E6%9C%AF
  • 相关阅读:
    django orm 以列表作为筛选条件进行查询
    申请Let's Encrypt通配符HTTPS证书
    redis集群部署及踩过的坑
    MySQL的索引是什么?怎么优化?
    Session管理之超时设置和强制下线
    在MySQL中使用explain查询SQL的执行计划
    基于Docker搭建MySQL主从复制
    这些年一直记不住的 Java I/O
    高并发大容量NoSQL解决方案探索
    php 如何生成静态页
  • 原文地址:https://www.cnblogs.com/coder-ahao/p/14225318.html
Copyright © 2011-2022 走看看