📄 复习3.txt
字号:
hibernate
1、作用:
O/R Mapping
将工作量降底95%
2、核心配置文件
hibernate.cfg.xml:数据库的连接、 批量处理、加载二级缓存驱动、显示sql
*.hbm.xml:将一个表与类相映射、二级缓存的方式
3、核心接口及类
类:
Configuration:读取hibernate.cfg.xml及*.hbm.xml文件
接口:
SessionFactory:产生具体的session
Session:做具体的操作
save
update
saveOrUpdate:有主键修改,没主键增加
delete
load
Transaction :事务处理
Transaction trans=session.beginTransaction();
trans.commit();
trans.rollback();
Query:执行查询
//hql,类及属性是对象
Query query=session.createQuery("from Customer where customerid=:aa")
query.setString("aa","aa")
List list=query.list();
Validator:在做之前进行拦截,在处理之前进行校验
Lifecycle:拦截器,可以增加、修改、查询等之前触发,但其让数据类与
hibernate的藕合度增加,一般不用。
public class Users implements Validator,Lifecycle
{
}
interceptor:拦截器,其比Lifecycle更加的优秀,不用每个数据类去实现一些
接口,而是在产生session时将其注入到session中。
其可以增加、修改、查询等之前触发,但其中的session不可以重用,
可以用上一个session的connection,不用管事务,因为事务已被
前一个session实现。
4、关联:
one-to-many
get/set方法
一方通过get方法可以取出另一方,另一方也可以通过get方法取出对方,
所以在one这边有一个Set属性可以得到所有的many,many这边有一个One类型
的属性可以取出one
inverse:主控方,维护外键值,说明外键列由谁来控制,要想维护外键列的值
必须将被控方作为主控方的属性,主控方一般在many方。
inverse=false 是主控方,外键是由它控制的
inverse=true 是被控方,外键与它没关系
cascade:级联,要想实现级联必须将从对象作为主对象的属性。
主表增从表增
主表修从表修
主表删从表删
lazy:延迟
lazy=false:不但取当前对象,还取其关联的所有内容
lazy=true:只取当前对象不取关联对象的属性,当真正
用到对方属性时才执行sql加载相应的值
4、批量删除
Query query=session.createQuery("update"或"delete");
query.executeUpdate();
不同步缓存
5、Tomcat连接池:
在容器中预先产生了n个连接实例,客户端不用重新实例化,可以直接取
用完后还可以放回去。
1、 将sql-server三个包拷贝到C:\tomcat-6\lib下目录下
2、修改C:/tomcat-6/conf/context.xml为以下内容
<Context path="/chap0" docBase="chap0"
debug="5" reloadable="true" crossContext="true">
<Resource name="jdbc/sqlserver" auth="Container" type="javax.sql.DataSource"
maxActive="100" maxIdle="30" maxWait="10000"
username="sa" password="" driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
url="jdbc:microsoft:sqlserver://localhost:1433;databaseName=pubs;selectMethod=cursor"/>
</Context>
jdbc测试代码
Context initCtx = new InitialContext();
//进入连接池环境
Context envCtx = (Context)initCtx.lookup("java:comp/env");
//得到一个连接池
ds = (DataSource)envCtx.lookup("jdbc/sa");
//得到连接
Connection conn = ds.getConnection();
hibernate通过连接池实现连接
<session-factory name="foo">
<property name="connection.datasource">java:comp/env/jdbc/sa</property> <!--指定tomcat连接池-->
<property name="show_sql">true</property> <!--是否显示sql-->
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property> <!--hibernate的驱动管理器-->
<mapping resource="com/accp/t15/Customer.hbm.xml"/>
</session-factory>
spring调用tomcat中的连接池
<bean id="dataSource" class="org.springframework.jndi.JndiObjectFactoryBean">
<property name="jndiName">
<value>java:comp/env/jdbc/name</value>
</property>
</bean>
6、hibernate中的主键生成机制:
1) Assigned:手动给定
5) identity:sqlserver、db2、mySql的自动增加
6) sequence:oracle的序列
7) native:自动选择identity、sequence,不用手动给定
8) uuid.hex:Hibernate基于128位唯一值产生算法生成16 进制数值
7、数据库开发的过程
外模型
以客户为中心,客户可以看懂。
概念模型
以外模型作为输入,适应开发的进一步细化,是外模型全集
注意事项:
符合需求
速度
冗余
开发的难度
内模型
数据库
8、e-r图设计的过程
找实体
拉关系
写属性
9、三级范式
主键
projectID projectName empID empName 职务 小时工资 工时
完全依赖于主键
--project
projectID projectName
--emp
empID empName 职务 小时工资
--工时
工时 projectID empID
不出现传递依赖
--project
projectID projectName
--emp
empID empName 职务
--工时
工时 projectID empID
--职务
职务 小时工资
10.对象的三大状态
自由(transient)
与session无关
持久(persistent)
由session来管理
在持久状态中通过get方法取出对方
游离(detached)
被session抛弃
11、没有锁出现的问题
1、脏读:一个事务处理的数据是另一个事务没有提交的数据
2、覆盖更新:一个事务将另一个事务的修改覆盖了。
3、不可重复读:一个事务两个相同的sql读取出来的内容不一样。
4、幻想读:同一个事务第一次读有,第二次读没有。
12、锁的分类
1、读未提交:可以读取未提交的数据,不可以防止脏读、覆盖更新。
2、读已提交(数据库默认的处理方式):读取的数据是已提交的,在提交之前当前行的版本与数据
库的版本比较,若小于数据库的版本报错回退。
乐观锁:一个游标读取一批数据后不加锁,
另一个事务可以更新游标中的数据,
但游标所在事务更新另一事务更新过的行时,
报错,回退。
系统运行效率快。
悲观锁:一个游标读取一批数据后加锁,
另一个事务不可以更新游标中的数据,
但游标所在事务的更新一定成功。
系统运行效率慢。
3、可重复读:将上一个sql取的数据临时存储,保证同一个事务内下一个
sql与上一个sql取的数据一样。
4、串行化:一个事对表进行select、update、delete、insert时
全表加锁,另一个事只可以select不可update、delete、
insert。
速度最慢。
13、hibbernate的缓存有几种
1、事务级(一级缓存 session):当前事务结束缓存结束。
2、应用级(二级缓存 SessionFactory):所有session共享同一个SessionFactory
的数据。要人为让SesionFactory是单例模式。
3、集群(有多个应用服务器):每一台主机有一个SessionFactory,
一个服务器的数据发生改变要通知其它所有服务器
同步缓存数据或删除缓存数据,如果删除,下次取
时再从数据库中取。集群级缓存要慎用,因为有主
机之间有通信,要有socket连接,要同步数据增加网络
流通量及系统开销。
14、利用缓存的原则
数据量在可接收的范围内
更新或并发更新少
重复查询且使用率高的数据
15、缓存的实现
1、hibernate提供了支持缓存的接口,通过修改
hibernate.cfg.xml设置缓存。
2、将ehcache.jar拷入工程
3、要src的根目录下加入ehcache.xml说明缓存。
<ehcache xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="ehcache.xsd">
<defaultCache
maxElementsInMemory="10000"
eternal="false"
timeToIdleSeconds="120"
timeToLiveSeconds="120"
overflowToDisk="true"
/>
</ehcache>
3、在hibernate.cfg.xml中加入两个属性
a、说明提供二级缓存驱动类
b、说明query也支持缓存
<property name="hibernate.cache.provider_class">
org.hibernate.cache.EhCacheProvider
</property>
<property name="hibernate.cache.use_query_cache">true</property>
4、在具体的hbm.xml中说明当前类使用二级缓存
<cache stage="read-only"/>
5、在执行query之前设置其支持二级缓存
query.setCacheable(true);
16、list使用缓存的特点:
sql只执行一次,直接查询o/r mapping后返回结果,
要想重用缓存,hql必须相同,如果相同,
相应行的主键在缓存中就直接取,如果没有根据
主键值在数据库中找,而不是重新执行整个sql。
17、iterator使用缓存的特点:先执行一次sql取出所有主键,
再根据主键值查找缓存,若有直接取出,若没有根据主键
在数据库中查相应的对象并进行o/rMapping。
对于没缓存的sql,其sql要执行 "行数+1"次。对于有缓存的行,
执行效率高。
综上:第一次查询用list方法,第二查询用iterator方法。
18、数据查找的过程
首先在一级缓存中中找,若没有找到就在二级缓存中,若还是没有
找到就产生sql在数据据库中找。
19、缓存的特点:
load、get、insert、update、delete都会自动同步缓存
但query.executeUpdate()不更缓存,但如果批量更新时exeucuteUpdate执行效率很高。
一个对象通过get或query.list的方法查询放到一级缓存或二级缓存中时,不能用update直接更新,
只通通过set方法更新。
evict:清除缓存。
20、load与get方法的区别
相同点:3.2版本
先从一级缓存找,如果没在二级缓存中找的。
load:
如果没有找到报ObjectNotFoundException
返回的是一个代理
如果当前数据类的接口返回的应是接口
如果当前数据类没有接口,通过CGLIB返回类似接口的引用。
get
如果没有找开返回null
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -