- 浏览: 47977 次
- 性别:
- 来自: 西安
文章分类
一、缓存的分类
1.集群
2.应用级
3.事务级
二、什么时候用缓存
三、缓存的优缺
四、hibernate与ehcache如何实现二级缓存
五、list与iterator的区别
六、get与load主法的区别
七、executeUpate的特点,load,get,update,delete的特点?
八、hibernate如何用连接池
九、spring如何用连接池
一、事务的四大特点
1.原子性(atomic)
要么全成功,要么全失败
2.隔离性(isolate)
事务间不相互影响
3.持久性(persistent)
将数据写入到数据库中
4.一致性(coherence)
业务处理要适合业务逻辑,将相关的操作放到
同一个业务方法
二、没有锁的问题
1.脏读(dirty)
事务1先开始,但没有提交,事务2将在事务1数据的基础上更新了。
事务1:
update buy set amount=amount+1 where buyID=1;
sleep(1000);
rollback;
事务2:
update buy set amount=amount+1 where buyID=1;
commit;
2.覆盖更新(overwrite)
事务1:
update buy set amount=amount+1 where buyID=1;
sleep(1000);
commit;
事务2:
update buy set amount=amount+1 where buyID=1;
commit;
事务1,事务2同进读取数据,事务2的操作被事务1覆盖了。
3.不可重复读:同一个事务内,相同有select得到的结果不一样.
事务1:
update buy set amount=amount+1 where buyID=1;
commit;
事务2:
select * from buy;
sleep(1000);
select * from buy;
commit;
事务1,事务2同时进行
4.幻想读(fancy):第一次读有(没有),第二次读没有(有)
(insert,delete)
事务1:
insert into buy();
commit;
事务2:
select * from buy;
sleep(1000);
select * from buy;
commit;
三、锁的分类
1.读未提交:四大问题都无法处理。
2.读已提交:数据库默认的处理方式.
a.读了的数据都是已提交的,可防止脏读。
b.如果一行正在更新,加锁。
c.提交时会将当行对应的版本与数据库版本比较
如果小于数据库版本回退,当将操作失败。(可以防止覆盖更新)
d.乐观锁(optimistic)与悲观锁(pessimistic)
pessimistic(铁公鸡):该事务下select了一批数据
,不管更新与否,别的事务都不可以更新
该行.如果它更新,肯定可以成功。
optimistic:该事务下select了一批数据
,如果不更新,别的事务都可以更新
该行,该事务更新时,如果比数据版本低
报错。
3.可重复读:将一个SQl的查询结果备份一份,第二次取时从
备份的文件中取。
4.串行化(serializable):对整个表加锁,只一个事务可以操作当前表,
其余事务只能等待。
四、hiberntate的优化
1.用延迟加载
many
大文本
2.用二级缓存
3.更多的选择optimistic而不是pessimistic
1、pessimistic
a.Query query1=session.createQuery("select * from Customer for update");
b.
Query query1=session.createQuery("select * from Customer");
query1.setLockMode("Customer",LockMode.UPGRADE);
2、optimistic:默认是乐观锁
<class optimistic-lock="version/none"/>
4.合理的规划session的生命周期
5.在hibernate.cfg.xml文件中
设置fetch-size及batch-size参数
batch-size:在更新或增加数据时,删除时执行多少个sql后
再向数据库一次传送多个sql.
fetch-size:从数库一次提取的行数.
记录条数一般设置为30、50、100。
OracleJDBC驱动默认的Fetch Size=15,
设置Fetch Size为:
30、50性能会明显提升。
6.如有可能,选用uuid作为主键生成器
7.开发过程中,打开hibernate的SQl日志输出(hibernate.show_sql=true),通过观察hibernate生成的sql语句进一步了解其实现原理,
从而指事实上更好的实现策略。
org.hibernate.Criteria对象,可以在不使用SQL甚至
HQL的情況下进行数据库查询
查询所有的Customer的记录
Criteria crit = session.createCriteria(Customer.class)
查询限定条件,org.hibernate.expression.Expression
Expression.eq("field",value)对应SQL的表达式:field=value
Expression.ge("field",value)对应SQL的表达式:field>=value
Expression.gt("field",value)对应SQL的表达式:field>value
Expression.lt("field",value)对应SQL的表达式:field<value
Expression.le("field",value)对应SQL的表达式:field<=value
Criteria crit = session.createCriteria(Customer.class);
crit.add(Expression.ge("age", new Integer(20))); //Expression.ge的用法取出年龄>=20的customer的记录
如果要对结果进行排序,可以使用org.hibernate.expression.Order,列如:
Criteria crit = session.createCriteria(Customer.class);
crit.add(Expression.ge("age", new Integer(20)));
crit.addOrder(Order.asc("customerName"));
crit.addOrder(Order.desc("age") ) ;
分页
crit.setFirstResult(1);
crit.setMaxResults(2) ;//指定返回条数为3条;
DetachedCriteria类可以脱离session独立存在
Session session = sessionFactory.openSession();
DetachedCriteria crit = DetachedCriteria.forClass(Customer.class);
crit.add(Expression.ge("age", new Integer(20)));
crit.getExecutableCriteria(session);//
Hibernate Query Language(HQL)查询
实体查询
String sql="from Customer as customer where customer.age=20";
Query q= session.createQuery(sql);
单个属性查询
String sql="select customer.customerName from Customer as customer ";
Query q= session.createQuery(sql);
q.list();//在这里list集合里的数据就不是一条条Customer实体对象,而是一个个String类型的customerName
Object[] customerNames=q.list().toArray();//把他转化为对象数组
for(int i=0;i<customerNames.length;i++)
{
System.out.println(customerNames[i]);
}
多个属性查询
String sql="select customer.customerName ,customer.age from Customer as customer ";
Query q= session.createQuery(sql);
q.list();//现在我们的list集合元素是一个个对象数组
Iterator iterator=q.iterate();
while(iterator.hasNext())//把每个对象数组迭代取出
{
Object []obj=(Object[]) iterator.next();//用一个象数组接受
System.out.println("customerName:"+obj[0]+" "+"age:"+obj[1]);
}
取出属性直接转化为一个对象
List<Customer> results=session.createQuery("select new Customer(sex,customerName) from Customer ").list();
for (Customer customer : results)
{
System.out.println(customer.getCustomerName()+" "+customer.getSex());
}
分组与排序
order by 子句
String sql=" from Customer as customer order by customer.age";
Query q= session.createQuery(sql);
group by ---对某个字段进行分组统计,查询实现同年龄的人的个数
String sql=" select count(customer.customerName),customer.age from Customer as customer group by customer.age";
Query q= session.createQuery(sql);
引用查询
Hibernate提供了HQL可配置化的内置功能,
<class>
.....
.....
</class>
<query name="myhql">
<![CDATA[from Customer as customer where customer.customerName=:customerName]]>
</query>
Customer f=new Customer();
f.setCustomerName("a");
Query q= session.getNamedQuery("myhql");
q.setProperties(f);//给HQL传一个Customer的对象作为参数设进去
联合查询
加fetch后,当Buy对象被加载时就立即填充Cutomer里的buies集合
String sql="from Customer as customer inner join fetch customer.buies";
Query q= session.createQuery(sql);
List list=q.list();
for(int i=0;i<list.size();i++)
{
Customer c=(Customer) list.get(i);
System.out.println(c.getCustomerName()+c.getbuies());
}
没有声明fetch,则得到的list集合里面每一个元素就是一个对象数组,其包括一个Customer对象和一个Customer相对应的Buy对象。
String sql="from Customer as customer inner join customer.buies order by customer.customerName";
Query q= session.createQuery(sql);
List list=q.list();
for(int i=0;i<list.size();i++)
{
Object []obj=(Object[]) list.get(i);
Customer c=(Customer) obj[0];
Buy b=(Buy) obj[1];
System.out.println("客户名 :"+c.getCustomerName()+" 购买物 : " +b.getProductName());
}
左连接:没有fetch
String sql = "from Customer as customer left join customer.buies order by customer.customerName";
Query q = session.createQuery(sql);
List list = q.list();
for (int i = 0; i < list.size(); i++)
{
Object[] obj = (Object[]) list.get(i);
Customer c = (Customer)obj[0];
if (obj[1] != null)
{
Buy b = (Buy) obj[1];
System.out.println("客户名 :" + c.getCustomerName() + " 购买物 : "+ b.getProductName());
}
else
{
System.out.println("客户名 :" + c.getCustomerName()+ " 购买物 : null ");
}
}
Connection con=session.getConnection();
右连接
String sql = "from Customer as customer right join customer.buies order by customer.customerName";
子查询
String sql=" from Customer as customer where (select count(*) from customer.buies)>1";
数据加载方式
即时加载
当实体被加载时,立即加载他的关联属性
预先加载:用一个sql语句取出多个对象的信息,用关联实现,只要一个SQL
延迟加载:至少要两个sql
批量加载:batch-size
继承映射:有三种策略
1、一个类一个表。
2、继承同一父类的子类通通映射到一张数据表里面,
在数据表里加入一个标识字段,
用于去识别某个字段具体是属于哪个子类或是父类的属性。
create table user2
(
userName varchar(20) primary key,
pwd varchar(20),
guessRemark varchar(20),
adminRemark varchar(20),
DISCRIMINATOR_USERTYPE varchar(30)
);
package hibernate;
public class Users2 implements java.io.Serializable
{
private String userid;
private String username;
private String pwd;
public Users2()
{
}
public String getPwd()
{
return pwd;
}
public void setPwd(String pwd)
{
this.pwd = pwd;
}
public String getUserid()
{
return userid;
}
public void setUserid(String userid)
{
this.userid = userid;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
}
子类:guest
public class guest extends Users2 {
private String guestRemark;
public String getGuestRemark() {
return guestRemark;
}
public void setGuestRemark(String guestRemark) {
this.guestRemark = guestRemark;
}
public guest() {
}
}
子类:admin类
public class admin extends Users2
{
private String adminRemark;
public String getAdminRemark() {
return adminRemark;
}
public void setAdminRemark(String adminRemark) {
this.adminRemark = adminRemark;
}
public admin()
{
}
}
映射文件中该如何编写,由于这些子类和父类將映射至同一个表格,我门使用discriminator作为每个类记录在
表格中的识别,先直接看看映射文件如何编写:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="hibernate.Users2" table="users" discriminator-value="Users">
<id name="userid" type="string">
<column name="USERID" length="32" />
<generator class="assigned" />
</id>
<discriminator column="DISCRIMINATOR_USERTYPE" type="string"/>
<property name="username" type="string">
<column name="username" length="30" />
</property>
<property name="pwd" type="string">
<column name="pwd" length="20" />
</property>
<subclass name="hibernate.guest" discriminator-value="guest">
<property name="guestRemark" type="string">
<column name="guest_remark" length="20" />
</property>
</subclass>
<subclass name="hibernate.admin" discriminator-value="admin">
<property name="adminRemark" type="string">
<column name="admin_remark" length="20" />
</property>
</subclass>
</class>
</hibernate-mapping>
在查询父类时可以查询所有的子类
在查询子类时只查询子类
三、父类与每个子类建立一数据表,
父类映射的表格与子类映射的表格共享相同的主键值,
父类表格只记录本身的属性,如果要查询的是子类,
则透过外键关联从父类表格中取得继承而來的属性数据。
数据库建立如下:
drop table guest3;
drop table admin3;
drop table user3;
create table user3
( USERID varchar(32) primary key,
username varchar(30),
pwd varchar(20)
);
create table guest3
(
USERID varchar(32) primary key,
guest_remark varchar(20)
);
alter table guest3 add constraint guest3_fk foreign key(userID) references user3(userID);
create table admin3
(
USERID varchar(32) primary key,
admin_remark varchar(20)
);
alter table admin3 add constraint admin3_fk foreign key(userID) references user3(userID);
其中guest与admin表格的主键值將与users表格的主键值相同,
guest的主键USERID与admin的主键USERID作为一个外键,
以取得父类的数据。
在映射文件中要实现这种映射,我们使用<joined-subclass>标签,
并使用<key>标签指定子类表格与父类表格共享的主键值,
映射文件的编写方式如下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="hibernate.Users2" table="users" schema="dbo" catalog="t29">
<id name="userid" type="string">
<column name="USERID" length="32" />
<generator class="assigned" />
</id>
<property name="username" type="string">
<column name="username" length="30" />
</property>
<property name="pwd" type="string">
<column name="pwd" length="20" />
</property>
<joined-subclass name="hibernate.guest" table="guest">
<key column="USERID"/>
<property name="guestRemark" type="string">
<column name="guest_remark" length="20" />
</property>
</joined-subclass>
<joined-subclass name="hibernate.admin" table="admin">
<key column="USERID"/>
<property name="adminRemark" type="string">
<column name="admin_remark" length="20" />
</property>
</joined-subclass>
</class>
</hibernate-mapping>
测试类的代码可以用第二种映射的测试方法去测试。。。。
hibenate中用oracle的sequence
create table customer(
customerID int primary key,
customerName varchar2(20)
);
create sequence customer_sequence;
oracle中的操作
创建一个表、一个序列
在myEclipse中的操作
加入一个数据连接
url=jdbc:oracle:thin:@主机名:1521:数据库名
dirver=oracle.jdbc.driver.OracleDriver
oracle驱动包在:D:\oracle92\jdbc\lib\classes12.jar
加入hibernate环境
生成映射文件,主键的生成机制是sequence,具体的配置如下:
<id name="customerid" type="java.lang.Long">
<column name="CUSTOMERID" precision="22" scale="0" />
<generator class="sequence" >
<param name="sequence">序列名称</param>
</generator>
</id>
Oracle登陆:
cmd
sqlplus 用户名/密码@网络服务名
复合主键:一个表的主键列不是一个而是多个
drop table buy1;
create table buy1
(
buyID int not null,
customerName varchar(20) not null,
buyName varchar(20)
);
alter table buy1 add constraint buy1_pk primary key(buyID,customerName);
会生成一个主键类,这个类的属性就是多个主键对应的属性,
将主键类作为一个整体传给真实的类。
通过get/load查询时也是将主键类的实例作为作为主键值。
blob、clob字段映射
drop table testBlob;
create table testBlob
(
id int primary key,
myImage Blob
);
hibernate的回调与拦截机制
拦截与回调的实现
1、高藕合度
1、每一个数据库数据类实现hibernate的Lifecycle接口,Lifecycle有如下方法
public class Users implements Lifecycle
{
//在增加到数据库之前调用
public boolean onSave() thows CallableException
{
}
public boolean onFlush()
{
}
}
2、校验
public class Users implements Validatable
{
//在增加到数据库之前调用,这个方法可被调用多次
public void validate() thows CallbackException
{
}
}
以上两个机制与hibernate的藕合度太高,
所以可以选择Interceptor实现
2、低藕合度:写一个拦截器,在产生SessionFactory产生Session时将
拦截器通过参数传给openSession()方法,
如果调用其它方法对数据进行持久化操作不会重用前一个
session,但可以重用前一个Session中的Connection
具体使用如下:
Session newSession=SessionFactory.openSession(oldSession.connection());
oldSession与newSession共用同一个Connection因事务在
oldSession中已启动,newSession不用管理具体的事务实现。
public class MyInterceptor implements Interceptor
{
//在增加之前调用
public void onSave()
{
}
//在更新之前调用w
public void onDirtyFlush()
{
}
}
MyInterceptor mi=new MyInterceptor();
Session session=SessionFactory.getSession(mi);
1.集群
2.应用级
3.事务级
二、什么时候用缓存
三、缓存的优缺
四、hibernate与ehcache如何实现二级缓存
五、list与iterator的区别
六、get与load主法的区别
七、executeUpate的特点,load,get,update,delete的特点?
八、hibernate如何用连接池
九、spring如何用连接池
一、事务的四大特点
1.原子性(atomic)
要么全成功,要么全失败
2.隔离性(isolate)
事务间不相互影响
3.持久性(persistent)
将数据写入到数据库中
4.一致性(coherence)
业务处理要适合业务逻辑,将相关的操作放到
同一个业务方法
二、没有锁的问题
1.脏读(dirty)
事务1先开始,但没有提交,事务2将在事务1数据的基础上更新了。
事务1:
update buy set amount=amount+1 where buyID=1;
sleep(1000);
rollback;
事务2:
update buy set amount=amount+1 where buyID=1;
commit;
2.覆盖更新(overwrite)
事务1:
update buy set amount=amount+1 where buyID=1;
sleep(1000);
commit;
事务2:
update buy set amount=amount+1 where buyID=1;
commit;
事务1,事务2同进读取数据,事务2的操作被事务1覆盖了。
3.不可重复读:同一个事务内,相同有select得到的结果不一样.
事务1:
update buy set amount=amount+1 where buyID=1;
commit;
事务2:
select * from buy;
sleep(1000);
select * from buy;
commit;
事务1,事务2同时进行
4.幻想读(fancy):第一次读有(没有),第二次读没有(有)
(insert,delete)
事务1:
insert into buy();
commit;
事务2:
select * from buy;
sleep(1000);
select * from buy;
commit;
三、锁的分类
1.读未提交:四大问题都无法处理。
2.读已提交:数据库默认的处理方式.
a.读了的数据都是已提交的,可防止脏读。
b.如果一行正在更新,加锁。
c.提交时会将当行对应的版本与数据库版本比较
如果小于数据库版本回退,当将操作失败。(可以防止覆盖更新)
d.乐观锁(optimistic)与悲观锁(pessimistic)
pessimistic(铁公鸡):该事务下select了一批数据
,不管更新与否,别的事务都不可以更新
该行.如果它更新,肯定可以成功。
optimistic:该事务下select了一批数据
,如果不更新,别的事务都可以更新
该行,该事务更新时,如果比数据版本低
报错。
3.可重复读:将一个SQl的查询结果备份一份,第二次取时从
备份的文件中取。
4.串行化(serializable):对整个表加锁,只一个事务可以操作当前表,
其余事务只能等待。
四、hiberntate的优化
1.用延迟加载
many
大文本
2.用二级缓存
3.更多的选择optimistic而不是pessimistic
1、pessimistic
a.Query query1=session.createQuery("select * from Customer for update");
b.
Query query1=session.createQuery("select * from Customer");
query1.setLockMode("Customer",LockMode.UPGRADE);
2、optimistic:默认是乐观锁
<class optimistic-lock="version/none"/>
4.合理的规划session的生命周期
5.在hibernate.cfg.xml文件中
设置fetch-size及batch-size参数
batch-size:在更新或增加数据时,删除时执行多少个sql后
再向数据库一次传送多个sql.
fetch-size:从数库一次提取的行数.
记录条数一般设置为30、50、100。
OracleJDBC驱动默认的Fetch Size=15,
设置Fetch Size为:
30、50性能会明显提升。
6.如有可能,选用uuid作为主键生成器
7.开发过程中,打开hibernate的SQl日志输出(hibernate.show_sql=true),通过观察hibernate生成的sql语句进一步了解其实现原理,
从而指事实上更好的实现策略。
org.hibernate.Criteria对象,可以在不使用SQL甚至
HQL的情況下进行数据库查询
查询所有的Customer的记录
Criteria crit = session.createCriteria(Customer.class)
查询限定条件,org.hibernate.expression.Expression
Expression.eq("field",value)对应SQL的表达式:field=value
Expression.ge("field",value)对应SQL的表达式:field>=value
Expression.gt("field",value)对应SQL的表达式:field>value
Expression.lt("field",value)对应SQL的表达式:field<value
Expression.le("field",value)对应SQL的表达式:field<=value
Criteria crit = session.createCriteria(Customer.class);
crit.add(Expression.ge("age", new Integer(20))); //Expression.ge的用法取出年龄>=20的customer的记录
如果要对结果进行排序,可以使用org.hibernate.expression.Order,列如:
Criteria crit = session.createCriteria(Customer.class);
crit.add(Expression.ge("age", new Integer(20)));
crit.addOrder(Order.asc("customerName"));
crit.addOrder(Order.desc("age") ) ;
分页
crit.setFirstResult(1);
crit.setMaxResults(2) ;//指定返回条数为3条;
DetachedCriteria类可以脱离session独立存在
Session session = sessionFactory.openSession();
DetachedCriteria crit = DetachedCriteria.forClass(Customer.class);
crit.add(Expression.ge("age", new Integer(20)));
crit.getExecutableCriteria(session);//
Hibernate Query Language(HQL)查询
实体查询
String sql="from Customer as customer where customer.age=20";
Query q= session.createQuery(sql);
单个属性查询
String sql="select customer.customerName from Customer as customer ";
Query q= session.createQuery(sql);
q.list();//在这里list集合里的数据就不是一条条Customer实体对象,而是一个个String类型的customerName
Object[] customerNames=q.list().toArray();//把他转化为对象数组
for(int i=0;i<customerNames.length;i++)
{
System.out.println(customerNames[i]);
}
多个属性查询
String sql="select customer.customerName ,customer.age from Customer as customer ";
Query q= session.createQuery(sql);
q.list();//现在我们的list集合元素是一个个对象数组
Iterator iterator=q.iterate();
while(iterator.hasNext())//把每个对象数组迭代取出
{
Object []obj=(Object[]) iterator.next();//用一个象数组接受
System.out.println("customerName:"+obj[0]+" "+"age:"+obj[1]);
}
取出属性直接转化为一个对象
List<Customer> results=session.createQuery("select new Customer(sex,customerName) from Customer ").list();
for (Customer customer : results)
{
System.out.println(customer.getCustomerName()+" "+customer.getSex());
}
分组与排序
order by 子句
String sql=" from Customer as customer order by customer.age";
Query q= session.createQuery(sql);
group by ---对某个字段进行分组统计,查询实现同年龄的人的个数
String sql=" select count(customer.customerName),customer.age from Customer as customer group by customer.age";
Query q= session.createQuery(sql);
引用查询
Hibernate提供了HQL可配置化的内置功能,
<class>
.....
.....
</class>
<query name="myhql">
<![CDATA[from Customer as customer where customer.customerName=:customerName]]>
</query>
Customer f=new Customer();
f.setCustomerName("a");
Query q= session.getNamedQuery("myhql");
q.setProperties(f);//给HQL传一个Customer的对象作为参数设进去
联合查询
加fetch后,当Buy对象被加载时就立即填充Cutomer里的buies集合
String sql="from Customer as customer inner join fetch customer.buies";
Query q= session.createQuery(sql);
List list=q.list();
for(int i=0;i<list.size();i++)
{
Customer c=(Customer) list.get(i);
System.out.println(c.getCustomerName()+c.getbuies());
}
没有声明fetch,则得到的list集合里面每一个元素就是一个对象数组,其包括一个Customer对象和一个Customer相对应的Buy对象。
String sql="from Customer as customer inner join customer.buies order by customer.customerName";
Query q= session.createQuery(sql);
List list=q.list();
for(int i=0;i<list.size();i++)
{
Object []obj=(Object[]) list.get(i);
Customer c=(Customer) obj[0];
Buy b=(Buy) obj[1];
System.out.println("客户名 :"+c.getCustomerName()+" 购买物 : " +b.getProductName());
}
左连接:没有fetch
String sql = "from Customer as customer left join customer.buies order by customer.customerName";
Query q = session.createQuery(sql);
List list = q.list();
for (int i = 0; i < list.size(); i++)
{
Object[] obj = (Object[]) list.get(i);
Customer c = (Customer)obj[0];
if (obj[1] != null)
{
Buy b = (Buy) obj[1];
System.out.println("客户名 :" + c.getCustomerName() + " 购买物 : "+ b.getProductName());
}
else
{
System.out.println("客户名 :" + c.getCustomerName()+ " 购买物 : null ");
}
}
Connection con=session.getConnection();
右连接
String sql = "from Customer as customer right join customer.buies order by customer.customerName";
子查询
String sql=" from Customer as customer where (select count(*) from customer.buies)>1";
数据加载方式
即时加载
当实体被加载时,立即加载他的关联属性
预先加载:用一个sql语句取出多个对象的信息,用关联实现,只要一个SQL
延迟加载:至少要两个sql
批量加载:batch-size
继承映射:有三种策略
1、一个类一个表。
2、继承同一父类的子类通通映射到一张数据表里面,
在数据表里加入一个标识字段,
用于去识别某个字段具体是属于哪个子类或是父类的属性。
create table user2
(
userName varchar(20) primary key,
pwd varchar(20),
guessRemark varchar(20),
adminRemark varchar(20),
DISCRIMINATOR_USERTYPE varchar(30)
);
package hibernate;
public class Users2 implements java.io.Serializable
{
private String userid;
private String username;
private String pwd;
public Users2()
{
}
public String getPwd()
{
return pwd;
}
public void setPwd(String pwd)
{
this.pwd = pwd;
}
public String getUserid()
{
return userid;
}
public void setUserid(String userid)
{
this.userid = userid;
}
public String getUsername()
{
return username;
}
public void setUsername(String username)
{
this.username = username;
}
}
子类:guest
public class guest extends Users2 {
private String guestRemark;
public String getGuestRemark() {
return guestRemark;
}
public void setGuestRemark(String guestRemark) {
this.guestRemark = guestRemark;
}
public guest() {
}
}
子类:admin类
public class admin extends Users2
{
private String adminRemark;
public String getAdminRemark() {
return adminRemark;
}
public void setAdminRemark(String adminRemark) {
this.adminRemark = adminRemark;
}
public admin()
{
}
}
映射文件中该如何编写,由于这些子类和父类將映射至同一个表格,我门使用discriminator作为每个类记录在
表格中的识别,先直接看看映射文件如何编写:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="hibernate.Users2" table="users" discriminator-value="Users">
<id name="userid" type="string">
<column name="USERID" length="32" />
<generator class="assigned" />
</id>
<discriminator column="DISCRIMINATOR_USERTYPE" type="string"/>
<property name="username" type="string">
<column name="username" length="30" />
</property>
<property name="pwd" type="string">
<column name="pwd" length="20" />
</property>
<subclass name="hibernate.guest" discriminator-value="guest">
<property name="guestRemark" type="string">
<column name="guest_remark" length="20" />
</property>
</subclass>
<subclass name="hibernate.admin" discriminator-value="admin">
<property name="adminRemark" type="string">
<column name="admin_remark" length="20" />
</property>
</subclass>
</class>
</hibernate-mapping>
在查询父类时可以查询所有的子类
在查询子类时只查询子类
三、父类与每个子类建立一数据表,
父类映射的表格与子类映射的表格共享相同的主键值,
父类表格只记录本身的属性,如果要查询的是子类,
则透过外键关联从父类表格中取得继承而來的属性数据。
数据库建立如下:
drop table guest3;
drop table admin3;
drop table user3;
create table user3
( USERID varchar(32) primary key,
username varchar(30),
pwd varchar(20)
);
create table guest3
(
USERID varchar(32) primary key,
guest_remark varchar(20)
);
alter table guest3 add constraint guest3_fk foreign key(userID) references user3(userID);
create table admin3
(
USERID varchar(32) primary key,
admin_remark varchar(20)
);
alter table admin3 add constraint admin3_fk foreign key(userID) references user3(userID);
其中guest与admin表格的主键值將与users表格的主键值相同,
guest的主键USERID与admin的主键USERID作为一个外键,
以取得父类的数据。
在映射文件中要实现这种映射,我们使用<joined-subclass>标签,
并使用<key>标签指定子类表格与父类表格共享的主键值,
映射文件的编写方式如下:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="hibernate.Users2" table="users" schema="dbo" catalog="t29">
<id name="userid" type="string">
<column name="USERID" length="32" />
<generator class="assigned" />
</id>
<property name="username" type="string">
<column name="username" length="30" />
</property>
<property name="pwd" type="string">
<column name="pwd" length="20" />
</property>
<joined-subclass name="hibernate.guest" table="guest">
<key column="USERID"/>
<property name="guestRemark" type="string">
<column name="guest_remark" length="20" />
</property>
</joined-subclass>
<joined-subclass name="hibernate.admin" table="admin">
<key column="USERID"/>
<property name="adminRemark" type="string">
<column name="admin_remark" length="20" />
</property>
</joined-subclass>
</class>
</hibernate-mapping>
测试类的代码可以用第二种映射的测试方法去测试。。。。
hibenate中用oracle的sequence
create table customer(
customerID int primary key,
customerName varchar2(20)
);
create sequence customer_sequence;
oracle中的操作
创建一个表、一个序列
在myEclipse中的操作
加入一个数据连接
url=jdbc:oracle:thin:@主机名:1521:数据库名
dirver=oracle.jdbc.driver.OracleDriver
oracle驱动包在:D:\oracle92\jdbc\lib\classes12.jar
加入hibernate环境
生成映射文件,主键的生成机制是sequence,具体的配置如下:
<id name="customerid" type="java.lang.Long">
<column name="CUSTOMERID" precision="22" scale="0" />
<generator class="sequence" >
<param name="sequence">序列名称</param>
</generator>
</id>
Oracle登陆:
cmd
sqlplus 用户名/密码@网络服务名
复合主键:一个表的主键列不是一个而是多个
drop table buy1;
create table buy1
(
buyID int not null,
customerName varchar(20) not null,
buyName varchar(20)
);
alter table buy1 add constraint buy1_pk primary key(buyID,customerName);
会生成一个主键类,这个类的属性就是多个主键对应的属性,
将主键类作为一个整体传给真实的类。
通过get/load查询时也是将主键类的实例作为作为主键值。
blob、clob字段映射
drop table testBlob;
create table testBlob
(
id int primary key,
myImage Blob
);
hibernate的回调与拦截机制
拦截与回调的实现
1、高藕合度
1、每一个数据库数据类实现hibernate的Lifecycle接口,Lifecycle有如下方法
public class Users implements Lifecycle
{
//在增加到数据库之前调用
public boolean onSave() thows CallableException
{
}
public boolean onFlush()
{
}
}
2、校验
public class Users implements Validatable
{
//在增加到数据库之前调用,这个方法可被调用多次
public void validate() thows CallbackException
{
}
}
以上两个机制与hibernate的藕合度太高,
所以可以选择Interceptor实现
2、低藕合度:写一个拦截器,在产生SessionFactory产生Session时将
拦截器通过参数传给openSession()方法,
如果调用其它方法对数据进行持久化操作不会重用前一个
session,但可以重用前一个Session中的Connection
具体使用如下:
Session newSession=SessionFactory.openSession(oldSession.connection());
oldSession与newSession共用同一个Connection因事务在
oldSession中已启动,newSession不用管理具体的事务实现。
public class MyInterceptor implements Interceptor
{
//在增加之前调用
public void onSave()
{
}
//在更新之前调用w
public void onDirtyFlush()
{
}
}
MyInterceptor mi=new MyInterceptor();
Session session=SessionFactory.getSession(mi);
相关推荐
Hibernate 配置各种数据库 Hibernate 是一个基于 Java 的持久层框架,提供了一个抽象的数据访问层,能够与多种数据库进行集成。在 Hibernate 的配置文件中,我们可以配置不同的数据库连接,包括驱动程序、URL 等...
Hibernate.jar包,Hibernate可以应用在任何使用JDBC的场合,包含 hibernate-commons-annotations-4.0.1.Final.jar hibernate-core-4.1.12.Final.jar hibernate-ehcache-4.1.12.Final.jar hibernate-entitymanager-...
"Hibernate入门到精通" Hibernate 是一个基于Java的ORM(Object-Relational Mapping,对象关系映射)框架,它提供了一种简洁高效的方式来访问和操作关系数据库。下面是 Hibernate 的主要知识点: Hibernate 简介 ...
项目原型:Struts2.3.16 + Spring4.1.1 + Hibernate4.3.6 二、 项目目的: 整合使用最新版本的三大框架(即Struts2、Spring4和Hibernate4),搭建项目架构原型。 项目架构原型:Struts2.3.16 + Spring4.1.1 + ...
【hibernate学习资料大全】 Hibernate 是一个开源的对象关系映射(ORM)框架,它极大地简化了Java应用程序对数据库的操作。这个压缩包包含了丰富的Hibernate学习资源,旨在帮助开发者深入理解和熟练掌握这一强大的...
《Hibernate-Extensions全面指南》 Hibernate,作为Java领域中的一款著名对象关系映射(ORM)框架,极大地简化了数据库操作。然而,为了满足更复杂的业务需求,Hibernate还提供了丰富的扩展功能,这就是我们今天要...
【描述】中的"hibernate的jar包"指的是Hibernate框架的运行库文件,这些JAR文件包含了Hibernate的所有核心API、实现和依赖库,如Hibernate Commons Annotations、Hibernate EntityManager、Hibernate Core等。...
Hibernate是一个开源的对象关系映射(ORM)框架,它允许Java开发者使用面向对象的方式来操作数据库,极大地简化了数据访问层的编程工作。这个压缩包包含了Hibernate的基础jar包,这些jar文件是开发Hibernate应用所...
HibernateTools是Java开发人员在使用Hibernate ORM框架时的有力辅助工具集,主要目的是为了提高开发效率,简化数据库操作。在HibernateTools 3.2.4版本中,它包含了一系列的特性与插件,以支持更便捷地进行对象关系...
在Java开发环境中,与KingbaseV8数据库进行交互通常会用到Hibernate框架和JDBC驱动。 Hibernate是一个优秀的对象关系映射(ORM)框架,它简化了Java应用程序对数据库的操作,通过将Java对象与数据库表进行映射,...
Hibernate3 是一个强大的Java持久化框架,它允许开发者将数据库操作与业务逻辑解耦,使得应用程序的开发更为简便。这个“hibernate3全部jar包:hibernate3.jar.zip”包含了所有必要的库文件,方便用户一次性下载并...
Hibernate3是一个广泛使用的Java对象关系映射(ORM)框架,它允许开发者用面向对象的方式处理数据库操作,极大地简化了Java应用程序与数据库之间的交互。在这个"Hibernate3的依赖包"中,包含了运行Hibernate3应用...
标题中的“hibernate和MySQL的jar”指的是Hibernate ORM框架与MySQL数据库之间的连接库。Hibernate是一种流行的Java对象关系映射(ORM)工具,它允许开发者使用面向对象的编程方式来操作数据库,而无需直接编写SQL...
Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端...
标题"Hibernate 中文api 等学习资料"暗示了这是一组针对Hibernate ORM框架的中文学习资源,包括API文档和其他指南,旨在帮助用户更好地理解和使用Hibernate。 描述中的"hibernate orm框架api中文文档,学习资料,...
包含hibernate所有所需jar包还有一些其他包日志包、jpa支持包等: 列如:hibernate-core-5.1.0.Final.jar hibernate-ehcache-5.1.0.Final.jar hibernate-entitymanager-5.1.0.Final.jar hibernate-envers-5.1.0....
Hibernate是一款强大的Java持久化框架,它简化了数据库与Java对象之间的交互,使开发者可以更加专注于业务逻辑而不是数据访问层的实现。本压缩包提供的是Hibernate入门所需的jar包,包括了Hibernate的核心库以及与之...
Hibernate3 是一个非常重要的Java持久化框架,它允许开发者将对象模型与数据库关系模型进行映射,从而简化了数据存取的过程。这个压缩包“hibernate3必要jar包”显然是针对Hibernate3版本的,已经去除了冗余的库文件...
Hibernate 是一个著名的开源对象关系映射(ORM)框架,它为Java开发者提供了便捷的数据持久化方式,使得在Java应用程序中操作数据库变得更加简单。这个“hibernate_3.2官方开发包”包含了所有你需要开发基于...
在Java开发领域,Hibernate是一个非常重要的对象关系映射(ORM)框架,它简化了数据库操作,使得开发者可以使用面向对象的方式来处理数据。当涉及到Hibernate项目时,为了使其正常运行,通常需要一系列的JAR(Java ...