Hibernate问题
ORM (object relation mapping)是一种体系结构思想,叫对象关系映射。
Hibernate,Ibits,JPA是这种体系思想下的一种体现。 Hibernate在我们分层下充当持久层。
Hibernate全自动化 Ibits半自动化 JDBC手动化他们三个相对来说性能方面
JDBC>Ibist>Hibernate对于开发效率来说Hibernate >Ibist>JDBC
*.Hbm.xml 文件中有 类,表,字段,主键自动生成策略。
*.cfg。xml 文件中有 连接数据库,方言, session工厂,包含关系.显示sql语句的show_sql 为true
Session工厂是用来制造session, session就相当于jdbc里面的conaction Session不是线程安全的 session工厂是线程安全的
状态转换
Transient(临时状态) 当开始new的时候并没有调用save()方法的时候就是临是状态数据库没有记录
Persistent(持久化状态) 当调用save()方法但是session没有关闭的时候这时候处于持久状态数据库里面有数据。
Detache(脱管状态/游离状态)session关闭的时候持久状态变成Detache(脱管状态/游离状态)数据库有相对应的记录但是不能和数据库同步不再受Hibernate管理 常用对象
save()方法将指定对象保存,插入表中一条数据;
update()方法将指定对象更新,更新表中一条数据;
delete()方法将指定对象删除,删除表中一条数据
Session的get()/load()方法
get()方法会总是查询实体对象,不存在时候返回null;
load()方法也是获取一个实体对象,不存在时候抛空指针异常。
Query的实例是和Session绑定的,其生命周期跟随着Session结束而结束。
saveOrUpdate()方法接收一个实体对象,根据实体对象的id判断是否已经存在进行保存或更新操作,这样保存和更新方法就统一了;
特别注意:为了使用saveOrUpdate()方法,在由定义映射文件时,通过设定<id>标签的unsaved-value="null"来判断执行什么操作:当id属性等于unsaved-value的值(在此为null)时,则认为还没有保存,应该执行保存操作,否则执行更新操作。这样设定之后,可以使用saveOrUpdate()方法来统一保存和更新的方法。
1.uuid是产生一个32位的字符串,所以在数据库主键字段的大小上必须要大于等于32位。另外如果之前在库表设置了触发器和sequence,那么即使是采用uuid主键生成策略,那么hibernate在做插入时,uuid将会失效,而是采用sequence中的值作为主键id。相当于先用uuid做主键id,但是在插入之前又被sequence中的值覆盖掉了。这点必须注意。删除掉该表的触发器即可恢复。
2.native 意味着主键生成机制的实现方式将交给hibernate决定。hibernate 将根据底层数据库适配器dialect 的定义,采用不同数据库特定的主键生成方式。(对于SQLServer和MySQL自动采用自增字段,对于oracle自动采用Sequence生成主键)
注意:在这种情形下,hibernate会默认使用名为hibernate_sequence的序列,如果oracle中没有设置,Console控制台将会产生“Hibernate: select hibernate_sequence.nextval from dualCaused by: java.sql.SQLException: ORA-02289: 序列(号)不存在”的错误。那么应当在oracle中添加名为hibernate_sequence的序列。
或者采用如下方法来指明具体使用哪个序列:
<generator class="native"><param name="sequence">HUSER_SEQ</param></generator>
3.sequence 意味着将采用数据库提供的sequence机制产生主键。在hbm.xml映射文件中,如果采用这种主键映射机制,那么必须明确指定用哪个序列来产生主键。如:
<id name="userId" type="java.lang.Long">
<column name="USER_ID" precision="22" scale="0" />
<generator class="sequence">
<param name="sequence">SEQ_USER</param>
</generator>
</id>
HQL 可以采用 ?来传递参数(索引从0开始)
可以采用 :参数名 来传递参数
分页:setFirstResult(),从0开始setMaxResults,每页显示多少条数据 跨数据库
级联属性cascade
有以下取值:
all:代表在所有的情况下都执行级联操作
none:在所有情况下都不执行级联操作 save-update:在保存和更新时执行级联操作 delete:在删除时执行级联操作
第二篇:hibernate之增删查改总结
使用Hibernate实现数据的增删查改操作:
////////////////////////////////////////////////////////
1、加载(即根据主键将一条数据查询出来)
import org.hibernate.*;//导入包
import org.hibernate.cfg.*;
public class HibernateTest {
private Session session=null;
public HibernateTest(){//构造函数
Configuration config=new Configuration().configure()//第一步:得到配置对象 SessionFactory sf = config.buildSessionFactory(); //第二步:得到会话工厂 session=sf.openSession();//第三步:打开会话
}
public void close(){
session.close();
}
public static void main(String[] args) {
HibernateTest test=new HibernateTest();
this.close();
}
//加载,即根据主键查询数据的方法
public Customer get(String id){
//实质上在Hibernate中就只需下面这一句话
Customer cust = (Customer)session.get(Customer.class, id);
return cust;
}
//测试加载的方法
public void testLoad(){
Customer cust = this.get("209");
System.out.println(cust.getCustomerId()+":"+cust.getPassword());
}
}
从上可得,使用Hibernate加载数据只需一行代码,不再需要繁琐的从ResultSet中取数据封装到实体的代码
注意:load方法与get方法的用法一样,但是如果在load方法调用得到cust对象后,其他任何地方要使用cust对象,则不能在使用cust对象之前出现session.close()方法,否则会报no session的异常。而这种情况get方法就不会发生.
////////////////////////////////////////////////////////////
2、保存
注意:Hibernate中执行增删改操作一定要在事务环境中完成
public void testSave(){
Transaction tran = null;
try{
tran = session.beginTransaction();//第四步,开始一个事务 //第五步,持久化操作
Customer cust = new Customer();
cust.setCustomerId("211");cust.setFirstName("zhang"); cust.setMiddleInitial("d");cust.setLastName("san"); cust.setPassword("111");cust.setCity("changsha");
cust.setEmail("zhang@126.com");cust.setPhone("23432344"); cust.setState("H");cust.setStreet("五一大道");
cust.setZip("41001");
session.save(cust);//保存对象
tran.commit();//提交事务
}catch(Exception ex){
if(tran!=null){
tran.rollback();
}
ex.printStackTrace();
}finally{
session.close();
}
}
//////////////////////////////////////////////////////////
3、更新
public Customer get(String id){
......//上面第一点中的get代码
}
public void testUpdate(){
Transaction tran = null;
try{
tran = session.beginTransaction();//增删改之前一定要开启事务 Customer cust = this.get("211");//先加载,再修改
cust.setFirstName("wang");
session.update(cust);//执行修改的代码
tran.commit();
}catch(Exception ex){
if(ex!=null){
tran.rollback();
}
ex.printStackTrace();
}finally{
session.close();
}
}
注意:因为Hibernate是使用面向对象的语义,所以在更新、删除时,要操作的应该是对象,而不是主键或其他的字段。因此要先加载数据,得到对象之后,再更新或删除对象 ////////////////////////////////////////////////////
4、删除
public Customer get(String id){
......//上面第一点中的get代码
}
public void testDelete(){
Transaction tran = null;
try{
tran = session.beginTransaction();
Customer cust = this.get("211");//先加载,再删除
session.delete(cust);//执行删除的对象
tran.commit();
}catch(Exception ex){
if(ex!=null){
tran.rollback();
}
ex.printStackTrace();
}finally{
session.close();
}
}