Hibernate备课笔记.docx

上传人:b****6 文档编号:5616641 上传时间:2022-12-29 格式:DOCX 页数:35 大小:2.89MB
下载 相关 举报
Hibernate备课笔记.docx_第1页
第1页 / 共35页
Hibernate备课笔记.docx_第2页
第2页 / 共35页
Hibernate备课笔记.docx_第3页
第3页 / 共35页
Hibernate备课笔记.docx_第4页
第4页 / 共35页
Hibernate备课笔记.docx_第5页
第5页 / 共35页
点击查看更多>>
下载资源
资源描述

Hibernate备课笔记.docx

《Hibernate备课笔记.docx》由会员分享,可在线阅读,更多相关《Hibernate备课笔记.docx(35页珍藏版)》请在冰豆网上搜索。

Hibernate备课笔记.docx

Hibernate备课笔记

Hibernate笔记:

作者:

胡晟源QQ:

1312837781

1.hibernate不能删除全是非空记录表记录。

org.hibernate.PropertyValueException:

not-nullpropertyreferencesanullortransientvalue:

cn.itcast.hibernate.domain.Department.name

在hbm.xml里面写了not-null=“true”,至于什么原因,目前正在寻找。

2.Hql语句:

form+对象名。

后面的名字必须和javabean类类名相同。

3配置Myeclipse连接数据库,使之自动生成hibernate.cfg.xml和javabean类。

第一步:

成功连接数据库。

第三步:

新建一个Web工程项目。

选中该项目然后:

MyEclipse-->Project--->addHibernateCapabilities。

操作之后会出现如下界面:

选中myhibernate这个项目。

然后点击:

一:

Myeclipse

二:

projectcapabilities

三:

addHibernateCapabilities.

第二步:

第三步:

第四步:

对于这步中,我选中去掉自动生成的HibernatesessionFactory工具类,该工具类就是一个回去Session的单例。

完成后,打开项目就可以看到:

第五步:

重新回到MyEclipseDatabaseExploere界面。

选中刚刚配置的SQLServerDriver,右击选中openconnection,完成后就会出现如下界面:

第六步:

在dbo-->table中选中相应的表,右击选中HibernateReverseEngineering。

如上。

然后出现:

第七步:

第八步:

4.查询一列:

返回的是:

List,查询多列:

返回的是List数组集合。

5.条件查询与占位符查询。

@Test

publicvoidtest03()

{

Sessionsession=HibernateUtils.openSession();

Transactiontransaction=session.beginTransaction();

Stringhql="fromDepartmentwherename=:

abc";

Queryquery=session.createQuery(hql).setParameter("abc","媒体部");

Listlist=query.list();

for(Departmentff:

list)

{

System.out.println(ff.getName());

}

mit();

session.close();

}

6.Criteria高级查询。

@Test

publicvoidtest04(){

Sessionsession=HibernateUtils.openSession();

Transactiontransaction=session.beginTransaction();

Criteriac=session.createCriteria(Department.class);

c.add(Restrictions.eq("name","媒体部"));

//DepartmentuniqueResult=(Department)c.uniqueResult();

Listlist=c.list();

System.out.println(list);

mit();

session.close();

}

7.主键生成策略

●(increment)并发问题。

演示并发:

给程序2次debug,第一次让程序停在点上,在运行一个debug,发现第一个成功,第二个失败。

两次debug的目的:

为了演示并发的效果,我们需要第一个程序停在某个点上等待程序第二次的运行。

●Identity标示符。

由于identity生成标识符的机制依赖于底层数据库系统,因此,要求底层数据库系统必须支持自动增长字段类型.支持自动增长字段类型的数据库包括:

DB2,Mysql,MSSQLServer,Sybase等

OID必须为long,int或short类型,如果把OID定义为byte类型,在运行时会抛出异常

●Sequence序列

●复合主键。

●派生属性。

在数据库里面定义一个字段totalPrice,formula里面的sql语句查询出来值付给totalPrice属性。

注意:

formula里面语句必须加括号().

8.MySql数据库乱码处理

Mysql乱码的解决

showvariableslike'char%';查看数据库字符集设置

client、connection、result和命令行客户端相关(windows下命令行客户端必须要设置gbk)

databaseserversystem和服务器相关字符集(system字符集不可修改)

*实际开发中建议大家将database和server字符集设置为utf8

mysql核心配置文件my.ini如果linuxf

[mysql]主要配置命令行客户端参数default-character-set=gbk----影响client、connection、result

[mysqld]配置服务器参数character-set-server=utf8-----影响databaseserver

如果服务器server字符集已经设置utf8建立数据库数据表默认utf8-----插入数据一定没有乱码

如果服务器没有设置server字符集,默认latin1,建立数据库指定字符集utf-8建表指定字符集utf-8(有乱码)

解决方案一:

设置server字符集,重新建立数据库和表

解决方案二:

