8_9.JDBC_1

1. JDBC:

1.1 ODBC: 桥链接: ODBC是微软的。 通过桥连接链接数据库

– ip:1521/实例名 用户名 密码

– ip:服务名a1

1.2 JDBC: Java database connect: java代码链接数据

  1. 加载驱动

    • 基本不用了jdk升级后 读取jar文件中配置
  2. 获取链接

    1. url是数据库厂商规定的协议
  3. 获取执行器

    1. Statement原始

    2. PreparedStatement: 预处理执行,是Statment子类:

      1. 类型转换问题
      2. 防注入
    3. CallableStatment: 存储过程调用执行器 CallableStatement extends PreparedStatement {

                  // 3. 创建执行器Statement
                  // 1) sql提前 2) 预处理 预在?自动类型转换
                  int empno = 7369;
                  String ename = "SMITH";
      
                  LocalDateTime ld = LocalDateTime.of(1980, 12, 17, 0, 0, 0);
      
                  java.sql.Date d = new java.sql.Date(ld.atZone(ZoneId.of("America/Los_Angeles")).toInstant().toEpochMilli());
                  String sql = "select * from emp where empno = ? and ename = ? and hiredate = ?";
                  PreparedStatement ps = conn.prepareStatement(sql);
                  ps.setInt(1, empno); // 填充第一问号 是int
                  ps.setString(2, ename);  // 填充第二问号 是String
                  ps.setDate(3, d);
                  // 4. 执行sql,处理结果
                  // 3)sql提前,无参数
                  ResultSet rs = ps.executeQuery();
      
  4. 执行sql,处理结果

    1. ResultSet 对象。 理解成游标-fetch指向新的一行。 resultset.next();指向下一行。

      1. rs.get类型(int 第几列) 获取value
      2. rs.get类型(String 列名) 获取value
       ResultSet rs = st.executeQuery(sql);
                  while (rs.next()) { // 判断有没有,并且指向下一行
                      System.out.print(rs.getInt(1) + "\t");
                      System.out.print(rs.getString(2)+ "\t");
                      System.out.print(rs.getString(3)+ "\t"); // 第几列
                      System.out.print(rs.getInt("mgr")+ "\t"); // 列名
                      System.out.print(rs.getDate("hiredate")+ "\t"); // 列名
                      System.out.println();
                  }
      
      
  5. 释放资源


        Connection conn = null;
        try {
            // 1. 加载驱动
            Class.forName("oracle.jdbc.OracleDriver"); // 驱动类的类全名

            // 2. 创建链接
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "123456");

            // 3. 创建执行器Statement
            Statement st = conn.createStatement();

            // 4. 执行sql,处理结果
            String sql = "select * from emp";
            ResultSet rs = st.executeQuery(sql);
            while (rs.next()) {
                System.out.print(rs.getInt(1) + "\t");
                System.out.print(rs.getString(2)+ "\t");
                System.out.print(rs.getString(3)+ "\t"); // 第几列
                System.out.print(rs.getInt("mgr")+ "\t"); // 列名
                System.out.print(rs.getDate("hiredate")+ "\t"); // 列名
                System.out.println();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
            System.out.println("驱动加载错误");
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            System.out.println(throwables.getMessage());
        } finally {
            // 5.释放资源
            if (conn != null) {
                try {
                    conn.close();
                } catch (SQLException throwables) {
                    throwables.printStackTrace();
                }
            }
        }


2. JDBC查询应用

2. 1 综合查询问题!

select *
from emp
where 1 = 1
if empno != null && !"".equals(empno)
	and empno = ? 
if ename != null && !"".equals(ename)
	and ename = ? 
if deptno != null && !"".equals(deptno)
	and deptno = ?;

3. CUD:

更新为例:

update emp set ename = ? where empno = ?;

{

        Connection conn = null;
        try {
            // 1. 加载驱动
            Class.forName("oracle.jdbc.OracleDriver");
            // 2。創建鏈接
            conn = DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:orcl", "scott", "123456");
            conn.setAutoCommit(false); // 激活事务
            // 3. 创建Statement
            StringBuilder sb = new StringBuilder();
            sb.append("  update  emp set ename = ? where empno = ? ");
            PreparedStatement ps = conn.prepareStatement(sb.toString());

            // 给?号赋值
            ps.setString(1, "TOM4");
            ps.setInt(2, 7369);

            // 4. 执行SQL,处理结果※
            // 修改了几行数据
            int result = ps.executeUpdate(); // executeQuery用于查询  executeUpdate()CUD操作
            if (result != 1) {
                conn.rollback();
                throw new Exception("和預想結果不一樣,更新失敗");
            }
            ps = conn.prepareStatement("insert into EMP_BAK1 select * from emp where empno = ?");
            ps.setInt(1, 7369);
            result = ps.executeUpdate(); // executeQuery用于查询  executeUpdate()CUD操作
            if (result != 1) {
                conn.rollback();
                throw new Exception("和預想結果不一樣,插入備份失敗");
            }

            conn.commit();
        } catch (SQLException throwables) {
            throwables.printStackTrace();
            try {
                conn.rollback(); // 判断某种异常要回滚
            } catch (SQLException e) {
                e.printStackTrace();
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } finally {
            try {
                conn.close();
            } catch (SQLException throwables) {
                throwables.printStackTrace();
            }
        }

    }

4. 乐观锁与悲观锁(排他制御-乐观排他,悲观排他)

  • 乐观锁:通过技术手段例如:数据表中加版本号或时间戳

  • 悲观锁:通过行级锁解决。–

  • 开发时: 乐观锁+悲观锁

    select * from 表。。。。。 for update
    for update就是行级锁
    
  • 乐观锁:通过技术手段例如:数据表中加版本号或时间戳

  • 悲观锁:通过行级锁解决。–

  • 开发时: 乐观锁+悲观锁

    select * from 表。。。。。 for update
    for update就是行级锁
    
posted @ 2021-05-16 11:36  剑心空明  阅读(6)  评论(0编辑  收藏  举报  来源