jdbc 学习

2018-12-06  本文已影响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);

数据库连接池

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

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

连接池中的属性:

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

常见的数据库连接池有

获取方式不同:

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

上一篇 下一篇

猜你喜欢

热点阅读