您的位置:首页 > 其它

hibernate学习之路

2016-07-24 16:54 218 查看
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) ----批量添加参数
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: