资源介绍
jdbc:
1.数据库连接的方式:
ODBC:开放式数据库连接。
C语言实现的,提供语言和(基于SQL的)数据库进行交互的“一致性”的接口
JDBC:java版本的ODBC
JDBC连接数据库的步骤:
1.注册驱动(加载驱动):
注册的方式:
1.使用类加载器(使用反射的方式)
Class.forName(driverName);
2.实例化Driver
Driver driver =
new oracle.jdbc.driver.OracleDriver();
DriverManager.registerDriver(driver);
3.加虚拟机参数jdbc.drivers
-Djdbc.drivers=oracle.jdbc.driver.OracleDriver
4.从Jdk6.0以后要求,JDBC 4.0 Drivers 必须包括 META-INF/services/java.sql.Driver 文件,有了这个文件以后不需要在显示的使用Class.forName来进行驱动的注册
Oracle数据库进行连接的时候,使用的驱动类:
1.oracle.jdbc.driver.OracleDriver
2.oracle.jdbc.OracleDriver
2.建立连接
连接方式:
1.DriverManager(中的getConnection其实也是调用的Driver.connect方法)
getConnection(url);//没有用户名密码
//将用户名密码存放在java.util.Properties对象中
getConnection(url,properties);
getConnection(url,user,passwd);
2.直接调用Driver.connect方法执行
Driver d = new DriverClass();
d.connect(url,properties);
3.创建Statement:
Statement:
1.创建时不需要传递sql语句,但是执行时需要传递sql语句
2.如果涉及到动态参数的传递,必须使用字符串拼接
PreparedStatement:
1.创建时就需要传递sql语句,执行的时候不需要传递sql语句
2.如果涉及到动态参数的传递,可以使用字符串拼接,也可以使用?占位的形式
给?号传值使用的是
pstmt.setType(index,value);
index从1开始
3.提供预编译的功能,某种程度上可以避免sql注入的问题
4.提前做语法检查,在给?赋值的过程中要求数据类型一定要匹配,这样在某种程度上可以避免因为数据类型不匹配而发生的异常
CallableStatement:主要用来执行pl/sql的一些过程,函数等。
1.写一条恒成立的select语句,无论你输入的条件是什么,总是能讲表中的所有数据输出
select id,last_name
from s_emp
where '1' ='1'; where 1=1;
findByOption(Integer age,String province,String gender){
String sql = select * from s_emp where 1=1;
if(age!=null){
sql + "and age < age";
}
if(province!=null){
sql + "and province=province";
}
if(gender!=null){
sql + "and gender = gender";
}
}
4.执行sql语句:
execute:返回boolean类型的值,代表是否有结果集返回(如果执行select操作,是有ResultSet的,返回值为true)
executeUpdate:返回int类型的值,代表的是,操作执行完成后,受影响的数据库的行计数(针对于insert,update,delete)
executeQuery:返回的是ResultSet
ResultSet:类似于指针或者游标的东西,里边保存的不是所有的结果,而是指向结果集的正上方。所以如果一旦连接关闭那么ResultSet将取不到值
5.处理结果
如果有结果集,处理结果集
ResultSet
next(),每执行一次,向下移动一次,如果有值,返回true,如果没值返回false
while(rs.next()){
rs.getType(index/columnName);
如果传的是index,那么索引是从1开始的。
select id,last_name from s_emp;
那么1代表的就是id,依次类推
}
6.关闭资源
先开的后关
D:\oraclexe\app\oracle\product\10.2.0\server\jdbc\lib\ojdbc14.jar
linux下启动数据库监听的命令:
lsnrctl start;
"select id from s_emp where name = '"+name+"'";
table s_user(
id ,
name,
age)
class User{
}
//分别使用Statement对象和PreparedStatement对象实现
public class JDBCTest{
//查找s_user表中所有的数据,并且返回他们的集合
public Collection findAll(){
}
//按照名字进行删除
public int deleteUser(String name){
}
//将user对象的信息更新到数据库表中
public int updateUser(User user){
}
//讲User对象保存到数据库中
public void insertUser(User user){
}
}
JDBC:本身自动帮我做事务管理的操作
AutoCommit = true;
Connection.setAutoCommit(false);
正常:
conn.commit();
异常:
conn.rollback();
JDBC批处理:
addBatch
executeBatch
Statement
PreparedStatement
Statement{
1.获取连接 getConnection();
2.创建Statement conn.createStatement();
3.执行sql语句 String sql ....
insert delete update executeUpdate
select ----- Result executeQuery
4.如果有结果集处理结果集
5.资源关闭
}
Statement:
update/delete/insert:
stmtExecute(String sql){
1.获取连接 getConnection();
2.创建Statement conn.createStatement();
3.执行sql语句
stmt.execute(sql);
4.资源关闭
}
Select:
stmtQuery(String sql,ResultHander handler){
1.获取连接 getConnection();
2.创建Statement conn.createStatement();
3.执行sql语句
ResultSet set = executeQuery
4.如果有结果集处理结果集
handler!=null
handler.handler(set);
5.资源关闭
}
结果集处理的规则:
ResultHandler{
handler(ResultSet rs);
}
PreparedStatement
update/delete/insert:
pstmtExecute(String sql,PstmtSetter setter){
1.获取连接 getConnection();
2.创建PreparedStatement conn.prepareStatement(sql);
if(setter!=null){
setter.setter(pstmt);
}
3.执行sql语句
pstmt.execute(sql);
4.资源关闭
}
?设值的标准:
PstmtSetter{
setter(PreparedStatement pstmt);
}
Select:
stmtQuery(String sql,PstmtSetter setter,ResultHander handler){
1.获取连接 getConnection();
2.创建PreparedStatement conn.prepareStatement();
setter!=null
setter.setter(pstmt);
3.执行sql语句
ResultSet set = executeQuery
4.如果有结果集处理结果集
handler!=null
handler.handler(set);
5.资源关闭
}
结果集处理的规则:
ResultHandler{
handler(ResultSet rs);
}
表现层
业务逻辑层
持久层
java中的对象分为:
1.域对象:主要作为信息的载体
2.行为对象:注重操作
Register(User user){
}
insert(User user){
String sql = "insert into s_user(
user.getId()+user.getName().......)";
}
insert(User user){
save(user);
}
ORM
Object Relational
Class-Object 表
名字 表名
属性 字段(列)
object 记录
User s_User
id id
name name
passwd passwd
insert into s_user(id,name,passwd)
values(?,?,?);
Hibernate:ORM的中间件,或者说是实现了ORM的一个框架,对JDBC做了轻量级的封装。
ORM:使用元数据信息来描述对象和数据库之间的关系,并且能够自动实现java中持久化对象到关系型数据库中表的映射
脏检查:自动对缓存中的数据进行检查,并且选择在合适的时机和数据库之间进行交互,以保持数据的一致性
延迟加载:从数据库中还原对象的时候,不会立即对对象进行初始化,而是等到用到的时候才会进行初始化
Core:
POJO
hibernate.cfg.xml
.hbm.xml
Session:
1.轻量级的,创建和销毁不需要消耗很大的资源
2.非线程安全的
3.hibernate的一级缓存
4.介于Connection和Transaction之间的一个对象
5.hibernate中用来做持久化操作的
SessionFactory
1.重量级的,创建和销毁需要消耗很大的资源,不建议频繁创建和销毁
2.线程安全的,一个数据库对应一个Sessionfactory(一般一个应用程序对应一个SessionFactory就够了)
3.是一个很大的缓存,本身维护了一个可配置的二级缓存
4.用来构建Session对象
Configuration
1.启动和配置Hibernate
2.读取hibernate的配置文件和映射文件
3.构建SessionFactory对象
Transaction
1.事务管理对象
Query
1.查询对象,HQL
Criteria
1.hibernate提供的更面向对象的一种查询方式。
准备工作:
1.java中的POJO对象存在
2.数据库,表得存在
3.hibernate的配置文件(hibernate.cfg.xml)得存在
4.POJO.hbm.xml文件存在
5.hibernate的jar包以及数据库的驱动包存在
Hibernate的编程:
1.构建Configuration对象读取配置文件
2.读取映射文件
3.构建SessionFactory对象
4.构建Session对象
5.开启事务
6.持久化操作
7.事务的提交(正常提交,不正常回滚)
8.关闭资源
主键增长策略:
1.increment:自动增长
select max(id) from table;
找到最大值之后+1赋给要持久化的对象
2.assigned:指派
hibernate不在自动生成主键值,需要你在插入时自己指明
3.hilo:高低值算法,由数据库表提供高值,程序提供低值
value = hi*(max_lo+1)+lo
4.sequences
Cat:
cid
name
color
weight
age
---------------------------
1.每个人都有一个地址
person{
id
name
}
Address{
country
province
city
street
}
table:
id
name
country
province
city
street
Component:数据库中采用一张表的设计,java中采用两个类的设计
-----------------------------------
Employee:
id
name
salary
award
amount
table
id
name
salary
award
formula:
----------------------------
关系模型:
多对一:
订单和客户之间的关系
Order{
id
amount
customer
}
Customer{
id
name
}
many-to-one:标签中对于cascade的取值delete,delete-orphan,all-delete-orphan(只用unique属性值不为true不能出现)慎用
cascade:级联属性
none:不做任何级联操作
save-update:对当前对象执行save,update,
saveOrupdate,会级联操作和它相关联的对象
delete:在删除当前对象的时候,级联删除和他相关联的对象
all: save-update+delete
delete-orphan:解除关联关系时,删除和当前对象失去关联的对象
all-delete-orphan:all+delete-orphan
单向的一对多的关系,在进行关联关系的操作时,会执行不必要的update语句,所以,一般情况下,我们不会做单向一对多的映射。
inverse="true":让其中一方放弃对关联关系的维护
一般在做双向多对一(一对多)关联关系映射的时候,一般会设置让一的一方放弃对关联关系的维护,以减少不必要的更新语句
一对一:
基于外键的一对一
Wife Husband
id id
name name
h_id references Husband(id) unique
基于主键的一对一
Wife Husband
id references Husband(id) id
name name
create table Husband(
id number primary key,
name varchar2(15)
);
create table Wife(
id number primary key references husband(id),
name varchar2(15)
);
多对多:
Teacher Student
id id
name name
桥表:s_t
s_id
t_id
------------------------------
操作持久化对象:
Hibernate中对象的三种状态:
Transient(瞬态):
1.由new关键字创建
2.没有和Session进行关联的
3.数据库中没有对应的记录存在
4.操作不会影响数据库中的数据
Persistent(持久态):
1.和Session之间有关联
2.在数据库中有对应记录存在,并且有持久化标识
3.对持久对象的更动,会对数据库中的数据产生影响。(自动脏检查机制)
Detached(托管状态):
1.和Session失去关联
2.数据库中有对应记录存在
3.对托管对象的更动,在托管期间不会影响数据库,但是将托管状态重新和数据库进行关联的时候会将托管对象重新变为持久态,那么在托管期间发生的更动也会被更新到数据库中
get()/load():从数据库中还原数据
get:
1.先从缓存中进行查找,如果找到就直接返回
2.如果找不到,get()会立即发送sql语句到数据库中查找数据,如果找到就返回,如果找不到返回null;
load:(使用延迟加载策略)
1.load()方法默认要加载的对象一定存在,所以很放心的使用代理对象,等到用到的时候从缓存中查找数据,如果找到,就返回,找不到发送sql语句到数据库中查找,如果数据库中没有对应记录存在,抛ObjectNotFoundException
Hibernate中的查询:
1.OID检索:
get
load
2.导航对象图查询:
Customer ---- Order之间有对应关系
通过检索到Customer以后,想获取和Customer相关的对象,可以使用
cus.getOrders();
3.HQL:
Query
sql:
select name from t_cus;
hql:
select name from hiber.many2one.Customer
query.list();
直接发送一条select语句去表中查找所有的属性
query.iterate();
先发送一条select语句从表中查找所有的id,然后根据id从缓存中进行查找,找到就返回,找不到再发送sql语句按id从数据库中进行查找,所以可能会产生N+1的问题
Customer order
select
from customer order
where customer.id=order.c_id;
4.QBC(Query By Criteria)
Criteria
Restrictions
Order
Projections
QBE(Query By Example)
5.sql
A B 总额 《 4000 - 100
1900 2100
900
Session默认在遇到以下情况的时候会flush:
1.事务提交的时候
2.某些查询操作执行的时候(不是所有的查询)
3.当应用程序显示的调用session.flush操作的时候
悲观锁:
LockMode
LockMode.UPGRADE:借助于数据库的
select ... for update;
那么事务一定会等到上一个获取了锁的事务commit之后才执行,如果上一个事务一直不提交,那么它就一直等下去
LockMode.UPGRADE_NOWAIT:
select ... for update nowait;
nowait就是不等待,一旦在操作过程中发现要操作的数据被加了锁,那么直接抛
ORA-00054: 资源正忙, 但指定以 NOWAIT 方式获取资源
乐观锁:
版本控制(version)
时间戳(timestamp)
- 上一篇: java的JDBC扩展包(jar包)
- 下一篇: SqlJDBC3.0和4.0