JAVA_EE第一章 JDBC

一、JDBC概念

Java Database connecitivity:java连接访问关系型数据库技术。
SUN公司提供的一套执行SQL语句的API,主要由接口组成,可以为多种关系型数据库提供统一访问。
Sun公司为简化数据库开发,定义了一套JDBC接口,这套接口由数据库厂商去实现,开发人员只需要学习JDBC接口,并通过JDBC加载具体的驱动,就可以操作数据库。

二、JDBC开发条件

1.JDBC接口:
  • java.sql包
  • javax.sql包

三、JDBC开发原理这里写图片描述

四.JDBC开发步骤
  • 1)通过DriverManager 实现对驱动的注册
  • 2) 建立连接,
  • 3)发送sql指令。
  • 4)接收请求并处理
  • 5)释放资源
    数据库的连接数是有限的,比如200个,必须释放完了才能给后面用。
五.入门案例

1)创建java程序,导入mysql的驱动jar包(jar包就是很多.class文件。可以直接运行).

  • 协议 IP 端口 其他参数
  • jdbc:mysql://localhost(127.0.0.1):3306/bd1804
  • 以前的url都是http,现在是https,s指的是ssl
        ResultSet rs = null;
        Statement stmt = null;
        Connection conn = null;
        try {
            //1.使用DriverManager实现对驱动的注册
            //com.mysql.jdbc.Driver是java.sql.Driver的实现类
            //DriverManager.registerDriver(new Driver());  //加载两次
            //获取Dirver的class对象
            //1.实现驱动注册只有一个方法DriverManager.registerDriver()
            //2.在加载Driver类调用registerDriver()
            //3.静态代码块
            Class.forName("com.mysql.jdbc.Driver");  

            //2.获取连接
            conn = DriverManager.getConnection(
                            "jdbc:mysql://localhost:3306/bd1804?useSSL=true", 
                            "root", 
                            "root");

            //获取connection的元数据信息(元数据:解释数据的数据)
            //封装了与连接相关的所有信息(数据库类型 版本  用户 ip等)
            /*DatabaseMetaData md = conn.getMetaData();
            System.out.println(md.getDatabaseProductName());
            System.out.println(md.getDatabaseProductVersion());
            System.out.println(md.getURL());
            System.out.println(md.getUserName());
            System.out.println(md.getSchemas());*/
            //3.发送请求
            String sql = "select * from stu";
            //创建stmt对象用于发送sql指令
            stmt = conn.createStatement();
            //rs底层维护的是一个指向结果集的游标
            rs = stmt.executeQuery(sql);
            //4.处理结果
              //逐行获取

                //rs的元数据
              //ResultSetMetaData m = rs.getMetaData();

              while(rs.next()){
                  //获取当前行的数据
                  int sid = rs.getInt("sid");
                  String sname = rs.getString("sname");
                  System.out.println("sid:"+sid+"\tsname:"+sname);
              }
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                if(rs!=null){
                    rs.close();
                }
                if(stmt!=null){
                    stmt.close();
                }
                 if(conn!=null){
                    conn.close();
                }
                } catch (SQLException e) {
                        e.printStackTrace();
                }
                }

六.JDBC详解

(A)DriverManager类(驱动管理器):
  • 实现具体的驱动的注册管理;
  • 获取连接
//1.实现驱动注册只有一个方法DriverManager.registerDriver()
//2.在加载Driver类调用registerDriver()
//3.静态代码块
Class.forName("com.mysql.jdbc.Driver");
不建议:
DriverManager.registerDriver(new Driver());  //加载两次
(B)Connection接口(java.sql):

由DriverManager创建。可以用于创建发送Sql命令的Statement对象。

DriverManager.getConnection("jdbc:mysql://localhost:3306/bd1804?useSSL=true", "root", "root");

//url:统一资源定位符  协议:子协议://ip:port/dbname

//获取connection的元数据信息(元数据:解释数据的数据)
            //封装了与连接相关的所有信息(数据库类型 版本  用户 ip等)
            DatabaseMetaData md = conn.getMetaData();
            System.out.println(md.getDatabaseProductName());
            System.out.println(md.getDatabaseProductVersion());
            System.out.println(md.getURL());
            System.out.println(md.getUserName());
            System.out.println(md.getSchemas());
(C)Statement:用于发送sql命令
  • execute方法:用于发送任意一条sql命令,返回resultSet时返回ture,其他返回false;
  • executeQuery()方法:发送insert/update/delte/ddl语句,返回int
  • addBatch()以及executeBatch()执行批处理命令。
(D)ResultSet :接口集

底层维护一个指向结果集的游标。封装了跟结果相关的信息。

while(rs.next()){
                  //获取当前行的数据
                  int sid = rs.getInt("sid");
                  String sname = rs.getString("sname");
                  System.out.println("sid:"+sid+"\tsname:"+sname);
              }

    //rs的元数据
    //封装和结果相关的信息。
    ResultSetMetaData m = rs.getMetaData();
