hibernate学习之路

来源:互联网 发布:王者荣耀淘宝限定皮肤 编辑:程序博客网 时间:2024/05/16 05:41
2016.6.24----------------------------------------------------------------------------------
hibernate.hbm2ddl.auto=update 属性   ddl :数据定义语言


update只是更新表结构,但不能生成
请仔细参考一下hibernate.hbm2ddl.auto的配置参数,有以下四种:
validate:加载hibernate时,验证创建数据库表结构
create:在创建SessionFactory的时候,从schema中drop掉所以的表,再重新创建它们,这就是导致数据库表数据丢失的原因)
create-drop:加载hibernate时创建,退出是删除表结构
update:加载hibernate自动更新数据库结构




2016.6.25---------------------------------------
Annotation 分为两种  它符合JPA标准 
1、JPA
2、Hibernate-extension


JPA是一种标准,Hibernate是它的一种实现(作者被挖走,参考了Hibernate制定了EJB3与JPA标准),所以,标准的东西是放在java里面,而Hibernate是实现的具体的Jar包,在@Entity的引用中,我们引用的是java的jar,这样如果将Hibernate换掉,依然可以执行。


2016.6.27-----------------------------------------
一般来说,工程中,先建表,再建类。因为建完表之后,会经常做一些优化和改动,索引,触发器什么的。


使用log4j,日志输出。
log4j是slf4j标准的一种实现,但是slf4j本身也有一种实现,不常用。将slf4j的api jar包加入,加入log4j的实现,以及 slf4j对于log4j的转换jar包。在log4j.property配置文件里,对日志输出的内容进行控制。


注解,在实体类里面进行。


@Id,第一种方法:加在get方法上面(最好做法)。第二种:加在属性上面,但是破坏了面向对象的原则,因为hibernate会通过反射机制直接访问私有变量。


@Entity,在类名上面加,表示这是一个实体类。


@Basic,在get方法上面加,表示这是一个属性,默认的。


@Column(name=""),在get方法上面加,表示属性对应的字段。显示映射,不加表示相同。


@Transient,在get方法上面添加,意思是,该字段与数据库无关。(在xml配置里面,不写该属性就可以了)


@Temporal(Temporal.Type=) 指定一个时间精度,具体可到数据库相应字段的类型,xml要指定类型


@Enumerated(EnumType.STRING) 表示枚举类型。STRING表示文本,ORDINAL表示枚举值的下标。用xml的方式表示枚举,很麻烦,需要自定义,不考虑。


单元测试,可以加@Test,表示要测试的代码 @beforeclass注解,表示在编译之后执行。@afterclass,表示在@Test执行完之后执行。


表名和类名不一致怎么办?:可用@Table(name="")注解来标明,也可以在xml文件里面,有个class属性,也可以配置。具体可查参考文件




2016.6.28------------------------------------
ID 生成策略
XML:
<id name="id" type="long" column="cat_id">
        <generator class="org.hibernate.id.TableHiLoGenerator">
                <param name="table">uid_table</param>
                <param name="column">next_hi_value_column</param>
        </generator>
</id>


注解:@GeneratedValue(strategy=GenerationType.SEQUENCE,generator=""),写在@Id的下面







native 多用 让hibernate 自己选择
auto increment:mysql的native,自动递增,集群不要使用
sequence:ORCLE的native。
identity:sql server的native
hilo 和 sequence hilo 不用关。两种算法。


使用Annotatio注解,GeneratedValue,默认为auto,auto=native


@SequenceGenerator(name="A",sequenceName="B") 写在类名上。name生成器的名字,sequenceName 是squence的名字
@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="A") generator 指定具体使用哪一个生成器,默认是native








联合主键
XML:
写一个PK类,包含两个对象,然后这个PK类作为主键。
然后在xml里面 用这个表示联合主键
<composite-id name="声明" class="类的地址">
<key-property name="类属性的声明"></>   
</> 


注解:
第一种方法:
@Embeddable 写在主键类上(表示可以被嵌入的)
将@Id写在这个属性的get方法上(主键类),


第二种方法:
直接在主键属性的get方法上写 @EmbeddedId


第三种方法:
将类注解为@IdClass(value="主键类.class")(或者不写value=),然后不用在类里面声明主键类,直接声明两个联合主键,然后将这两个属性的get方法注解为@Id