jdbc:

mysql:

///db?

useUnicode=true&characterEncoding=utf-8(默认传输字符集utf8/gbk)

9.Hibernate中将PO对象分为三种状态。

●瞬时态transient尚未与HibernateSession关联对象,被认为处于瞬时状态,失去引用将被JVM回收,无持久化标识OID,未与Session关联

●持久态persistent数据库中有数据与之对应并与当前session有关联,并且相关联的session没有关闭数据库并且事务未提交存在持久化标识OID,与Session关联

●脱管态detached数据库中有数据与之对应,但当前没有session与之关联,脱管状态改变hibernate不能检测到,存在持久化标识OID,未与Session关联

自动建表:

update

Hbm文件使用type制定类型生成表如下:

CREATETABLE`book`(

`id`int(11)NOTNULLAUTO_INCREMENT,

`name`varchar(255)DEFAULTNULL,

`price`doubleDEFAULTNULL,

PRIMARYKEY(`id`)

)ENGINE=InnoDBAUTO_INCREMENT=2DEFAULTCHARSET=utf8

未使用type进行类型制定,生成表如下:

生成表和上面一样,说明这个type是与javabean类的属性类型是相关的。

与这类型无关。

程序代码

生命周期

状态

tx=session.beginTransaction();

Customerc=newCustomer();

开始生命周期

瞬时状态

Session.save(c)

处于生命周期中

转变为持久化状态

Longid=c.getId();

c=null;

Customerc2=(Customer)session.load(Customer.class,id);

mit();

处于生命周期中

处于持久化状态

session.close();

处于生命周期中

转变为脱管态

c2.getName();

处于生命周期中

处于脱管态

c2=null;

结束生命周期

结束生命周期

10.证明一级缓存存在。

@Test

publicvoidtest06()

{

Sessionsession=HibernateUtils.openSession();

Transactiontransaction=session.beginTransaction();

//证明一级缓存的存在。

Bookbook1=(Book)session.get(Book.class,1);

System.out.println(book1);

//为了证明缓存存在,重新获取一下id为1的实例。

发现其地址一样。

Bookbook2=(Book)session.get(Book.class,1);

System.out.println(book2);

mit();

session.close();

}

运行结果:

cn.itcast.hibernate.domain.Book@1397e5c

cn.itcast.hibernate.domain.Book@1397e5c

可以看出,hashcode一致。

并且2次查询只有一条select的sql语句。

●将缓存中的数据同步到数据库。

如果在上面代码中间加入session.flush();没有任何效果,输出结果,select语句全部一样。

如果使用book1.setName(“哦哦哦”);改变了其值,那么flush将会使用快照更新数据库。

●Clear清空所有缓存。

●Evit清楚指定缓存。

●证明不使用flush自动更新。

说明:

三种情况会更新数据库。

事物提交,Query查询,还有flush都会同步数据库。

●FlushMode:

设置什么时间进行一级缓存刷出。

清理缓存的模式

Session的

查询方法

tx的

commit()

Session的

flush()

FlushMode.AUTO(默认)

刷出

刷出

刷出

FlushMode.COMMIT

不刷出

刷出

刷出

FlushMode.ALWAYS

刷出

刷出

刷出

FLushMode.MANUAL

不刷出

不刷出

刷出

11.数据建表原则。

●多对多:

必须创建一张中间表,引用两张实体表主键作为外键,2个外键作为中间表的联合主键。

(非常常用重要)

学生Student和课程Course之间关系

●一个学生可以选修多门课程

一门课程可以被多名学生选修

多对多和一对多重要区别:

多对多种没有父子关系

●Student.hbm.xml

--多对多必须有中间关系表-->

--

name:

是Student类中关联Course对应属性集合名称

table:

生成中间表表名

-->

--当前Student对象,在中间表生成外键列列名-->

--

class:

set集合数据类型

column:

set映射目标类,生成中间表外键列列名

-->

Course.hbm.xml

--多对多-->

●测试用例一:

建表

●测试用例二:

测试保存,多对多没有父子关系,在真正的开发中不建议级联

*当两个持久对象,建立关系,在关系表插入一条数据(防止重复数据:

1)inverse=true使一端放弃外键维护2)不要建立双向关系)

●测试用例三:

解决学生和课程关系,产生一条delete语句

●测试用例四:

将1号学生选修1号课程,改为2号学生选修1号课程

●测试用例五:

删除一个选过课的学生

*不用级联,删除学生后,选课记录自动删除

多对多删除离线对象---cascade无效

多对多删除持久对象---cascade生效

一对多:

在多方表引入一方表作为外键。

一对一:

在任意一方引入对方主键作为外键。

12.一对多关联映射。

在多方表引入一方表作为外键。

注意配置的相互关联性:

测试类:

注意:

测试类没有添加配置文件级联操作,一旦session.save()少保存一个对象,那么就会出错。