七、登陆问题
Connection conn = null;
        Statement stmt = null;
        ResultSet rs = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/bd1804?useSSL=true", 
                    "root", 
                    "root");
            //3.借助于stmt发送sql
            String sql = "select * from userinfo where sname = '"
                                +name+"' and password = '"+password+"'";
            stmt = conn.createStatement();
            //4.接收响应并处理
            rs = stmt.executeQuery(sql);
            if(rs.next()){
                System.out.println("登录成功");
            }else{
                System.out.println("登录失败");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(rs!=null){
                    rs.close();
                }
                if(stmt!=null){
                    stmt.close();
                }
                if(conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
  • sql注入攻击:对于输入参数判断不完全,导致输入参数改变原本的sql,实现对数据库恶意攻击方式;
  • 根本原因:输入参数改变原本的sql格式(参数拼接字符串方式);

八、PreparedStatement

  • 接口:statement的子接口;
  • 能够实现对Sql的发送。
Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            //1.注册驱动
            Class.forName("com.mysql.jdbc.Driver");
            //2.获取连接
            conn = DriverManager.getConnection(
                    "jdbc:mysql://localhost:3306/bd1804?useSSL=true", 
                    "root", 
                    "root");
            //3.借助于ps发送sql
               //?代表占位符
            String sql = "select * from userinfo where sname = ? and password = ?";
               //创建ps对象(预编译)
            ps = conn.prepareStatement(sql);
               //给占位符位置进行赋值
            ps.setString(1, name);
            ps.setString(2, password);
            //4.接收响应并处理
            rs = ps.executeQuery();
            if(rs.next()){
                System.out.println("登录成功");
            }else{
                System.out.println("登录失败");
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(rs!=null){
                    rs.close();
                }
                if(ps!=null){
                    ps.close();
                }
                if(conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
statement 和 PreparedStatement的区别
  • 1.PreparedStatement使用占位符能够防止sql的注入攻击,安全性较高
  • 2.PreparedStatement编写简单;
  • 3.PreparedStatement有预编译。将语句先拿到缓存,提升查询效率。
  • (sql语句到mysql里查找内容会有语法检查和语义检查。正确后才去查找。PreparedStatement预编译也是这个作用)
  • 4.但是在批处理中,statement能够实现不同的sql的批量处理,但是PreparedStatement不行。
  • (还是由于预编译)。

九、增删改

Connection conn = null;
        PreparedStatement ps = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///bd1804?useSSL=true", "root", "root");
            //阻止默认提交
            conn.setAutoCommit(false);
            String sql = "insert into userinfo(sname,password) values(?,?)";
            ps = conn.prepareStatement(sql);
            ps.setString(1, sname);
            ps.setString(2, password);
            int rows = ps.executeUpdate();
            //提交事务
            conn.commit();
            System.out.println(rows);
        } catch (Exception e) {
            e.printStackTrace();
            //事务回滚
            try {
                conn.rollback();
            } catch (SQLException e1) {
                e1.printStackTrace();
            }
        }finally{
            try {
                if(ps!=null){
                    ps.close();
                }
                if(conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

十、其他操作

//分页查询(根据传入页码不同展示相应的数据)
        //select * from emp limit index,length
    public static void queryByPage(int pageIndex,int size){
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///bd1804?useSSL=true", "root", "root");
            String sql = "select * from emp limit ?,?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, (pageIndex-1)*size);
            ps.setInt(2, size);
            rs = ps.executeQuery();
            while(rs.next()){
                String ename = rs.getString("ename");
                BigDecimal sal = rs.getBigDecimal("sal");
                System.out.println("ename="+ename+"\tsal="+sal);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(rs!=null){
                    rs.close();
                }
                if(ps!=null){
                    ps.close();
                }
                if(conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //批量处理(增删改)
    public static void batchStmt(){
        Connection conn = null;
        Statement stmt = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///bd1804?useSSL=true", "root", "root");
            String sql1 = "insert into stu(sname,cid,sex) values('ww',1,'男')";
            String sql2 = "update stu set sex = 'man' where sid = 4";
            String sql3 = "delete from stu where sid = 5";
            stmt = conn.createStatement();
            stmt.addBatch(sql1);
            stmt.addBatch(sql2);
            stmt.addBatch(sql3);
            int[] rows = stmt.executeBatch();
            System.out.println(Arrays.toString(rows));
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        }finally{
            try {
                if(stmt!=null){
                    stmt.close();
                }
                if(conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    //ps的批处理
    public static void batchPs(){
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            conn = DriverManager.getConnection("jdbc:mysql:///bd1804?useSSL=true", "root", "root");
            String sql = "insert into stu(sname,cid,sex) values(?,?,?)";
            ps = conn.prepareStatement(sql);

            ps.setString(1, "ss");
            ps.setInt(2, 1);
            ps.setString(3, "man");
            ps.addBatch();

            ps.setString(1, "dd");
            ps.setInt(2, 1);
            ps.setString(3, "woman");
            ps.addBatch();

            int[] rows = ps.executeBatch();
            System.out.println(Arrays.toString(rows));
        } catch (ClassNotFoundException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }finally{
            try {
                if(ps!=null){
                    ps.close();
                }
                if(conn!=null){
                    conn.close();
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

猜你喜欢

转载自blog.csdn.net/gegeyanxin/article/details/80659200