• Java进阶之JDBC


    Java进阶之JDBC

    Java进阶之JDBC

    什么是JDBC

    • 它是Java操作数据库的一组接口
    • 它也是数据库开发的规范
      • 针对程序开发人员的规范
      • 针对于数据库厂商的规范

    操作JDBC

      • 下载JDBC
      • 在项目中导入下载的jar包
      • Java操作MySQL基本步骤
        • 加载驱动,默认情况下,Java程序中是没有JDBC的,需要在程序启动时,将JDBC加载到Java程序中后,即可在程序中使用JDBC
          • Class.forName("com.mysql.jdbc.Driver")
        • 连接数据库
          • 使用驱动管理器连接数据库 DriverManager.getConnection(URL,USER,PASSWORD)
          • 如果连接成功后返回数据库连接对象Connection,是Java程序与数据库进行通信的桥梁
          • 一定要使用java.sql下的Connection
        • 操作数据库
          • 使用Statement接口进行数据库操作
          • Statement接口的来源必须是由Connection对象创建
        • 释放资源
          • close关闭连接
          • 一般创建对象放置在异常块外部,在finally释放资源时,抛出空指针异常
        • 一些常见问题
          • 创建的类名称不要和API库名称一样
          • 保证MySQL数据库的版本与JDBC的版本要一致,否则会报出异常,比如时区异常,检查性异常
    import java.io.*;
    import java.sql.*;
    
    public class JDBC {
        /**
         * 导包 mysql-connector-java-5.1.34-bin
         * @珍珠奶茶不加糖
         */
    
        //静态内部类加载驱动
        static{
            //处理类加载异常
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
    
        //建立连接
        public void JDBC(){
            //从文件中读取URL,USER,PASSWORD
            File file = new File("E:\JAVA\Java2006\src\com\xumouren\work0823\jdbc.txt");
            FileReader fileReader = null;
            BufferedReader bufferedReader = null;
            String URL = null;
            String USER = null;
            String PASSWORD = null;
            try {
                fileReader = new FileReader(file);//抛文件处理异常
                bufferedReader = new BufferedReader(fileReader);
                URL = bufferedReader.readLine();//抛IO流异常
                USER = bufferedReader.readLine();
                PASSWORD = bufferedReader.readLine();
            } catch (FileNotFoundException e) {
                e.printStackTrace();
            } catch (IOException e) {
                e.printStackTrace();
            }finally {//关闭连接
                if(bufferedReader!=null){
                    try {
                        bufferedReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
                if(fileReader!=null){
                    try {
                        fileReader.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
    
            //连接数据库
            Connection connection = null;
            Statement statement = null;
            PreparedStatement preparedStatement = null;
            ResultSet resultSet = null;
            //抛数据库异常
            try {
                connection = DriverManager.getConnection(URL,USER,PASSWORD);
                if(connection.getAutoCommit()){//关闭数据库自动提交
                    connection.setAutoCommit(false);
                }
            } catch (SQLException e) {
                e.printStackTrace();
            }
    
            try {
                //使用sql语句两种方式
                //方式一
                String sql1 = "insert EMP values(7000,'张三','写bug',7839,null,2000,null,10)";
                statement = connection.createStatement();
                statement.execute(sql1);
                //方式二 -- 预编译形式
                String sql2 = "select * from EMP where ENAME = ? ";
                preparedStatement = connection.prepareStatement(sql2);
                //将所要求的值传入问号处
                preparedStatement.setObject(1,"张三");
    
                //将查询结果按结果集输出
                //查询用executeQuery(); 修改改用executeUpdate();  excute()可以执行所有的SQL语句
                resultSet = preparedStatement.executeQuery();
                while(resultSet.next()){//迭代输出
                    String ename = resultSet.getString("ENAME");
                    int empno = resultSet.getInt("EMPNO");
                    // 变量[类型与后面数据库数据类型对应]  = resultSet.get[数据库数据类型](字段名);
                    System.out.println(ename+empno);//输出结果
                }
    
                //如果上述都没有异常,则提交
                connection.commit();
            } catch (SQLException e) {
                //如果出现异常,则回滚
                try {
                    connection.rollback();
                } catch (SQLException ex) {
                    ex.printStackTrace();
                }
                e.printStackTrace();
            }finally {//关闭连接
                if(resultSet!=null){
                    try {
                        resultSet.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(preparedStatement!=null){
                    try {
                        preparedStatement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(statement !=null){
                    try {
                        statement.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
                if(connection!=null){
                    try {
                        connection.close();
                    } catch (SQLException e) {
                        e.printStackTrace();
                    }
                }
            }
    
        }
        //入口
        public static void main(String[] args) {
            JDBC jdbc = new JDBC();
            jdbc.JDBC();
        }
    }
      • JDBC核心接口
        • Connection
          • 与数据库进行连接
          • 作用:与数据库进行交互
          • 常用的API方法
            • DriverManager.getConnection(url,user,password)
            • 对数据库进行事务操作
            • SetAutoCommit(boolean)
        • Statement
          • 实现在Java中执行SQL语句
          • 通过excute(sql)方法,将指定的SQL传入到MySQL数据库中执行
          • 执行excute有三种形式
            • excute(sql) -- 执行所有的sql命令
            • excuteQuery(sql) -- 此方法只能执行对MySQL进行查询的命令
            • excuteUpdate(sql) -- 此方法只能执行对MySQL修改的命令
          • 返回值
            • 当执行select命令后,所有的数据将封装的对象(ResultSet)返回给Java程序
            • 返回的是数据表的快照,返回到内存中
          • 子接口PreparedStatement
            • 出现子接口原因
            • 因为在使用Statement执行查询的时候,会出现SQL注入问题
            • 什么是SQL注入
              • 破坏原有的SQL语句结构,添加新的SQL指令
              • 使原有SQL失去效果
            • PreparedStatement预编译
              • 防止SQL注入
              • 执行SQL命令时,数据的组装更简单
              • 预编译会使执行效率更高
        • ResultSet
          • 该接口是MySQL数据查询后,返回的数据记录集
          • 此接口默认指向内存表中第一行数据的上面
          • 此接口的方法可以实现访问内存表
          • 所有的数据都存储到ResultSet对象
          • 常用API
            • next() -- 可以判断下一行有没有数据,返回值类型Boolean
            • get()<'Type'>(int) -- 参数int表示列的序号,通过列的序号来获取当前数据
            • get()<'Type'>(String) -- 参数String表示列的名称,通过列的名称来获取数据
      • 操作日期类型数据
        • 在MySQL数据库中,常用日期的类型
          • date
          • datetime
          • year
          • timestamp
        • 使用java.sql包下时间类
          • 继承自java.util.Date下
      • 操作事务
        • 关闭自动提交SetAutoCommit(boolean)
        • 提交commit
        • 回滚rollback
      • JDBC操作大对象
        • 将大对象数据按照二进制通过流的方式写入
        • 例如存储一张图片
          • 方法一:将图片上传到服务器本地,在数据库中存放图片的路径
          • 方法二:将图片通过流按照二进制方式存放进数据库
        • 在MySQL中,操作大对象的数据类型有两种
          • text -- 针对文本的大对象类型
          • blob -- 针对于二进制的大对象类型
        • JDBC操作blob步骤
          • 写操作
          • 使用Connection对象创建blob对象
          • Blob blob = connection.createBlob()
          • 将要存储搭配数据库的二进制数据写入搭配blob对象中
            • 需要使用blob对象中提供的输出流对象,向blob对象存储二进制数据
            • 向blob对象中的指定位置,一般都是从头开始写入,设置参数为1
            • 使用OutputStream中的Write()方法向blob对象输出数据
            • 使用preparedStatament将blob对象执行到MySQL数据库
          • 读取与写入操作相反
    import java.io.*;
    import java.sql.*;
    
    public class TestBlob {
        static {//加载驱动
            try {
                Class.forName("com.mysql.jdbc.Driver");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            String url = null;
            String user = null;
            String password = null;
            try {
                Connection connection = DriverManager.getConnection(url,user,password);
                //创建文件流
                File file = new File("E:\img\图片一.jpg");
                //读取文件
                FileInputStream fileInputStream = new FileInputStream(file);
    
                //创建Blob对象,用来存储二进制数据
                Blob blob = connection.createBlob();
                
                //创建输出流,用来将二进制数据存储到Blob对象中
                OutputStream outputStream = blob.setBinaryStream(1);
                
                //创建字节数组
                byte[] bytes = new byte[100];
                //检测是否读取到数据
                int size = -1;
                //将读取到的值存入bytes,返回存储字符个数
                while((size = fileInputStream.read(bytes))!=-1){
                    outputStream.write(bytes,0,size);//将字节写入,从0开始,到最后一个
                }
                outputStream.close();//关闭流
                fileInputStream.close();
                String sql = "insert img values(?,?)";
                PreparedStatement preparedStatement = connection.prepareStatement(sql);
                preparedStatement.setString(1,"图片一.jpg");
                preparedStatement.setBlob(2,blob);
                preparedStatement.close();
                connection.close();
                
            } catch (SQLException e) {
                e.printStackTrace();
            }catch (IOException e){
                e.printStackTrace();
            }
        }
    }
      • 元数据
        • 元数据是用来描述数据的数据
        • 主要用来说明“数据”的意义
        • 元数据的分类
          • 数据库“元数据”
            • 数据库的元数据体现了数据库相关的信息
            • 包含数据库的版本、驱动名称等等
            • 通过Connection下的getMetaData()获取元数据信息
            • 数据库元数据存储到返回的Database对象中
        • 数据表“元数据”
          • 主要是用来描述表的信息的
          • 数据表元数据与数据无关
          • 常用API
            • 获取数据表列的总数 -- getColumnCount
            • 获取数据表列的原名称 -- getColumnName
            • 获取数据表列的别名 -- getColumnLable 没有别名则获取原名称
            • 获取数据表列的类型对应的常量值 -- getColumnType
            • 获取数据表列的类型名称 -- getColumnTypeName
    • JDBC主键返回与批量添加
      • 主键数据的自动返回
        • 使用主键数据自动返回,会自动返回主键值,可以省去一步查询过程
        • 使用主键自动返回操作
          • 创建PreparedStatement时,要指定是否自动返回主键
          • PreparedStatement preparedStatement = connection.preparedStatement(sql,[1 | PreparedStatement.RETURN_GENERATED_KEYS])
          • 如果输入2,或NOT_RETURN_GENERATED_KEYS则不返回
          • 使用preparedStatement.getGeneratedKeys获取主键,返回一个ResultSet
      • 批量添加
        • 执行批量命令与执行单条命令是不一样的
        • 将待插入的数据存储到缓存中 -- preparedStatement.addBatch()
        • 批量执行,将缓存中每一条记录循环插入到数据表中 -- preparedStatement.excuteBatch()

    import java.io.*;import java.sql.*;
    public class TestBlob {    static {//加载驱动        try {            Class.forName("com.mysql.jdbc.Driver");        } catch (ClassNotFoundException e) {            e.printStackTrace();        }    }    public static void main(String[] args) {        String url = null;        String user = null;        String password = null;        try {            Connection connection = DriverManager.getConnection(url,user,password);            //创建文件流            File file = new File("E:\img\图片一.jpg");            //读取文件            FileInputStream fileInputStream = new FileInputStream(file);
                //创建Blob对象,用来存储二进制数据            Blob blob = connection.createBlob();                        //创建输出流,用来将二进制数据存储到Blob对象中            OutputStream outputStream = blob.setBinaryStream(1);                        //创建字节数组            byte[] bytes = new byte[100];            //检测是否读取到数据            int size = -1;            //将读取到的值存入bytes,返回存储字符个数            while((size = fileInputStream.read(bytes))!=-1){                outputStream.write(bytes,0,size);//将字节写入,从0开始,到最后一个            }            outputStream.close();//关闭流            fileInputStream.close();            String sql = "insert img values(?,?)";            PreparedStatement preparedStatement = connection.prepareStatement(sql);            preparedStatement.setString(1,"图片一.jpg");            preparedStatement.setBlob(2,blob);            preparedStatement.close();            connection.close();                    } catch (SQLException e) {            e.printStackTrace();        }catch (IOException e){            e.printStackTrace();        }    }}

    如有问题,请发送邮件至buxiaqingcheng@163.com或者buxiaqingcheng@dingtalk.com
  • 相关阅读:
    javascript获取当前日期、年份和月份等
    程序员也可以懂一点期望值管理
    数据类型,隐式转换以及json,对象,引用类型,预解析 视频教程
    两个值交互位置的几种方法
    通过Class获取标签,兼容的几种思路
    前端开发流程
    元素多层嵌套,JS获取问题
    原生JS实现分页效果2.0(新增了上一页和下一页,添加当前元素样式)
    原生JS实现分页效果1.0
    学习方法,以及时间的安排。
  • 原文地址:https://www.cnblogs.com/zhenzhunaichabujiatang/p/13627559.html
Copyright © 2020-2023  润新知