二、JDBC

JDBC

  • Java DataBase Connectivity —> Java数据库连接技术
  • Java语言连接数据库的方式有两种
    • JDBC直接连接数据库
    • JDBC和数据库连接池的配合
  • 不同数据库在使用存在差异,用JDBC技术依靠接口提供了连接数据库的标准和规范 —> JDBC中提供了一套通用的访问数据库的接口,可以通过JDBC技术连接不同的数据库
  • JDBC包含两部分
    • 接口:sun公司提供,位于jdk中的 java.sql 和 javax.sql 包中
    • 实现类:数据库厂商提供,用于实际具体的的连接操作数据库的功能,以 jar 包的形式提供
      • ojdbc5.jar:适用于 jdbc6.0
      • ojdbc6.jar:适用于 jdbc7.0及以上
  • JDBC常见API
    • java.sql.Connection:获取数据库的连接,只有获取到Connection连接对象时才能访问数据库
    • java.sql.PreparedStatement:获取发送SQL的工具,使用方法实现发送功能
    • java.sql.ResultSet:接收数据库查询之后返回的数据结果
    • java.sql.Driver:驱动类,不同的数据库使用方式不同,所以不同的数据库厂商提供对应的驱动类,Oracle的驱动类为OracleDriver
    • java.sql.DriverManager:管理不同数据库的驱动类
JDBC开发步骤
  • 加载驱动 —> 通过反射让 JVM 加载驱动类 . class文件(类加载)

    • Class.froName(“oracle.jdbc.OracleDriver”)
  • 获取连接

    • Connection conn = DriverManager.getConnection(“连接数据库字符串”,“连接数据库账号”,“密码”);
    • 连接数据库的字符串:jdbc:oracle:thin:@localhost:1521:xe
    • 协议:子协议:子协议(轻量级):@ip地址:端口号:数据库的sid(名)
  • 发送SQL工具,同时准备SQL语句

  • PreparedStatement pstm = conn.prepareStatement(sql);

  • 往数据库服务端发送SQL

    • int n = pstm.executeUpdate();

      —> 发送insert、delete、update语句,返回值代表影响数据库数据的行数

    • ResultSet rs = pstm.executeQuery();

      —> 发送select语句,返回值代表从数据库服务端返回的查询结果

  • 处理结果集 —> 执行 select 查询语句时应用

    • rs.next():让游标移动一行数据,用于判断当前行是否有数据,有true,反之false
    • 从ResultSet中获取数据
      • rs.getXxx():根据当前行的字段数据类型来获取对应字段的数据,返回值为对应的数据类型
      • 获取某一字段数据时,可以通过字段名或是字段编号指定获取哪一个列数据
      • 位置编号从1开始
    数据库Java数据库Java
    number(10)rs.getInt(字段名 / 位置)Varchar2/charrs.getString(字段名 / 位置)
    number(10,2)re.getDouble(字段名 / 位置)to_date
  • 释放资源 —> 先开启的资源后关闭

PreparedStatement
  • preparedStatement允许使用 ? 占位,但 ? 仅代表数据、数值,不能为字段名占位
  • 在executeQuery提交之前,给占位符赋值,赋值方法为pstm.setXxx ( 位置,value ) ;
  • 动态参数中常用的日期类型
    • 字符串类型的日期
      • 用户通过操作平台或客户端输入的日期,为String类型的日期,如1024-10-24
      • String类型的日期需要借助java.util.Date转换成java.sql.Date
    • java.sql.Date
      • 专门用于对数据库中的日期进行操作(增删改查)
    • java.util.Date —> java.sql.Date 的父类
      • 在Java类中定义日期的属性通常为java.util.Date类型
//日期转换
String strDate = "2020-9-19";
//从String到java.sql.Date  进行插入、修改操作时应用
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("yyyy-MM-dd");//月份为大写M
java.util.Date utilDate = sdf.parse(strDate);
java.sql.Date sqlDate = new java.sql.Date(utilDate.getTime());

//查询操作时,将java.sql.Date的数据存储在java.util.Date无需转换,利用多态即可
类加载流
  • public InputStream getResoutceAsStream(String name)
  • Properties中load(输入流),将输入流指向的文件内容以key-value形式加载到Properties中,自动以 = 分割,左边为key,右边value
  • getProperty(key):根据键获取值
ORM —> Object Relational Mapping
  • 对象关系映射
  • Java-Object对象 与 Oracle-表中数据 —>Java对象和表中一行数据的对应关系
  • 即为实体类
    • 实体类类名通常和表名相同
    • 实体类中的属性个数、数据类型取决于表中的字段个数和数据类型
    • 提供有参无参构造方法(无参构造方法是使用反射获取对象时默认的构造方法)
    • 提供公开get、set方法,有选择的覆盖toString
    • 实现Serializable接口,为对象序列化做准备
