`

Hibernate Annotation应用

    博客分类:
  • J2EE
 
阅读更多
@Entity
@Table
@Id
@Column
@Transient  //透明,不加入影射
@Temporal(TemporalType.DATE)   //时间刻度、针度
@Enumerated(EnumType.STRING)   //枚举类型
ID生成策略
@Id
@TableGenerator(name = "tab_pk", table = "PKS_TABLE", pkColumnName = "G_KEY", pkColumnValue = "EXAM_ONLINETEST_PK", valueColumnName = "G_VALUE", allocationSize = 1)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "tab_pk")
@OrderBy("id")

strategy = GenerationType.TABLE  //策略
AUTO mysql IDENTITY sql server orcel SEQUENCE

在实体前加入策略
@SequenceGenerator(name="gzmetro",sequenceName="gzmetro_db")
方法前
@GenericGenerator(strategy=GenerationType.SEQUENCE,generator="gzmetro")

联合主键(三种方法)
1、主键类 @Embeddable  //注解嵌入类
   主键类属性方法 @Id
2、主键类属性方法 @EmbeddedId //声明成联合组件
3、在多个属性方法 @Id @IdClass(value=Test.Class)

hibernate 三种状态
Transient 瞬时 对象创建 对象不会被持久化到数据库中,也不会被赋予持久化标识
Persistent 持久 内存、数据库存在 在数据库中有对应的记录,并拥有一个持久化标识
Detached  脱管 缓存 与持久(Persistent)对象关联的Session被关闭后,对象就变为脱管(Detached)的

Session session = sessionFactory.openSession();
Session session = sessionFactory.getCurrentSession();  //上下文找,如果没有,自动创建
getCurrentSession的话会自动关闭,而openSession需要你手动关闭
Student t= new Struden();
t.setId(1);
session.delete(t);   //必须有Id
load 返回代理对象,调用时加载
get 直接发送sql查询,加载数据,不会延迟
update 更新Transient时会报错,但自己设定数据存在对应对象Id不会报错
merge(s) 首先load查询后,update可以是缓存对象
saveOrUpdate
clear()  清除缓存(hibernate首先查询缓存)
flush()  强制缓存与数据库同步
evict() 从一级缓存中去掉这些对象及其集合

SchemaExport 输出sql语句
new SchemaExport(new AnnotationConfiguration().configure()).create(true, true);

关系映射
一对一
   单向(外键关联)
   @OneToOne
   @JoinColumn(name="QUESTIONPOOL_ID")  //指定生成外键ID
   单向(外键关联xml)
   <money-to-one name="Student" column="student_id" unique="true" />
   双向(外键关联)
   @OneToOne
   @JoinColumn(name="QUESTIONPOOL_ID")  //指定生成外键ID
   @OneToOne(mappedBy="questionpool")   //对方关联属性
   双向(外键关联xml)
   <money-to-one name="Student" column="student_id" unique="true" />
   <one-to-one name="person"  property-ref="student"/>
   单向(主键关联)
   @OneToOne
   @PrimaryKeyJoinColumn
   单向(主键关联xml)
   <id name="id" column="personId">
        <generator class="foreign">
            <param name="property">person</param>
        </generator>
    </id>
   <one-to-one name="person" constrained="true"/>
   双向(主键关联)
   @OneToOne
   @PrimaryKeyJoinColumn
   @OneToOne
   @PrimaryKeyJoinColumn
   双向(主键关联xml)
   <class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <one-to-one name="address"/>
</class>
<class name="Address">
    <id name="id" column="personId">
        <generator class="foreign">
            <param name="property">person</param>
        </generator>
    </id>
    <one-to-one name="person"
        constrained="true"/>
</class>
联合主键
@OneToOne
@JoinColumns(
     {
@JoinColumn(name="wifeId", referencedColumnName="id"),
@JoinColumn(name="wifeName", referencedColumnName="name")
     }
)
  组件映射
  一个类是另外一个类组成部分,产生一张表
  @Embeddable  //注解嵌入类
  采用xml
  <component name="Name" class="eg.Name">
<property name="initial"/>
  </component>
  属性重写
  @Embeddable
  @AttributeOverrides({
@AttributeOverride(name="name",column=@Column(name="bornCountryName"))
   }
  )
  采用xml
  <component name="Name" class="eg.Name" unique="true">
        <parent name="namedPerson"/> <!-- reference back to the Person -->
        <property name="initial"/>
</component>

一对多
   单向(一对多关联)
    @OneToMany
    @JoinColumn(name="Group_ID")  //必须有,否则会产生中间表,当作many-to-many
    xml文件配制
    <class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses">
        <key column="personId"
            not-null="true"/>
        <one-to-many class="Address"/>
    </set>
    </class>

    <class name="Address">
    <id name="id" column="addressId">
<generator class="native"/>
    </id>
</class>
   
多对一
   单向(多对一关联)多的一方加外键
   @ManyToOne
   //@JoinColumn(name="Group_ID")
   private Group getGroup(){return group;}
   xml配制
   <class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <many-to-one name="address"
        column="addressId"
        not-null="true"/>
    </class>

<class name="Address">
    <id name="id" column="addressId">
<generator class="native"/>
    </id>
</class>

一对多,多对一双向关联
@OneToMany(mappedBy="group")
@JoinColumn(name="Group_ID")
@ManyToOne
xml配制
<class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <many-to-one name="address"
        column="addressId"
        not-null="true"/>
</class>

<class name="Address">
    <id name="id" column="addressId">
        <generator class="native"/>
    </id>
    <set name="people" inverse="true">
        <key column="addressId"/>
        <one-to-many class="Person"/>
    </set>
</class>

多对多
  单向多对多
  @ManyToMany
    @JoinTable(name="center_tbales",joinColumns={
    @JoinColumn(name="Teacher_id")
    },inverseJoinColumns={@JoinColumn(name="Student_id")})
   //@JoinTable(name = "base_security_user_role", joinColumns = { @JoinColumn(name = "roleid") }, inverseJoinColumns = { @JoinColumn(name = "userid") })
   xml配制
   <class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses" table="PersonAddress">
        <key column="personId"/>
        <many-to-many column="addressId"
            class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
<generator class="native"/>
    </id>
</class>
   双向多对多
   @ManyToMany
    @JoinTable(name="center_tbales",joinColumns={
    @JoinColumn(name="Teacher_id")
    },inverseJoinColumns={@JoinColumn(name="Student_id")})
    @ManyToMany(mappedBy="Student_id")
    xml配制
    <class name="Person">
    <id name="id" column="personId">
        <generator class="native"/>
    </id>
    <set name="addresses"  table="PersonAddress">
        <key column="personId"/>
        <many-to-many column="addressId"
            class="Address"/>
    </set>
</class>

<class name="Address">
    <id name="id" column="addressId">
<generator class="native"/>
    </id>
    <set name="people" inverse="true"  table="PersonAddress">
<key column="addressId"/>
<many-to-many column="personId"
    class="Person"/>
    </set>
</class>

CRUD
存在关联,只save一个对象,需要做如下操作  cascade管CUD
双向多对一  @ManyToOne(cascade ={CascadeType.ALL}) //增删改查,级联关联对象
双向一对多  @OneToMany(mappedBy="group",cascade ={CascadeType.ALL}) //一这方要设置双向关联
  User u = new User();
  u.setName("aaa");
  Group g = new Goup();
  g.setName("bbb");
  g.getUsers().add(u);
  u.setGroup(g);
  seesion.save(g);
optional 属性用于定义关联关系的从类对象是否必须存在。如果设置为 false,那么该属性就不能设置为 null.默认值是 true
存在关联,get()、load()一个对象时  fetch管R
@ManyToOne 默认会把一方取出(fetch=FetchType.EAGER)
@OneToMany 默认不会把多的一方取出(fetch=FetchType.LAZY)
@OneToMany(mappedBy="group",cascade ={CascadeType.ALL},fetch=FetchType.EAGER) //把多一方取出
如果将fetch=FetchType.LAZY,对象调用时加载,如果sesion关闭时,就会报赖加载异常。
xml配制 (inverse="true")
更新cascade = { CascadeType.PERSIST, CascadeType.MERGE }//新增、修改
jap 标准新增、修改方法 persist merge
级联关系 delete(u) 全部会删除双向关联数据(u,g)内全部数据
解决办法
1、打破关联 u.setGroup(null);
2、createQuery 方法

集合映射
List  与set一样,@OneToMany 如果想对数据排序可以用@OrderBy("name ASC")
Map  
@OneToMany(mappedBy="group",cascade ={CascadeType.ALL})
@MapKey(name="id")

继承映射
生成一张表
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="discrininator",discriminatorType=DiscriminatorType.STRING)  //区分相同的属性
@DiscriminatorValue("person") //区分父类类型
@DiscriminatorValue("student") //区分子类
@DiscriminatorValue("teacher")//区分子类

子类包含所有父类全部属性
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
@TableGenerator(name = "tab_pk", table = "PKS_TABLE", pkColumnName = "G_KEY", pkColumnValue = "EXAM_ONLINETEST_PK", valueColumnName = "G_VALUE", allocationSize = 1)
@Entity //子类只要设置Entity

子类是扩展,父类没有,独有的
@Inheritance(strategy=InheritanceType.JOINED)
@Entity //子类只要设置Entity

HQL>EJBQL(jpal 1.0)>QBC(Qeary by criteria)>QBE(QUERY BY Eample)
当前主用habernate 编程接口
select distinct c from Catecy c //查找主主键不同对象
from Catecy c where c.id>:min and c.id<:max //q.setParame("min"2).setParame("max",8)
分页
q.setMaxResults(4).setFirstResult(2);
查询部分数据
Query q = session.createQuery("select c.id,  c.name from Category c order by c.name desc");
List<Object[]> categories = (List<Object[]>)q.list();
for(Object[] o : categories) {
System.out.println(o[0] + "-" + o[1]);
}
关联查询
from Topic t where t.category.id = 1
关联导航
from Msg m where m.topic.category.id = 1
视图(VO Value Object/DTO data transfer object)
select new com.bjsxt.hibernate.MsgInfo(m.id, m.cont, m.topic.title, m.topic.category.name) from Msg
join  //因为有可能存在多个成员变量(同一个类),需要指明用哪一个成员变量的连接条件来做连接
select t.title, c.name from Topic t join t.category c  //t.category 而不是Category c
uniqueResult
Query q = session.createQuery("from Msg m where m = :MsgToSearch "); //不重要
Msg m = new Msg();
m.setId(1);
q.setParameter("MsgToSearch", m);

Msg mResult = (Msg)q.uniqueResult();
单行函数
count、max、 min、avg、sum
between ? and ?、in、is not null

is empty and is not empty
from Topic t where t.msgs is empty  //集合是否为空

like (% 0个或多个,_一个)
from Topic t where t.title like '%5'

多行函数
lower、upper、trim、oncat、length、abs、sqrt、mod

数据库系统关键词
select current_date, current_time, current_timestamp, t.id from Topic t

日期比较
Query q = session.createQuery("from Topic t where t.createDate < :date");
q.setParameter("date", new Date());

分组
select t.title, count(*) from Topic t group by t.title
select t.title, count(*) from Topic t group by t.title having count(*) >= 1

子查询
from Topic t where t.id < (select avg(t.id) from Topic t)
from Topic t where t.id < ALL (select t.id from Topic t where mod(t.id, 2)= 0)  //结果所有值==min(t.id)

用in 可以实现exists的功能
但是exists执行效率高
from Topic t where not exists (select m.id from Msg m where m.topic.id=t.id)

//update and delete
//规范并没有说明是不是要更新persistent object,所以如果要使用,建议在单独的trasaction中执行
update Topic t set t.title = upper(t.title)

命名查询
在实体添加HQL语句
@NamedQueries(
{
@NamedQuery(name="topic.selectCertainTopic", query="from Topic t where t.id = :id")
}
)
Query q = session.getNamedQuery("topic.selectCertainTopic");
q.setParameter("id", 5);
Topic t = (Topic)q.uniqueResult();

Native(了解)//数据库本身的SQL语句
SQLQuery q = session.createSQLQuery("select * from category limit 2,4").addEntity(Category.class);
@NamedNativeQueries(
{
@NamedNativeQuery(name="topic.select2_5Topic", query="select * from topic limit 2, 5")
}
)
//hibernate尚未实现JPA命名的NativeSQL

orcle 存储过程(PROCEDURE)
CallableStatement cs = session
                                .connection()
                                .prepareCall("{call modifyapppnumber_remain(?)}");
                        cs.setString(1, foundationid);
                        cs.execute();

QBC  //标准、约束 Criteria  面向对象
Criteria c = session.createCriteria(Topic.class) //from Topic
.add(Restrictions.gt("id", 2)) //greater than = id > 2
.add(Restrictions.lt("id",) //little than = id < 8
.add(Restrictions.like("title", "t_")) 
.createCriteria("category")          //创建连接 join
.add(Restrictions.between("id", 3, 5)) //category.id >= 3 and category.id <=5

//DetachedCriterea 更灵活,脱离session管理,需要查询就绑定session

QBE(QBC一部分,子集query by  Eample)
//is empty and is not empty
//query by criteria query by example
Topic tExample = new Topic();
tExample.setTitle("T_");  //榜样对象

Example e = Example.create(tExample)
.ignoreCase().enableLike();
Criteria c = session.createCriteria(Topic.class)
.add(Restrictions.gt("id", 2))
.add(Restrictions.lt("id",)
.add(e)
;


for(Object o : c.list()) {
Topic t = (Topic)o;
System.out.println(t.getId() + "-" + t.getTitle());
}

性能优化
clear()应用,分页或遍历查询 
内存泄露 //部分资源没有回收,实际应用内存泄漏
1+N
不调用关联、解决产生多条sql语句
1、fetch=FetchType.LAZY 
2、List<Topic> topics = (List<Topic>)session.createCriteria(Topic.class).list();
3、@BatchSize(size=10)  //关联实体上
4、List<Topic> topics = (List<Topic>)session.createQuery("from Topic t left join fetch t.category c").list()

Query的遍历方式
1、query.list();2、query.iterate()
区别 1、iterate()首页取id,调用时才取相关属性 2、执行相同两次遍历,iterate从缓存中查找,产生一条sql,list每次调用查询一次

缓存
在内存分配一部分空间,服务本应该硬盘读取改变直接从内存中读取
一级缓存(session级别)

二级缓存(总缓存,SessionFactory所有缓存共有)
打开二级缓存(SessionFactory)
hibernate配制
hibernate.cfg.xml
<property name="cache.use_second_level_cache">true</property>
<property name="cache.provider_class">org.hibernate.cache.EhCacheProvider</property>
添加ehcache.xml
//默认的缓存策略.
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)  //hibernate 如果查询条件一样,先从缓存中查询
load、iterate使用二级缓存,list 刷新二级缓存,往二级缓存存入数据,查询不使用二级缓存

三级缓存(查询缓存)
//list使用setCacheable(true)使用二级缓存
List<Category> categories = (List<Category>)session.createQuery("from Category").setCacheable(true).list();

缓存算法
LRU、LFU、FIFO
1、least Recently Used (最近不常用)
2、Least Frequenty Used(命中率高低)
3、First in First out (先进先出)
在ehcache.xml文件添加 memoryStoreEvictionPolicy="LRU" (defaultCache)

事务并发处理 (事务ACID)
原子性、一致性、独立性、持久性
1、丢失更新(lost update)  插销事务丢失
2、脏读(dirtyread) 读取另外事务没有提交的数据
3、不可重复读(non-repeatable read) 同一个事务读取两次,每一个值不一样
第二类丢失更新(second lost update problem)不可重复读的特殊情况
4、幻读(phantorn read)  读取时,更外一个事务向数据库里插入新数据

数据库的事务隔离机制
1、TRANSACTION_NONE               //read-uncommitted
2、TRANSACTION_READ_COMMITTED  避免脏读,只读取提交数据   //read-committed
4、TRANSACTION_REPEATABLE_READ
8、TRANSACTION_SERIALIZABLE 解决一切问题,两个事务读取结果不一样 //排队

hibernate.connection.isolation=2
用悲观锁解决repeatable read的(依赖数据库)使用数据里锁
Account a = (Account)session.load(Account.class, 1, LockMode.UPGRADE);   
LockMode.UPGRADE_NOWAIT //orcle 数据独有锁
乐观锁,在程序内添加锁,效率高   使用版本锁
在实体内添加版本控制属性(每次更新增加)
@Version
private int version;

分享到:
评论

相关推荐

    Hibernate Annotation入门

    接下来,我们将逐步创建一个简单的Hibernate Annotation应用。首先,定义一个实体类,比如`User`: ```java @Entity @Table(name = "users") public class User { @Id @GeneratedValue(strategy = GenerationType...

    hibernate annotation 中文文档

    以上仅是Hibernate Annotation部分核心概念的简述,实际使用中还需要根据项目需求和最佳实践来灵活应用。深入理解和熟练掌握这些注解,能极大地提升开发效率并优化数据库操作。阅读《Hibernate Annotation 中文文档...

    Hibernate Annotation 中文文档

    随着Java社区对注解的广泛接受,Hibernate Annotation已经成为现代Java应用开发的标准实践,逐渐取代了传统的XML映射方式。 以上是对Hibernate Annotation的简要介绍,深入理解和熟练应用这些注解,将有助于提升你...

    Hibernate Annotation 学习笔记

    《Hibernate Annotation 学习笔记》 在Java的持久化框架中,Hibernate以其强大的功能和易用性成为开发者首选之一。而Hibernate Annotation则是Hibernate提供的一种基于注解的实体映射方式,它极大地简化了传统XML...

    sping hibernate Annotation(注释配置) demo(例子)

    Spring 和 Hibernate 是两个非常重要的 Java 开发框架,它们在企业级应用开发中广泛使用。本文将深入探讨如何结合 Spring 的注解配置与 Hibernate 实现数据持久化,通过一个实际的 demo 示例来阐述整个过程。 首先...

    hibernate annotation api chm文件

    总结,Hibernate Annotation API是Hibernate ORM的重要组成部分,它极大地简化了Java应用的数据库交互。通过合理运用注解,开发者能够高效地管理数据层,实现面向对象编程和关系型数据库之间的无缝对接。在实际开发...

    Hibernate Annotation 笔记 总结 注解

    【标题】:深入理解Hibernate Annotation及其使用 【描述】:本文将全面介绍Hibernate Annotation的使用,包括事务管理和声明式事务处理,以及如何通过注解简化数据库持久化操作。 【标签】:Hibernate, ...

    Hibernate Annotation 唯一外键一对一双向关联

    通过阅读《Hibernate_annotation_1to1_foreignKey》文档或博客,你可以更详细地了解如何配置和使用这种关联,包括示例代码、注意事项以及可能遇到的问题和解决方案。理解并熟练运用这些知识,能帮助你在使用...

    hibernate-annotation

    在传统的Hibernate应用中,我们通常使用XML文件来描述对象和表之间的映射关系。然而,随着Java 5的发布,注解成为了一种更简洁、更直观的元数据表示方式。Hibernate注解就是利用这种方式,将对象的映射信息直接写在...

    hibernate annotation jar

    【标题】:“Hibernate Annotation JAR” 【描述】:“Hibernate 3.3 Annotation JAR”指的是Hibernate框架的一个特定版本,即3.3版本中用于对象关系映射(ORM)的注解库。Hibernate是一个广泛使用的Java库,它允许...

    hibernate-Annotation.jar

    Annotation注解可以直接应用在类和类的属性上,减少了额外的配置文件需求,提升了开发效率。 1. **实体类注解@Entity** `@Entity` 注解标记一个Java类为Hibernate管理的实体类,表示这个类将映射到数据库的一个表...

    Hibernate Annotation笔记

    ### Hibernate Annotation概述与实践 #### 一、Hibernate Annotation简介 Hibernate作为Java领域内最流行的ORM框架之一,在过去的几年中经历了显著的发展,已经成为Java数据库持久化的事实标准。它不仅功能强大,...

    hibernate annotation spring 中文参考文档

    在"hibernate_annotation"这个部分,我们关注的是Hibernate的注解配置方式,这种方式比传统的XML配置更加简洁直观。Hibernate注解提供了如@Entity、@Table、@Id、@GeneratedValue等,它们分别用于定义实体类、指定...

    hibernate annotation 3.40

    《Hibernate Annotation 3.4.0:Java持久化框架的核心技术解析》 Hibernate Annotation是...通过实际项目中的应用和实践,我们可以更好地理解Hibernate Annotation的强大功能,从而在开发过程中发挥出它的最大价值。

    hibernate annotation学习文档

    ### Hibernate Annotation 学习知识点详解 #### 一、概述 Hibernate 是一款开源的对象关系映射 (ORM) 巨具,它极大地简化了 Java 应用程序与数据库之间的交互过程。Hibernate 支持多种注解(Annotation),使得...

    hibernate 中文文档 and _annotation.chm

    3. 注解(Annotation)在Hibernate中的应用: - @Entity:标记一个Java类为数据库中的一个表,表示该类是实体类。 - @Table:指定实体类对应的数据库表名。 - @Id:标识类中的主键字段,可以配合@GeneratedValue...

    java SSH项目 hibernate annotation

    Java SSH项目是基于三个主要框架——Struts、Spring和Hibernate构建的企业级Web应用程序。这个项目中,Hibernate作为ORM(对象关系映射)工具被用来处理数据库操作,而使用了注解方式来配置Hibernate,这是一种更加...

Global site tag (gtag.js) - Google Analytics