JDBC技术

JDBC

Java Database Connectivity

​ Java数据库连接技术,由一组java语言编写的类与接口组成,可以为多种关系型数据库提供统一访问。

作用:可以使用java语言操作数据库

JDBC中重要API

class java.sql.DriverManager
interface java.sql.Connection
interface java.sql.Statement
interface java.sql.ResultSet

JDBC开发步骤(重要)

public static void main(String[] args) {
        // 1、加载数据库驱动
        // 2、获取数据库连接
        // 3、准备SQL语句,通过preparedStatement发送SQL语句
        // 4、使用resultSet,接收返回来的结果集
        // 5、关闭资源(先开后关原则)
        ResultSet rs = null;
        Connection conn = null;
        PreparedStatement ps = null;
        try {
            Class.forName("oracle.jdbc.OracleDriver");
            conn = DriverManager.getConnection(
                    "jdbc:oracle:thin:@localhost:1521:xe", "hr", "hr");

            String sql = "select * from employees where rownum<=10";
            ps = conn.prepareStatement(sql);
            rs = ps.executeQuery();
            while (rs.next()) {
                System.out.println(rs.getString(1) + "\t" + rs.getString(2)
                        + "\t" + rs.getString(3));
            }
        } 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 (Exception e) {
                e.printStackTrace();
            }
        }
    }

补充

Statement:

Statement st = conn.createStatement();
int st.executeUpdate(sql); //执行增删改操作(有参)
ResultSet st.executeQuery(sql); //执行查询操作(有参)作为ResultSet的引入
//缺点:存在SQL注入的风险

PreparedStatement【重点】://继承Statement

  1. 编写参数化SQL:
String sql = "select * from account where cardId = ? and password = ?" ;
  1. 绑定动态参数:
ps.setInt(1,值);//参数位置从1开始
ps.setDouble(2,值);
ps.setString(3,值);
ps.setDate(4,值);
ps.setObject(5,值);
  1. 发送绑定参数后的SQL语句到Oracle数据库中:
int ps.executeUpdate(); //执行增删改操作(无参)
ResultSet ps.executeQuery(); //执行查询操作(无参)  作为ResultSet的引入
  1. 作用:发送预处理的SQL语句。

  2. 优势:防止SQL注入攻击,执行多个同构SQL的效率高。

  3. 预编译:

1). 验证用户访问权限。

2). 验证语法是否正确。

3). 计算访问计划(Access Plan)等效与Oracle的Map集合,将SQL语句一起缓存到内存中。首次比较耗时SQL=key/Plan = value

4). 通过SQL语句查找Oracle缓存的访问计划并执行。

扫描二维码关注公众号,回复: 3051557 查看本文章

JDBC进一步封装*(properties文件)

通过字节流读取配置文件jdbc.properties中的连接信息

public class JDBCUtil {
    private static final Properties prop = new Properties();
    static{
        try {
            InputStream is = new FileInputStream("bin\\jdbc.properties");
            prop.load(is);
            String driver = prop.getProperty("driver"); 
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection(){
        String url=prop.getProperty("url");
        String username=prop.getProperty("username");
        String password=prop.getProperty("password");
        try {
            return DriverManager.getConnection(url,username,password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void release(Connection conn,PreparedStatement ps,ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
            if(ps!=null){
                ps.close();
            }
            if(conn!=null){
                conn.close();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}
jdbc.properties
driver=oracle.jdbc.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:xe
username=jsk
password=jsk

JDBC封装(最终版)

事务控制

1、事务的边界:业务方法的首行–>整个方法结束(全部视为原子操作,要成功、都成功;要失败、都失败。)

2、手动控制事务:

I. 修改事务提交方案:conn.setAutoCommit(false);

II. conn.commit();

III. conn.rollback();

IV. trycatch final:异常的向上报告,连接对象的释放。

保证service(业务逻辑层与数据访问层使用同一个数据库的连接Connection):
通过ThreadLocal工具实现Connection与线程的绑定,通过JDBCUtil.getConnection()时,先判断线程中是否绑定了Connection,如果已经绑定则拿出此Connection使用;如果没有则重新获取新的Connection对象,并绑定到线程中。
注意:最后关闭Connection资源时,需要把线程中的Connection也移除
tl.remove();

代码示例

public class JDBCUtil {
    private static final Properties prop = new Properties();

    private static final ThreadLocal<Connection> tl = new ThreadLocal<Connection>();

    static{
        try {
            InputStream is = new FileInputStream("bin\\jdbc.properties");
            prop.load(is);
            String driver = prop.getProperty("driver");
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static Connection getConnection(){
        Connection conn = tl.get();
        if(conn==null){
            String url = prop.getProperty("url");
            String username = prop.getProperty("username");
            String password = prop.getProperty("password");
            try {
                conn = DriverManager.getConnection(url,username,password);
                tl.set(conn);
                return conn;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        return conn;

    }

    public static void release(Connection conn,PreparedStatement ps,ResultSet rs){
        try {
            if(rs!=null){
                rs.close();
            }
            if(ps!=null){
                ps.close();
            }
            if(conn!=null){
                conn.close();
                tl.remove();
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }
    }
}

总结

I. 线程工具类:可以在整个线程(单条执行路径)所持有的Map中,存储一个键(threadlocal)值(conn)。

II. 将参数对象(Connection conn)添加到当前线程中:

private static finalThreadLocal<Connection> tl = new ThreadLocal<Connection>(); //工具类

III. 修改getConnection方法:

Connection conn = tl.get(); //获取线程中保存的Connection对象

if(conn == null){ //当线程中没有保存过Connection对象时

    conn =DriverManager.getConnection(url, userName, password); //获取连接对象

    tl.set(conn); //并保存至线程中
}
return conn;

IV. 在release中关闭conn时,同时tl.remove(); //移除线程中的连接对象,只有业务提交或回滚之后才关闭、移除连接。

猜你喜欢

转载自blog.csdn.net/qq_38928944/article/details/79887445
今日推荐