2016.6.29-----------------------------------------------------------


JTA,即Java Transaction API,JTA允许应用程序执行分布式事务处理——在两个或多个网络计算机资源上访问并且更新数据。JDBC驱动程序的JTA支持极大地增强了数据访问能力。




session 是管理数据库的一个任务单元


save()---------------
在save时,hibernate 对象的三种状态


判断对象的三个条件:
1、有没有id
2、id在数据库中有没有
3、对象在缓存中有没有


trasient:内存中存在对象,没有ID,缓存中也没有
persistent:内存有,缓存有,数据库中有
detached:内存有,缓存没有,数据库有,有ID




对象没有id,trasient。save之后,对象变成persistent,session close之后,对象变成 detached。




delete-------------------
对象中有id就可以delete




load----get--------------
主要做查询功能,给定一个主键。
session.load(类.class,主键)   返回Object类型(代理对象)


session.get(类.class,主键)   返回Object类型


区别:


get :马上发送sql,取值,拼装对象,返回对象。


load:返回一个代理对象,然后当你用到需要去的值的时候,才会发送sql语句,去从数据库中取值。(延迟始化,动态代理模式)


当load/get同一个对象的时候,如果在同一个session下,那么只会查询一次,因为第一次查询之后,结果放到一级缓存里, 第二次查询之后


update-------------------


更新的对象必须有id。
更新默认更新所有的字段。


提交的时候,会检查缓存和数据库的对象的值是否一致。
一致的话,连更新都不更新。不一致的话,全都更新。


如何只更新部分字段?
一:在@Column(updatable=false)不允许更新该字段。(不灵活)
二:在映射文件class标签的属性中,加入dynamic-update="true",就可以只更新修改的字段。
(注意,当跨session的时候,第一次提交会从数据库中取出(手动取)比较,然后动态更新,但是第二次没有取出(没有手动取),也就没法比较,更不知道更新哪一个字段,所以是全更新。)(可以用merge(),先取(自动取),然后比较,然后update),这个属性,没有对应的注解。
三:使用HSQL(EJBQL)




2016.6.30-------------------------------


openSession 需要手动关闭session,getCurrentSession会在提交(commit)之后自动关闭。


session.saveOrUpdate 
当对象的状态为瞬时状态时,对对象进行save操作
当对象的状态为持久或托管状态时,对对象进行update操作


session.clear 清空缓存


session.flush() 强制同步当前的游离态的(当commit的时候,默认会flush)


2016.7.2-------------------------------


SchemaExport类,用于执行ddl语句。


2016.7.4-------------------------------


一对一:单向,双向,关联表(很少)


-------单向外键关联(某类的外键是其他类的主键):
注解,注明实体和id之后,在A类的getB对象方法上面 注明one to one,表示该实体A有外键是B的主键
xml:用manyt-to-one 标签,写在映射文件的class标签下。意识是 多对一,加上约束属性 unique="true",表示一对一。放在哪个类下,表示哪个类为多


-------双向外键关联(两个类拥有彼此的引用)
注解,两个类彼此引用,直接在get对象这个方法上 @OneToOne,这样生成的两张表都有对方的主键。如果不想这样,可以在@OneToOne的属性 mappedby="对象引用自己的属性的相应get方法的第四个字母开始"(通常与对象引用自己的字段一致,小知识点),表示对方是主导,对方拥有的我的主键。(双向外键关联,mappedby几乎为必设)。
xml:在单向的基础上,在除了many-to-many的另一个类映射文件里写上 <one-to-one name="本类的引用属性名" property-ref="另一个类的引用本类的属性名的相应get方法的第四个字母开始">,表示对方为主导




单向双向数据库是没区别的,但是java代码,单向只能通过丈夫找妻子。双向就可以通过一个找另一个。


-------单向的主键关联(不重要)








2016.7.5-------------------------------
column - precision 表示数字中的有效位,
column - scale 表示 从小数点右边的位数,默认为0,负数为小数点左边的位数




@JoinColumn(name="") 指定列名 在get方法上






2016.7.13------------------------------
query.setPropetries(Map) ----批量添加参数































0 0
原创粉丝点击