黑马程序员郑州中心编著黑马程序员:三大框架hibernate-day07笔记第1章Hibernate注解开发在hibernate中我们使用注解,可以帮助我们简化hbm文件配置。1.1PO类注解配置@Entity声明一个实体@Table来描述类与表对应@Id来声明一个主键@GenerateValue用它来声明一个主键生成策略默认情况下相当于native可以选择的主键生成策略AUTOIDENTITYSEQUENCE@Column来定义列注意:对于PO类中所有属性,如果你不写注解,默认情况下也会在表中生成对应的列。列的名称就是属性的名称@Temporal来声明日期类型可以选择黑马程序员郑州中心编著TemporalType.DATA只有年月日TemporalType.TIME只有小时分钟秒TemporalType.TIMESTAMP有年月日小时分钟秒我们最终需要在hibernate.cfg.xml文件中将我们类中的注解配置引用生效问题:1.如果我们主键生成策略想使用UUID类型?问题2:如果设定类的属性不在表中映射?对于我们以上讲解的关于属性配置的注解,我们也可以在其对应的getXxx方法去使用1.2一对多(多对一)@OneToMany@ManyToOne以Customer与Order为例黑马程序员郑州中心编著Customer类Order类示例:保存客户时,保存订单对于这个示例我们需要在Customer中配置cascade操作,save-update第一种方式,可以使用JPA提供的注解第二种方式:可以使用hibernate提供的注解以下是示例代码执行后的结果黑马程序员郑州中心编著订单中没有关联客户的id,为什么?原因:我们在Customer中配置了mappedBy=”c”它代表的是外键的维护由Order方来维护,而Customer不维护,这时你在保存客户时,级联保存订单,是可以的,但是不能维护外键,所以,我们必须在代码中添加订单与客户关系。扩展:关于hibernate注解@Cascade中的DELETE_ORPHAN过时s使用下面方案来替换过时方案第2章Hibernate关联映射-多对多我们使用注解完成多对多配置.描述学生与老师.黑马程序员郑州中心编著使用@ManyToMany来配置多对多,只需要在一端配置中间表,另一端使用mappedBy表示放置外键维护权。2.1创建PO类Teacher类中Student类中2.2级联保存操作测试因为我们将外键的维护权利由Student来维护,我们演示保存学生时,将都也级联保存。黑马程序员郑州中心编著我们在Student类中配置了级联2.3级联删除操作测试黑马程序员郑州中心编著第3章Hibernate关联映射-一对一以人与身份证号为例一对一操作有两种映射方式:1.在任意一方添加外键2.主键映射3.1外键映射创建实体User类上述配置,t_user表放弃对外键的维护权利IDCard类黑马程序员郑州中心编著joinColumn指定外键列名称,当前配置外键是在t_idcard表中测试代码3.2主键映射(了解)以Husband与Wife为例黑马程序员郑州中心编著Wife的主键生成策略是identity@PrimaryKeyJoinColumn说明husband与wife是使用主键映射Husband的主键我们设置成参考wife的主键方式测试操作黑马程序员郑州中心编著第4章Hibernate检索方式概述对数据库操作中,最常用的是select.使用hibernate如何select操作。分为五种:1导航对象图检索方式,根据已加载的对象导航到其它对象2.OID检索方式,按照对象的OID来检索对象3.HQL检索方式,使用面向对象的HQL查询语言4.QBC检索方式,使用QBC(QuerybyCriteria)API来检索对象,这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口5.本地SQL检索方式,使用本地数据库的SQL查询语句黑马程序员郑州中心编著4.1导航对象图检索方式Customerc=session.get(Customer.class,2);c.getOrders().size()通过在hibernate中进行映射关系,在hibernate操作时,可以通过导航方式得到其关联的持久化对象信息。4.2OID检索方式Session.get(Customer.class,3);Session.load(Order.class,1);Hibernate中通过get/load方法查询指定的对象,要通过OID来查询。4.3HQLHQL是我们在hibernate中是常用的一种检索方式。HQL(HibernateQueryLanguage)提供更加丰富灵活、更为强大的查询能力因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语句的查询方式,同时也提供了更加面向对象的封装。完整的HQL语句形式如下:Select/update/delete……from……where……groupby……having……orderby……asc/desc其中的update/delete为Hibernate3中所新添加的功能,可见HQL查询非常类似于标准SQL查询。基本步骤:1.得到Session黑马程序员郑州中心编著2.编写HQL语句3.通过session.createQuery(hql)创建一个Query对象4.为Query对象设置条件参数5.执行list查询所有,它反胃的是List集合uniqueResut()返回一个查询结果。4.3.1数据准备4.3.2基本检索From类名;黑马程序员郑州中心编著4.3.3排序检索黑马程序员郑州中心编著4.3.4条件检索4.3.5分页检索黑马程序员郑州中心编著4.3.6分组统计检索分组groupby统计countmaxminavgsum4.3.7投影检索我们主要讲解是关于部分属性查询,可以使用投影将部分属性封装到对象中。黑马程序员郑州中心编著注意:我们必须在PO类中提供对应属性的构造方法,也要有无参数构造。4.3.8命名检索我们可以将hql语句先定义出来,在使用时通过session.getNamedQuery(hqlName);得到一个Query,在执行.问题:hql定义在什么位置?1.如果你有hbm配置文件,那么当前的hql操作是对哪一个实体进行操作,就在哪一个实体的配置文件中声明。2.如果是使用注解来描述PO的配置我们直接在PO类中使用黑马程序员郑州中心编著如何使用?4.4QBCQBC(querybycriteria),它是一种更加面向对象的检索方式。QBC步骤:1.通过Session得到一个Criteria对象session.createCriteria()2.设定条件Criterion实例它的获取可以通过Restrictions类提供静态。Criteria的add方法用于添加查询条件3.调用list进行查询criterfia.list.4.4.1基本检索黑马程序员郑州中心编著4.4.2排序检索注意在criteri.addOrder()方法的参数使用的Order是hibernate中的对象黑马程序员郑州中心编著4.4.3条件检索4.4.4分页检索黑马程序员郑州中心编著4.4.5统计分组检索Countsumavgmaxmin4.4.6离线条件检索黑马程序员郑州中心编著4.5本地SQL本地sql也支持命名查询。可以将sql语句定义在hbm文件中,也可以使用注解。本地命名sql注解定义如果执行这个命名的sql会产生异常出现问题的原因:是hibernate不知道执行select*fromt_customer后如果将结果封装。黑马程序员郑州中心编著4.6多表操作4.6.1SQL多表操作4.6.1.11.交叉连接CROSSJOIN会产生迪卡尔积SELECT*FROMt_customerCROSSJOINt_order;4.6.1.22.内连接INNERJOINONSELECT*FROMt_customerAScINNERJOINt_orderASoONc.id=o.c_customer_id;使用内连接它只能将有关联的数据得到。隐式内连接使用逗号将表分开,使用WHERE来消除迪卡尔积SELECT*FROMt_customerASc,t_orderoWHEREc.id=o.c_customer_id;4.6.1.33.外连接左外LEFTOUTERJOIN右外RIGHTOUTERJOINOUTER可以省略SELECT*FROMt_customercLEFTOUTERJOINt_orderoONc.id=o.c_customer_id;黑马程序员郑州中心编著4.6.2HQL多表操作Hql多表操作分类:1.交叉连接2.内连接a)显示内连接b)隐式内连接c)迫切内连接3.外连接左外连接迫切左外连接右外连接注意:在hibernate中有迫切连接的概念,而sql中没有。4.6.2.1内连接显示内连接显示内连接使用的是innerjoinwith黑马程序员郑州中心编著隐式内连接隐式内连接也我们在sql中操作不一样,它是通过”.”运算符来关联迫切内连接迫切内连接得到的结果是直接封装到PO类中,而内连接得到的是Object[]数组,数组中封装的是PO类对象。黑马程序员郑州中心编著4.6.2.2外连接黑马程序员郑州中心编著第5章Hibernate事务管理5.1事务介绍问题:什么是事务?事务就是逻辑上的一组操作,组成这组操作的各个单元要么全部成功,要么全都失败。问题:事务四个特性?原子性:不可分割一致性:事务在执行前后,要保证数据的一致。隔离性:一个事务在执行的过程中,不应该受到其它事务的干扰。持久性:事务一旦结束,数据持久化到数据库。问题:不考虑事务的隔离性,会产生什么问题?脏读:一个事务读取到另一个事务的未提交数据不可重复读:一个事务读取到另一个事务提交的数据(主要是指update),会导致两次读取的结果不一致。虚读(幻读):一个事务读取到另一个事务提交的数据(主要是指insert),会导致两次读取结果不一致.问题:对于上述问题如何解决?我们可以通过设置隔离级别来解决.READ_UNCOMMITED读取未提交,它引发所有的隔离问题READ_COMMITTED读已提交,阻止脏读,可能发生不可重复读与虚读.REPEATABLE_READ重复读阻止脏读,不可重复读可能发生虚读SERIALIZABLE串行化解决所有问题不允许两个事务,同时操作一个目标数据。(效率黑马程序员郑州中心编著低下)ORACLE默认的是事务隔离级别READ_COMMITTEDMYSQL默认的事务隔离级别REPEATABLE_READ5.2Hibernate中设置事务隔离级别hibernate.connection.isolation它可取的值有12481代表的事务隔离级别为READUNCOMMITTED2代表的事务隔离级别为READCOMMITTED4.代表的事务隔离级别为REPEATABLEREAD8代表的事务隔离级别为SERIALIZABLE在hibernate.cfg.xml文件中配置5.3Hibernate中session管理Hibernate提供了三种管理session的方式:1.Session对象的生命周期与本地线程绑定(ThreadLocal)2.Session对象的生命周期与JTA事务绑定(分布式事务管理)黑马程序员郑州中心编著3.Hibernate委托程序来管理Session的生命周期我们之前所使用的是第三种,通过程序获取一个Session对象,使用它,最后session.close();在实际开发中我们一般使用的是前两种:主要介绍关于本地线程绑定Session。步骤:1.需要在hibernate.cfg.xml文件配置2.在获取session时不要在使用openSession而是使用getCurrentSession()方法