美文网首页
jdbc 学习

jdbc 学习

作者: 微笑中的你 | 来源:发表于2018-12-06 16:08 被阅读0次

    DAO (Data Access Object)数据访问对象

    位于业务逻辑层 和 数据库之间,实现对持久化数据的访问

    ORM 对象关系映射

    将关系型数据的表映射为对象,方便以面向对象思想开发

    Statement 接口

    PreparedStatement 预编译语句 防止sql拼接错误
    MySQL不支持预编译池,Oracle支持
    可以防止SQL注入 内部将非法字符进行了转义 如将 ' 转义为 \'

    调用带有参数和返回值的存储过程

    
            Connection conn = JdbcUtil.getConn();
            CallableStatement stCall = conn.prepareCall("call getNameById(?,?);");
            stCall.setInt(1, 1);
            stCall.registerOutParameter(2, Types.VARCHAR);
            stCall.execute();
            String name = stCall.getString(2);
            System.out.println(name);
            JdbcUtil.close(conn, stCall, null);
    

    事务模拟银行转账

            //是否有钱
            Connection conn = JdbcUtil.getConn();
            String sql = "select * from account where name=? and money>?";
            PreparedStatement ps = conn.prepareStatement(sql);
            ps.setString(1, "lisi");
            ps.setInt(2, 1000);
            ResultSet rs = ps.executeQuery();
            if (!rs.next()) {
                throw new RuntimeException("余额不足!");
            }
            
            try {       
                //设置事务
                conn.setAutoCommit(false);
                
                //李四  扣除钱
                sql = "update account set money=money-? where name=? ";
                ps = conn.prepareStatement(sql);
                ps.setDouble(1, 1000);
                ps.setString(2, "lisi");
                ps.executeUpdate();
                
                int a = 1/0; //模拟断电等异常
                
                //刘五 增加钱
                sql = "update account set money=money+? where name=? ";
                ps = conn.prepareStatement(sql);
                ps.setDouble(1, 1000);
                ps.setString(2, "liuwu");
                ps.executeUpdate();
                
                //提交事务
                conn.commit();
                System.out.println("转账成功");
            } catch (Exception e) {
                e.printStackTrace();
                //出现异常时进行事务回滚           
                conn.rollback();
            } finally {
                //释放资源
                JdbcUtil.close(conn, ps, rs);
            }
            
        }
    

    批处理

    一次性执行多条sql 语句,比单独提交处理效率高

        普通插入
            Connection conn = JdbcUtil.getConn();
            String sql = "INSERT INTO stu(name,age) VALUES(?,?)";       
            PreparedStatement ps = conn.prepareStatement(sql);
            long begin = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++) {
                ps.setString(1, "李狗蛋");
                ps.setInt(2, 30);
                ps.executeUpdate(); //一次执行一个。
            }
            long end = System.currentTimeMillis();
            long time = end - begin;
            System.out.println(time);
            JdbcUtil.close(conn, ps, null);
    
    批量处理进行插入
            Connection conn = JdbcUtil.getConn();
            String sql = "INSERT INTO stu(name,age) VALUES(?,?)";       
            PreparedStatement ps = conn.prepareStatement(sql);
            long begin = System.currentTimeMillis();
            for (int i = 0; i < 100000; i++) {
                ps.setString(1, "李狗蛋");
                ps.setInt(2, 30);           
                //加入批处理
                ps.addBatch();
            }
            //执行批处理 MySQL 默认不进行批处理,需要在连接数据时url后面添加 rewriteBatchedStatements=true;
            ps.executeBatch();
            long end = System.currentTimeMillis();
            long time = end - begin;
            System.out.println(time);
            JdbcUtil.close(conn, ps, null);
    
    

    存储图片

    可以已二进制流的形式存储 图片 音频 视频等 BLOB
    然而 实际开发中不可能这样做的,实际存储的是文件存储路径。

            //向数据库写入图片
            Connection conn = JdbcUtil.getConn();
            
            String sql = "insert into student(name,image) values(?,?)";
            PreparedStatement ps = conn.prepareStatement(sql);
            FileInputStream in = new FileInputStream("E:/mm.jpg");
            ps.setString(1, "橘子");
            ps.setBlob(2, in);
            ps.executeUpdate();
            JdbcUtil.close(conn, ps, null);
    
            //从数据库获取图片
            Connection conn = JdbcUtil.getConn();
            
            String sql = "select * from student";
            PreparedStatement ps = conn.prepareStatement(sql);
            ResultSet rs = ps.executeQuery();
            if (rs.next()) {
                //获取图片
                Blob blob = (Blob) rs.getBlob("image");
                //获取图片的二进制 输入流
                InputStream in = blob.getBinaryStream();
                
                //将输入流 写到磁盘
                Files.copy(in, Paths.get("E:/pp.png"));
            
            }
            JdbcUtil.close(conn, ps, rs);
    

    插入时获取主键

            Connection conn = JdbcUtil.getConn();
            
            String sql = "insert into stu(name,age) values(?,?)";
            PreparedStatement ps = conn.prepareStatement(sql, Statement.RETURN_GENERATED_KEYS);
            ps.setString(1, "小红");
            ps.setInt(2, 20);
            ps.executeUpdate();
            
            ResultSet rs = ps.getGeneratedKeys();
            if (rs.next()) {
                int id = rs.getInt(1);
                System.out.println(id);
            }
            JdbcUtil.close(conn, ps, rs);
    

    数据库连接池

    保存数据库连接对象的容器。优点:消除对象创建所带来的延迟,提高系统性能。

    为数据库的连接建立一个缓冲池,预先在存放一定数量的连接,
    需要建立连接时,取出一个,使用完毕后再放回去,
    可以通过设置连接池最大连接数来防止系统无尽的与数据库连接
    可以通过连接池的管理机制监视数据库的连接数量,使用情况,为系统开发,测试及性能调整提供依据。

    连接池中的属性:

    • 连接数据库需要的4个要素,驱动名称,数据库地址,用户名,密码
    • 初始化连接数,初始化时,连接池当中创建多少个连接对象
    • 最大连接数 连接池当中最多存储多少个连接对象
    • 最小连接数 连接池当中最少存储多少个连接对象
    • 最大空闲时间 如果获取了一个连接对象,指定时间内没有任何动作,就会自动释放
    • 最大等待时间 指定时间内,尝试获取连接,超出时间,就会提示获取失败

    java 中连接池是使用javax.sql .DataSource接口来表示。
    DataSource和jdbc一样,也是只是提供了一个接口,由第三方组织实现。

    常见的数据库连接池有

    • DBCP spring 推荐,Tomcat的数据源使用的就是DBCP
    • C3P0 是hibernate推荐的 基本上不用。从07年不更新了
    • Druid 阿里巴巴提供的连接池 号称最好的连接池。

    获取方式不同:

    • 传统:Connection conn = DriverManager.getConnection(url,username,pswd);
    • 连接池: Connection conn = DataSource对象.getConnection();
      释放资源不同
    • 传统:conn.close();
    • 连接池 把数据库连接对象还给连接池。
    DBCP 使用
    //  使用DBCP连接池
        public static String driverName = "com.mysql.jdbc.Driver";
        public static String url = "jdbc:mysql://localhost:3306/test_jdbc?rewriteBatchedStatements=true";
        public static String user = "root";
        public static String password = "123";
        public static BasicDataSource ds = null;
    
        static{
            ds = new BasicDataSource();
            ds.setDriverClassName(driverName);
            ds.setUrl(url);
            ds.setUsername(user);
            ds.setPassword(password);
        }
        /**
         * 获取连接对象
         * @return
         */
        public static Connection getConn() {
            try {
                 Connection connection = ds.getConnection();
                 return connection;
            } catch (Exception e) {
                e.printStackTrace();
            }
            return null;
        }
    
    Druid 使用
    创建db.properties配置文件
    driverName=com.mysql.jdbc.Driver
    url=jdbc:mysql://localhost:3306/test_jdbc?rewriteBatchedStatements=true
    username=root
    password=123
    
    创建数据库连接工具类
        public static DataSource ds = null;
        
        static {
            try {
    //          读取配置文件
                Properties p = new Properties();
                FileInputStream in = new FileInputStream("resource/db.properties");
                p.load(in);
                ds = DruidDataSourceFactory.createDataSource(p);
            } catch (Exception e) {
            }
        }
        private void DruidUtil() {
        }
        
        
        public static Connection getConn() throws IOException, SQLException{
            return ds.getConnection();
        }
        /**
         * 释放资源
         * @param conn
         * @param st
         * @param rs
         */
        public static void close(Connection conn, Statement st, ResultSet rs) {
            if (rs !=null) {
                try {
                    rs.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (st != null) {
                try {
                    st.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    

    中文乱码 useUnicode=true&characterEncoding=utf-8

    url=jdbc:mysql://localhost:3306/mystore?useUnicode=true&characterEncoding=utf-8&rewriteBatchedStatements=true

    相关文章

      网友评论

          本文标题:jdbc 学习

          本文链接:https://www.haomeiwen.com/subject/sdqsfqtx.html