@Test

publicvoidtest07()

{

Sessionsession=HibernateUtils.openSession();

Transactiontransaction=session.beginTransaction();

Customercustomer=newCustomer();

customer.setAge(19);

customer.setName("maechl");

Orderorder1=newOrder();

order1.setAddr("ooo");

order1.setTotalPrice(23d);

Orderorder2=newOrder();

order2.setAddr("lplpl");

order2.setTotalPrice(767d);

customer.getOrders().add(order1);

customer.getOrders().add(order2);

order1.setCustomer(customer);

order2.setCustomer(customer);

session.save(customer);

session.save(order1);

session.save(order2);

mit();

session.close();}

13.级联删除。

@Test

publicvoidtest08()

{

Sessionsession=HibernateUtils.openSession();

Transactiontransaction=session.beginTransaction();

Customercustomer=(Customer)session.get(Customer.class,1);

session.delete(customer);

mit();

session.close();

}

执行语句:

Hibernate:

deletefromsshdemo.orderwhereid=?

Hibernate:

deletefromsshdemo.orderwhereid=?

Hibernate:

deletefromsshdemo.customerwhereid=?

可以看出:

三条删除语句,删除所有关联关系的数据。

而且:

我们是从Customer端进行删除的,那么我们就可以在Customer端进行配置。

如果需要从Order进行删除,进行如下配置:

14.孤儿删除

✓在没有配置孤儿删除的时候:

Customercustomer=(Customer)session.get(Customer.class,2);

Orderorder=(Order)session.get(Order.class,3);

Customer.getOrders().remove(order);

使用customer移除3号订单,但是没有配置的情况下,那么将会把外键置为null空。

✓可以发现配置:

delete-orphan后:

客户的订单孤儿删除成功。

15.多余的SQL

修改订单:

把4号客户订单改为6号。

会产生2个update,这样不行,怎样才能一个update语句呢?

原则上,只需要一句update语句。

Inverse=true表示:

放弃维护外键值的权利,无法设置外键的值。

在父方设置cascade级联,

在父方设置inverse=true,表示Customer已无外键维护权利,把外键维护的权利交给Order.

Inverse和cascade是Hibernate映射中最难掌握的两个属性。

两者都在对象的关联操作中发挥作用。

1.明确inverse和cascade的作用 

inverse决定是否把对对象中集合的改动反映到数据库中,所以inverse只对集合起作用,也就是只对one-to-many或many-to-many有效(因为只有这两种关联关系包含集合,而one-to-one和many-to-one只含有关系对方的一个引用)。

cascade决定是否把对对象的改动反映到数据库中,所以cascade对所有的关联关系都起作用(因为关联关系就是指对象之间的关联关系)。

2.inverse属性 :

inverse所描述的是对象之间关联关系的维护方式。

 

inverse只存在于集合标记的元素中 。

Hibernate提供的集合元素包括 

Inverse属性的作用是:

是否将对集合对象的修改反映到数据库中。

 

inverse属性的默认值为false,表示对集合对象的修改会被反映到数据库中;inverse=false的为主动方,由主动方负责维护关联关系。

 

inverse=”true”表示对集合对象的修改不会被反映到数据库中。

 为了维持两个实体类(表)的关系,而添加的一些属性,该属性可能在两个实体类(表)或者在一个独立的表里面,这个要看这双方直接的对应关系了:

 这里的维护指的是当主控放进行增删改查操作时,会同时对关联关系进行对应的更新。

   一对多:

 该属性在多的一方。

应该在一方的设置inverse=true,多的一方设置inverse=false(多的一方也可以不设置inverse属性,因为默认值是false),这说明关联关系由多的一方来维护。

如果要一方维护关系,就会使在插入或是删除"一"方时去update"多"方的每一个与这个"一"的对象有关系的对象。

而如果让"多"方面维护关系时就不会有update操作,因为关系就是在多方的对象中的,直指插入或是删除多方对象就行了。

显然这样做的话,会减少很多操作,提高了效率。

注:

 

    单向one-to-many关联关系中,不可以设置inverse="true",因为被控方的映射文件中没有主控方的信息。

   多对多:

 属性在独立表中。

inverse属性的默认值为false。

在多对多关联关系中,关系的两端inverse不能都设为false,即默认的情况是不对的,如果都设为false,在做插入操作时会导致在关系表中插入两次关系。

也不能都设为true,如果都设为true,任何操作都不会触发对关系表的操作。

因此在任意一方设置inverse=true,另一方inverse=false。

   一对一:

 其实是一对多的一个特例,inverse的设置也是一样的,主要还是看关联关系的属性在哪一方,这一方的inverse=false。

   多对一:

 也就是一对多的反过来,没什么区别。

2.cascade属性 

cascade属性的作用是描述关联对象进行操作时

展开阅读全文
相关搜索

当前位置:首页 > 医药卫生 > 药学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1