JDBC:OJDBC

#JDBC

Java Database Connectivity:Java访问数据库的解决方案。
SUN公司编写了JDBC定义了一套标准接口,即访问数据库的通用API,不同的数据库厂商根据各自数据库的特点去实现这些接口。

#properties也是一种配置文件

  • 如db.properties的文件内容如下:
#database connection parameters
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@localhost:1521:orcl
user=lhh
pwd=1234
  • 读取它的方法
Properties p = new Properties();
p.load(DBTool.class.getClassLoader().getResourceAsStream("db.properties"))
String driver = p.getProperty("driver");
url = p.getProperty("url");
user = p.getProperty("user");
pwd = p.getProperty("pwd");

#JDBC的工作流程
这里写图片描述

##获取连接的两种方法
###DriverManager

Class.forName("oracle.jdbc.OracleDriver")
//根据url连接参数,找到与之匹配的Driver对象,调用其方法获取连接
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:@192.168.0.26:1521:orcl",
"用户名","密码");
  • 直接使用DriverManager的问题
  • 它没有管理连接上限,并发量大时很容易导致数据库崩溃每次调用它,它都创建新连接,而不是复用连接,效率低
    ###连接池/数据源
  • BasicDataSourcedataSource
private static BasicDataSource dataSource = new BasicDataSource();
//加载参数
dataSource.setDriverClassName(driveClassName);
dataSource.setUrl(url);
dataSource.setUsername(username);
dataSource.setPassword(password);
String initSize = p.getProperty("init_size");
String maxSize = p.getProperty("max_size");
//获得连接
Connection conn = dataSource.getConnection();
  • 连接池可以解决的问题
    它能管理连接上限,避免数据库崩溃
    它可以让我们复用连接,提高效率

  • 有哪些常用连接池?
    DBCP
    C3P0
    ##两种不同的语句对象Statement和PreparedStatement
    ###Statement

Statement适合执行静态(无条件)SQL

  • 图解:
    这里写图片描述
  • 使用
    Statement smt = conn.createStatement();
    String sql = “insert into emps values(”
    + “emps_seq.nextval,‘唐僧’,‘总监’,0”
    + “,sysdate,8000.0,6000.0,2)”;
    //返回sql所能影响(增删改)的行数
    //该方法在执行完sql后会自动commit
    int rows = smt.executeUpdate(sql);
    System.out.println(rows);
    ###PreparedStatement

PreparedStatement适合执行动态(有条件)SQL会进行预编译。

  • 图解
    这里写图片描述

  • 使用:

           conn = DBUtil.getConnection();
			//创建ps对象,并让它立刻发送SQL
			String sql = "select * from emps where empno=?";
			PreparedStatement ps = conn.prepareStatement(sql);
			//给?赋值
			//ps.set类型(?的序号,?的值)
			ps.setInt(1, empno);
			//发送条件,执行SQL
			ResultSet rs = ps.executeQuery();
			while(rs.next()) {
				System.out.println(rs.getString("ename"));
				System.out.println(rs.getDouble("sal"));
			}

##ResultSet

  • 结果集的指针
    这里写图片描述
    ###结果集元数据ResultSetMetaData

结果集元数据:对结果集进行描述(概括)的数据
包含:多少列,列名,列的类型

conn = DBUtil.getConnection();
String sql = "select * from emps order by empno";
Statement smt = conn.createStatement();
ResultSet rs = smt.executeQuery(sql);
//获取结果集元数据
ResultSetMetaData md = rs.getMetaData();
System.out.println(md.getColumnCount());
System.out.println(md.getColumnName(1));
System.out.println(md.getColumnTypeName(1));

#JDBC中的事务管理

  1. 自动管理事务
  • JDBC会自动管理事务
  • 每次调用executeUpdate()时,它会自动commit
  • 一个业务只需执行一次DML时,采用自动管理事务
  1. 手动管理事务
  • 取消自动提交:conn.setAutoCommit(false)
  • 采用手动提交:conn.commit()
  • 异常时要回滚:conn.rollback()
    一个业务需要执行多次DML时,采用手动管理事务
  1. 什么是事务?
  • 满足如下规则的数据库访问叫事务
    原子性:事务是一个完整的过程,要么都成功,要么都失败.
    一致性:事务前后的数据要保持一致,即收支平衡.
    隔离性:事务访问过程中的数据,不能被别人访问.
    持久性:事务一旦完成,就永久生效.
    要整体的看待事务的概念,不要割裂来理解.
    #批量添加
  1. 使用场景
    在企业软件上线时,导入原始数据,则需要进行批量添加.
  2. 如何实现
    这里写图片描述
try {
			conn = DBUtil.getConnection();
			conn.setAutoCommit(false);
			String sql = "insert into emps values("
				+ "emps_seq.nextval,?,?,?,?,?,?,?)";
			PreparedStatement ps = conn.prepareStatement(sql);
			for(int i=1;i<=108;i++) {
				ps.setString(1, "好汉"+i);
				ps.setString(2, "打劫");
				//省略5行
				//将此数据暂存到ps对象上
				ps.addBatch();
				if(i%50==0) {
					//将ps上暂存的50条数据发送给数据库
					ps.executeBatch();
					//将ps上暂存的数据清空,以便下一轮发送
					ps.clearBatch();
				}
			}
			//为避免有零头数据,再单独发送一次
			ps.executeBatch();
			conn.commit();

#获取自动生成的主键

  • 使用场景
    在增加主外键对应的2张表的数据时,需要获得主表自动生成的主键.
    这里写图片描述

  • 使用:

//给新增加的部门添加一个员工
conn = DBUtil.getConnection();
conn.setAutoCommit(false);
//增加部门
String sql = "insert into depts values("+ "depts_seq.nextval,?,?)";
//参数2是一个字符串数组,内含主键字段名,
//即告诉ps希望它返回哪个主键字段的值.
PreparedStatement ps = conn.prepareStatement(sql, new String[]{"deptno"});
ps.setString(1, dname);
ps.setString(2, loc);
ps.executeUpdate();
			
//从ps中获得生成的主键的值
ResultSet rs = ps.getGeneratedKeys();
rs.next();
//获取主键值时不能通过字段名获取
int deptno = rs.getInt(1);
			
//增加员工
sql = "insert into emps values("+ "emps_seq.nextval,?,?,?,?,?,?,?)";
ps = conn.prepareStatement(sql);
ps.setString(1, ename);
//省略
conn.commit();

#DAO
这里写图片描述

#JDBC支持如下的日期类型

  • java.sql.Date 年月日
  • java.sql.Time 时分秒
  • java.sql.Timestamp 完整日期
    上述日期都是java.util.Date的子类
    #JavaBean?
  • 满足如下规范的类
  1. 该类必须有包
  2. 该类必须有无参构造器
  3. 该类必须实现序列化接口
  4. 该类通常有get和set方法
  • 4
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值