使用hibernate编程,继承了面向对象编程的特点,使我们屏蔽了直接的拼sql语句对数据库表进行操作。JDBC操作数据库很繁琐,sql语句编写并不是面向对象的,可以在对象和关系表间建立关联来简化编程,跨数据库平台,只需改写方言Dialect
hibernate要学多久学习建立user library->hibernate,并加入相应的jar包:可以在项目右键build path->configure build path->add library选择user library,在其中新建library,命名为hibernate,加入所需的包(hibernate core、required、slf4j jar、log4j.jar)
配置文件l一般放在src根目录下面,这样当读取这个配置文件时,就可以直接使用figure()方法,而不需设置这个配置文件所在路径
所有的POJO最好都放到一个package下面,这样与之对应的映射文件*.l也都放在了那下面
在hibernate3以后开始支持annotation,目标是建立符合JPA标准的annotation,可以下载与hibernate版本对应的annotation包,引入三个jar包:hibernate-commons-annotations.jar,ejb3-persistence.jar,hibernate-annotations.jar。new Configuration时,要使用AnnocationConfiguration
使用注解时,如果想要当自己一键入@就给提示,content-assist的activation中加上@符号就可以了。
目前比较流行的ORM框架有hibernate,toplink,jdo,ibatis(“半自动化”的ORM实现,而非“一站式”),jp
a;jpa(意愿一统天下)
slf是一个日志框架,针对不同的实现,我们只需引入相关的jar包,比如slf4j nop,log4j, jdk logging, commons-logging,这种方式很像JPA,JDBC
我们可以常常看看project->etc下面的一些文件,主要是些配置文件,我们用的时候可以参考,比如log4j.properties
注解有的是写给javac编译器看的,有的是写给java运行环境看的。
l中的show_sql,format_sql分别都是在输出信息中输出sql语句,后者是格式化后的效果,便于查看
以xml映射时,除了主键id,其他每个字段都要映射,而以annotation的方式时,只需指定主键,其他默认进行了映射(默认加了@Basic)。
当字段名和类的属性名不对应的时候,在相应的getter方法上添加collumn(name=""),注意都要选择javax.persistence下面的。不想映射某个字段加入@Transient注解接口
映射日期的时候,如果只想映射精度到日期,可以加入@Temporal(TemporalType.DATE)默认是Temp
oralType.TIMESTAMP,完整的是(value=TemporalType.DATE),但只要是value=都可以不用写它,简写掉,这只针对类型为java.util.Date
大部分时候(95%)都不需要指定映射的类型,由hibernate默认自动类型映射
映射枚举类型采用@Enumerated方便而使用xml的时候就麻烦了,要定义相关的类型转换器,还需指定类型enumType
字段映射的位置放在field或者get方法,最好保持field和get set方法的一致。放到field上有点破坏面向对象编程封装机制,因为field一般来说都是私有的,虽然hibernate可以利用反射机制访问到
如果使用sequence的注解来指定生成策略,在类名前加@SequenceGenerator(name="seqGenerator", sequenceName="student_seq")表示声明一个生成器,然后在主键字段上加入注解
@GeneratoValure(strategy=GeneratorType.AUTO, generator="seqGenerator")
key,value是mysql的关键字,需要避免使用
如果使用联合主键,需要使用<composite-id>指定,我们可以将这些联合的属性组合到一个新的类中,
这个类需要实现序列化接口,同时最好还要重写equals和hashCode这个时候是为了保证在内存中唯一性
序列化就是一种用来处理对象流的机制,所谓对象流也就是将对象的内容进行流化。可以对流化后的对象进行读写操作,也可将流化后的对象传输于网络之间。序列化是为了解决在对对象流进行读写操作时所引发的问题。序列化的实现:将需要被序列化的类实现Serializable接口,该接口没有需要实现的方法
如果是一个联合主键,三种方式:@Embeddable(主键类)@Id; @EmbeddedId; @Id@IdClass 第二种常用
核心开发接口:Configuration进行配置信息的管理,用来产生SessionFactory,可以在configure方法中指定hibernate配置文件(不是以默认的l保存它的配置文件时要制定),只需关注一个方法buildSessionFactory
sessionfactory里面保存着数据库的连接池,可以使用getCurrentSession方法获得session或openSession方法(3.2以后不建议使用)。前一个方法如果当前上下文没有session会开启一个新的session,只要调用commit方法再用第一个方法获得的就是新的,用途是界定事务边界
注意getCurrentSession()方法和openSession()方法不能混用,如果混用出错的可能性很大,最常见出错是使用getCurrentSession方法的同时还使用了close方法
上下文依据l中定义的属性<property name="hibernate.current_session_context_class">thread</property>,还有一种比
较常用的值是jta
thread使用connection去管理,设置auto_commit为false,遇到异常就rollback,没有异常则提交;对于分布式的情况下,多个数据库位于不同的主机上,就涉及到多个connection,往往需要别人为你做一个专门的事务管理器(一般应用服务器提供),管理分布式事务
所以事务分为两种:一种叫做connection事务,依赖数据库本身的;还有一种叫做JTA 事务。前者只针对一个数据库,后者是分布式环境
hibernate中对象的三种状态:transient;persistent;detached
transient:内存中有一个对象,没ID,缓存中也没有
persistent:内存中有,缓存中有,数据库有ID
detached:内存有,缓存没有,数据库有
session管理一个数据库的任务单元。hibernate中涉及很多非常细节的区别,但在实际应用中用得很少,请大家先享受些项目的乐趣,再来探讨这些细节问题,比如save和persist的区别,merge和evict等方法,refresh和lock等
load返回的是代理对象,等到真正用到对象的内容时才发出sql语句;get直接从数据库加载,不会延迟;还有就是不存在对应记录时表现不一样,get会立即报错
生成的动态代理类将所获取的实体类作为父类,然后直接产生的是二进制码,使用了javassist
update用来更新detached对象,更新完成后转为persistent状态;更新transient对象会报错,但是更新自己设定好id的transient对象可以;p状态更改部分字段,会检查缓存中的和数据库中的是否一样,如果不一样会立即更新,这实际上是所有字段一起更新
更新部分更改的字段:1.xml设定property标签的update属性,annotation设定@column
的updatable属性,不过这种方式很少用,不灵活;2.使用xml中的dynamic-update,JPA1.0 Annotation没有对应的属性,hibernate扩展?i.同一个sesion可以。跨session 不行,不过可以用merge(不重要)3.使用HQL
saveOrUpdate方法根据不同情况。clear方法用于清除缓存(get和load都会先去查缓存中有没有,没有才去数据库查)。
Hibernate强的地方就在于,一个PO脱离Session之后,还能持久化状态,再进入一个新的Session之后,就恢复状态管理的能力,但此时状态管理需要使用session.update或者session.saveOrUpdate,简单的来说,update和saveOrUpdate是用来对跨Session的PO进行状态管理的。
clear方法,无论是load还是get,都会首先查缓存(一级缓存),如果没有,才会去数据库查,调用clear方法可以强制清除session缓存
flush方法可以强制进行从内存到数据库的同步!

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。