DAO —> Date Access Object
  • 数据库访问层,直接操作数据库的类
  • 对表中数据进行增删改查操作,即对同一张表中的相关操作,封装在同一个类中,体现为不同的方法
  • 通常命名为表名+Dao
Service —> 业务层
  • 为用户的需求提供一个功能服务,通常由对Dao方法的一次调用或是多次调用组成
  • 业务类:专注于对用户的需求进行处理,每一个业务对应一个功能方法
    • 命名:根据业务望文生义即可;如BankService
    • 必须保证业务的正确性,需要严格的控制事务
  • 业务层异常处理:根据业务需求可以定义一些自定义异常类
    • 在业务层需要的地方抛出即可
View —> 视图层
JDBC中事务控制API
  • JDBC中,执行完一条sql,自动提交事务
  • Connection事务相关的方法
    • conn.setAutoCommit(false); //将事务提交设置为手动,参数给true为自动提交
    • conn.commit(); //提交事务
    • conn.rollback(); //事务回滚
  • 业务方法步骤总结
    • 通过JDBCUtil工具类获取连接
    • 将事务设置为手动提交
    • 调用dao中的方法实现业务
    • 提交事务 / 回滚
    • 释放资源
ThreadLocal
  • 位于java.lang包中的类,当前线程的局部空间
    • 保证同一个线程中获取的同一个ThreadLocal对象存储的始终为同一个值
    • 不同的线程中获取不同的值
    • 在 JDBC技术中,利用ThreadLocal保证同一个线程获取相同的数据库连接,不同的线程获取不同的连接
  • 常见的API应用
    • ThreadLocal<数据类型> tl = new ThreadLocal<>(); 是一个泛型类,在局部空间存储T类型的数据
    • tl.set(数据); 存储数据,数据类型取决于ThreadLocal泛型类型
    • 数据类型 变量名 = tl.get(); 获取数据
    • tl.remove(); 移除当前线程局部变量对应的数据
ThreadLocal底层实现
线程 ---局部空间(ThreadLocalMap)
  			key(ThreadLocal)   value(Object)
  				tl									值


public void set(T value){
  Thread t = Thread.currentThread();  //获取当前线程对象
  ThreadLocalMap map = getMap(t);	 
  if(map != null)
    map.set(this,value);	//当前对象ThreadLocal(tl)作为键,给的对象作为值
  												//若key相同,则新的对象覆盖旧对象
  else
    createMap(t,value);
}

public T get(){
  Thread t = Thread.currentThread();
  ThreadLocalMap map = getMap(t);
  if(map != null){
    ThreadLocalMap.Entry e = map.getEntry(this);
    if(e != null)
      return (T)e.value;
  }
  return setInitialValue();
}
三层架构 —> 分包分层开发
  • Dao层:数据库访问层,专注于数据库的增删改查操作
  • Service层:业务层,专注于实现用户的业务需求,必须控制事务
  • View层:视图层,专注于输入、输出界面
  • 优点
    • 各司其职,解耦合
    • 利于团队的协同开发
  • 分包结构
conf包
  • 配置文件

    • 文件名 . properties
    • 存储的形式为:name-value
    • 配置文件中,没有空格、分号等
  • Properties

    • Map的实现类,存储的方式为Key-value,键值对默认为String

    • 使用静态代码块会先导致类加载,使用类加载流:

      InputStream in = JDBCUtil.class.getResourceAsStream("/com/hang/conf/db.properties"),

      然后 pro.load(in) 获取配置文件中数据

异常总结
  • java.lang.ClassNotFoundExeception
    • Class.forName 中类名写错
    • 导包只是拷贝没有完成build path
  • java.sql.SQLSyntaxErrorException
    • SQL语法错误异常,检查sql 语句是否正确
  • oracle.net.ns.NetException
    • Oracle核心服务是否正常启动
  • java.sql.SQLException:
    • java.sql.SQLException:No suitable driver found for jdbc:oracle:thin:@localhost:1521:xe
      • url 中 jdbc或oracle写错
    • java.sql.SQLException:指定了无效的Oracle URL
      • 没有写thin
    • java.sql.SQLException:The Network Adapter could not establish the connection
      • ip 地址写错或端口号写错
    • java.sql.SQLException:Invalid number format for port number
      • 端口号中出现字母
    • java.sql.SQLException:Listener refused the connection
      • Oracle 的 sid 数据库名字写错:xe
    • java.sql.SQLException:ORA-01017:invalid username/password;logon denied
      • 连接数据库的用户名或密码错误
  • java.lang.NullPointerException
    • 没有提交 conn.prepareStatement(sql) 语句
  • java.sql.SQLRecoverableException:关闭的连接
    • 使用的Connection被DAO提前关闭,Service再次调用导致
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值