`

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;

分享到:
评论

相关推荐

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

    spring ,hibernate ,flex 应用注释配置的一个例子,里面有数据库脚本和说明文件

    hibernate应用包

    hibernate应用的包基本上都有包括annotation的部分

    annotation 应用

    annotation对hibernate的应用 博文链接:https://sanzang.iteye.com/blog/213269

    SSH2 annotation 实现struts2.1.6 spring2.5.6 hibernate3.3 全注解开发

    SSH2 annotation 实现struts2.1.6 spring2.5.6 hibernate3.3 全注解开发 hibernate延迟加载_懒加载 具体应用

    hibernate应用[包括示例,映射,主键自增,各种查询操作方式以及配置文档以及 Annotation示例]

    hibernate应用[包括示例,映射,主键自增,各种查询操作方式以及配置文档以及Annotation示例]

    Struts2+Spring2.5+Hibernate3全注解实例详解

    超级详细的SSH2项目实例详解,并且附带两个项目详解。两种注解实现方式。...在JavaEE企业级开发中,以SSH2框架为核心的应用非常广,大象根据项目实践经验,通过二个实例,详细的为大家讲解如何实现全注解式的开发。

    hibernate2

    Hibernate Annotation简单应用 接着上次的程序我们将其改为Annotation版本的 既然用Annotation那就要将其对应的包导入到工程 然后我们将entity包中的Student.hbm.xml文件删除,将hibernate.cfg.xml文件中的 改为...

    jsf1.2+spring3.0+hibernate3.3例子-单表增删改查

    使用jsf1.2+spring3.0+hibernate3.3实现集成,利用annotation实现自动对象管理注入,用户表的登录增删改查操作,包括验证码ajax集成,消息机制,国际化处理,自定义转换器,自定义验证器等 qq:38732796 欢迎讨论

    精通Java Web整合开发(第2版)

    12.4.1 为hibernate应用添加annotation支持532 12.4.2 annotation为hibernate改头换面532 12.4.3 hibernate中的常用annotation介绍534 12.4.4 一对一关联的annotation注解实现536 12.4.5 多对一单向关联的annotation...

    passwd002-spring-hibernate应用

    这是一个Dynamic Web Project,主要使用hibernate和spring框架,其中事务管理使用的是注解。 hibernate的版本:hibernate-distribution-3.6.6.Final; spring的版本:spring-framework-3.1.0.M2 。 注意:此项目没有...

    百度BAE环境下的ssh应用

    3、struts2的配置采用xml(目前不支持annotation),spring和hibernate使用annotation配置; 4、开发者下载该应用后,只需修改WebRoot\WEB-INF\applicationContext.xml,将其中数据库连接信息修改为自己的即可;

    Hibernate+中文文档

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    hibernate3.2中文文档(chm格式)

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    HibernateAPI中文版.chm

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    Hibernate中文详细学习文档

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    Hibernate 中文 html 帮助文档

    1.2. 第一部分 - 第一个Hibernate应用程序 1.2.1. 第一个class 1.2.2. 映射文件 1.2.3. Hibernate配置 1.2.4. 用Ant构建 1.2.5. 启动和辅助类 1.2.6. 加载并存储对象 1.3. 第二部分 - 关联映射 1.3.1. ...

    基于Java的Hibernate MySQL数据持久化示例设计源码

    该示例包含了基于XML和Annotation的Hibernate配置,涵盖了one-to-one、one-to-many、many-to-many映射关系的配置,并提供了独立的测试用例。适合用于学习和实践Java和Hibernate技术,以及开发基于MySQL的数据持久化...

Global site tag (gtag.js) - Google Analytics