前言:

  最近正在学习Hibernate通过注解(annotation)来管理映射关系,以前都是通过XML映射文件。下面拿个小例子说一下。

数据库物理模型:

数据库的描述:

  一篇博客随笔可以分到不同的类中,一个类中又可以包含许多不同的博客随笔。就如同博客园的设计。也就是上图中 博客-组 和 博客-消息是多对多的映射。

Hibernate关联映射方式:

  双向N-N关联, 两端都要使用Set集合属性,两端都增加对集合属性的访问。双向N-N关联没有太多的选择,只能采用连接表来建立两个实体之间的关联关系。

生成sql语句:

drop table if exists blogGroup;

drop table if exists blogMessage;

drop table if exists groupMessage;

create table blogGroup
(
groupId int not null auto_increment,
groupName varchar(50),
primary key (groupId)
); create table blogMessage
(
msgId int not null auto_increment,
msgContent varchar(1000),
primary key (msgId)
); create table groupMessage
(
groupId int not null,
msgId int not null,
primary key (groupId, msgId)
); alter table groupMessage add constraint FK_Relationship_1 foreign key (groupId)
references blogGroup (groupId) on delete restrict on update restrict; alter table groupMessage add constraint FK_Relationship_2 foreign key (msgId)
references blogMessage (msgId) on delete restrict on update restrict;

PO(persisent object)类:

  PO = POJO(plain ordinary java object) + 注解

PO : BlogGroup

package com.blog.entriy;

@Entity
@Table(name="blogGroup")
public class BlogGroup implements Serializable{
@Id
@Column(name="groupId")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int groupId;
@Column(name="groupName")
private String groupName; //fetch=FetchType.EAGER 抓取实体时,立即抓取关联实体,我用的get()方式加载一个对象
//ascadeType.PERSIST, CascadeType.MERGE, 分别是更新和保存时级联
@ManyToMany(targetEntity=BlogMessage.class, cascade={CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
@JoinTable(name="groupMessage",
joinColumns=@JoinColumn(name="groupId", referencedColumnName="groupId"),
inverseJoinColumns=@JoinColumn(name="msgId", referencedColumnName="msgId")
)
private Set<BlogMessage> message = new HashSet<BlogMessage>(); public int getGroupId() {
return groupId;
}
public void setGroupId(int groupId) {
this.groupId = groupId;
}
public String getGroupName() {
return groupName;
}
public void setGroupName(String groupName) {
this.groupName = groupName;
}
public Set<BlogMessage> getMessage() {
return message;
}
public void setMessage(Set<BlogMessage> message) {
this.message = message;
}
}

PO : BlogMessage

package com.blog.entriy;

@Entity
@Table(name="blogMessage")
public class BlogMessage implements Serializable{
@Id
@Column(name="msgId")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int msgId;
@Column(name="msgContent")
private String msgContent; @ManyToMany(targetEntity=BlogGroup.class)
@JoinTable(name="groupMessage",
joinColumns=@JoinColumn(name="msgId", referencedColumnName="msgId"),
inverseJoinColumns=@JoinColumn(name="groupId", referencedColumnName="groupId")
)
private Set<BlogGroup> group = new HashSet<BlogGroup>(); public int getMsgId() {
return msgId;
} public void setMsgId(int msgId) {
this.msgId = msgId;
}
public String getMsgContent() {
return msgContent;
}
public void setMsgContent(String msgContent) {
this.msgContent = msgContent;
}
public Set<BlogGroup> getGroup() {
return group;
}
public void setGroup(Set<BlogGroup> group) {
this.group = group;
}
}

Hibernate中数据的三种状态

  补充一下:Dao层的操作,需要掌握Hibernate中数据的三种状态

  1,  临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;

  2,  持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;

  3,  游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。

  

盗图两张

  1.对于刚创建的一个对象,如果session中和数据库中都不存在该对象,那么该对象就是瞬时对象(Transient)。

  2.瞬时对象调用save方法,或者离线对象调用update方法可以使该对象变成持久化对象,如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较,如果不同,则发送一条update语句,否则就不会发送语句。

  3.离线对象就是,数据库存在该对象,但是该对象又没有被session所托管。

DAO层:

  分别测试了不同方式的插入操作, 以及更新和删除。具体看函数的实现。

package com.blog.dao;

public class BlogDao {
private SessionFactory sessionFactory; public Session getSession() {
return sessionFactory.getCurrentSession();
} public SessionFactory getSessionFactory() {
return sessionFactory;
} public void setSessionFactory(SessionFactory sessionFactory) {
this.sessionFactory = sessionFactory;
} public BlogGroup get_test(int id){
BlogGroup blogGroup = null;
Session session = null;
Transaction tran = null;
try{
session = this.getSession();
tran = session.beginTransaction();
blogGroup = (BlogGroup)session.get(BlogGroup.class, id);
tran.commit();
} catch(Exception e){
System.out.println(e.toString());
tran.rollback();
}
return blogGroup;
}

  //只插入一端博客-组(BlogGroup)
public void insert_test1(){
Session session = null;
Transaction tran = null;
try{
session = this.getSession();
tran = session.beginTransaction();
BlogGroup blogGroup = new BlogGroup();
blogGroup.setGroupName("html");
session.save(blogGroup);
tran.commit();
} catch(Exception e){
System.out.println(e.toString());
tran.rollback();
}
}
//同时插入两端(博客-组 和 博客-消息),没有用cascade级联操作,所以BlogGroup和BlogMessage两端都要先持久化
public void insert_test2(){
Session session = null;
Transaction tran = null;
try{
session = this.getSession();
tran = session.beginTransaction();
BlogGroup blogGroup = new BlogGroup();
blogGroup.setGroupName("c++");
BlogMessage blogMessage = new BlogMessage();
blogMessage.setMsgContent("c++ primer");
session.save(blogMessage);
Set<BlogMessage> message = new HashSet<BlogMessage>();
message.add(blogMessage);
blogGroup.setMessage(message);
session.save(blogGroup);
tran.commit();
} catch(Exception e){
System.out.println(e.toString());
tran.rollback();
}
}
//同时插入两端,对BlogGroup设置persist级联操作 @ManyToMany(cascade={CascadeType.PERSIST})
public void insert_test3(){
Session session = null;
Transaction tran = null;
try{
session = this.getSession();
tran = session.beginTransaction();
BlogGroup blogGroup = new BlogGroup();
blogGroup.setGroupName("javaee");
BlogMessage blogMessage = new BlogMessage();
blogMessage.setMsgContent("Spring+hibernate+struct");
blogGroup.getMessage().add(blogMessage);
session.persist(blogGroup);
tran.commit();
} catch(Exception e){
System.out.println(e.toString());
tran.rollback();
}
}
//向博客-组(BlogGroup)添加新的 博客-消息(BlogMessage),对BlogGroup再添加一个更新的级联操作,CascadeType.MERGE
public void update_test(){
BlogGroup blogGroup = get_test(1);//得到blogGroup主键为1的group
Session session = null;
Transaction tran = null;
try{
session = this.getSession();
tran = session.beginTransaction();
BlogMessage blogMessage = new BlogMessage();
blogMessage.setMsgContent("css 学习笔记");
blogGroup.getMessage().add(blogMessage);
session.merge(blogGroup);
tran.commit();
} catch(Exception e){
System.out.println(e.toString());
tran.rollback();
}
}
//删除某一个博客-组(BlogGroup),因为不能删除我们写的博客消息,所以不能有删除的级联操作
  //注意:我们有三个表,分别是“博客-组”, “博客-消息”,“组-消息”,当从“博客-组”中删除一条记录X时,表“博客-消息”中和X相关的数据不会删除,
  //因为我们没有设置级联关系,但是表“组-消息”中和X相关的数据会删除干净,表“组-消息”是中间关联表,一方被移除之后,该表相关数据自然被移除。
public void delete_test(){
BlogGroup blogGroup = get_test(1);//得到blogGroup主键为1的group
Session session = null;
Transaction tran = null;
try{
session = this.getSession();
tran = session.beginTransaction();
session.delete(blogGroup);
tran.commit();
} catch(Exception e){
System.out.println(e.toString());
tran.rollback();
}
}
}

罗列所有持久化类的类名:

  hibernate.cfg.xml中配置:

 <hibernate-configuration>
<session-factory>
   ...  

      <mapping class="com.blog.entriy.BlogGroup"/>
      <mapping class="com.blog.entriy.BlogMessage"/>

     ...
</session-factory>
</hibernate-configuration>

  如果整合了Spring:application.cfg.xml中的配置<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">

    <!--Spring中: 包扫描的方式加载注解类 -->
<property name="annotatedClasses">
<list>
<value>com.blog.entriy.BlogGroup</value>
<value>com.blog.entriy.BlogMessage</value>
</list>
</property> <!-- 通过配置文件的方式获取数据源,只是通过XML管理映射方式的。
<property name="mappingResources">
<list>
以下用来列出所有的PO映射文件
<value>publishparty.cfg.xml</value>
</list>
</property> -->
     .....
</bean>

Hibernate注解的更多相关文章

  1. Hibernate注解----关联映射注解以及课程总结详解----图片版本

    上一篇,记录了Hibernate注解----类级别注解以及属性注解详解 ,我们这一节主要讲解的是Hibernate注解----关联映射注解以及课程总结详解. 本节的主要内容: 第3章 关联映射注解 3 ...

  2. Hibernate注解----类级别注解以及属性注解详解----图片版本

    这篇文章是我在慕课网上学习Hibernate注解的时候进行手机以及整理的笔记. 今天把它分享给大家,希望对大家有用.可以进行收藏,然后需要的时候进行对照一下即可.这样能起到一个查阅的作用. 本文主要讲 ...

  3. hibernate注解随笔—10月8日

    hibernate注解(herbinate4 jar包注解可用,使用hibernate3.3注解失败) 如果javabean与数据库中表名一致(不区分大小写),则注解不用写@Table(name=&q ...

  4. Hibernate注解使用以及Spring整合

    Hibernate注解使用以及Spring整合 原文转自:http://wanqiufeng.blog.51cto.com/409430/484739 (1) 简介: 在过去几年里,Hibernate ...

  5. Hibernate注解映射联合主键的三种主要方式

    今天在做项目的时候,一个中间表没有主键,所有在创建实体的时候也未加组件,结果报以下错误: org.springframework.beans.factory.BeanCreationException ...

  6. 【maven + hibernate(注解) +spring +springMVC】 使用maven搭建项目

    研究,百度,查资料+好友帮助,使用MyEcplise2015工具,通过maven搭建hibernate+springMVC+spring的项目,数据库采用MySql5.5 不过使用的版本会在项目搭建过 ...

  7. Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长:

    Hibernate注解映射sequence时出现无序增长问题+hibernate 映射 oracle ID自动增长: 通过Hibernate注解的方式映射oracel数据库的sequence主键生成器 ...

  8. 。。。Hibernate注解配置的注意事项。。。

    今天本来打算录视频的,突然遇到一个拦路虎,Hibernate注解配置,有一个注意点:要么都在属性上面注解配置,要么都在getXX()方法上面用注解配置,要不然就会报错: Caused by: org. ...

  9. Hibernate注解错误之- org.hibernate.MappingException: Could not determine type for:

    Hibernate 注解 @OneToOne 时候,出现以下错误,经调试,发现 注解要么全部放在字段上,要么全部放在get方法上,不能混合使用! org.hibernate.MappingExcept ...

  10. Hibernate 注解 没有加@Column一样会在数据库创建这些字段

    Hibernate 注解 没有加@Column一样会在数据库创建这些字段 如下一个注解类: package com.hyy.hibernate.one_to_many.domain; import j ...

随机推荐

  1. 阅读jquery源码与js依赖加载的模块化!

    阅读源码肯定是先下载有注释的源码 我也是醉了,10309 行代码,在陆续续的一个月之内,看完了,虽有收获但收获不大, 直到又一次看jquery的github,怎么会有cmd????没听过使用jquer ...

  2. xpath tutorial

    http://www.cnblogs.com/yukaizhao/archive/2011/07/25/xpath.html http://www.w3schools.com/xpath/defaul ...

  3. appium的几点总结

    原文链接:http://blog.csdn.net/bear_w/article/details/50345283 1. 建立session时常用命令: DesiredCapabilities cap ...

  4. HTML5新特性——HTML 5 Canvas vs. SVG

    Canvas 和 SVG 都允许您在浏览器中创建图形,但是它们在根本上是不同的. SVG SVG 是一种使用 XML 描述 2D 图形的语言. SVG 基于 XML,这意味着 SVG DOM 中的每个 ...

  5. oracle触发器和存储过程的格式

    最近接到一个任务要根据一个表来转移另一个表的数据到第三个表.想了想,用决定用触发器+存储过程的方式来做.有些时间没有写存储过程和触发器了,查了一下资料,确定了oracle的触发器和存储过程的格式. 触 ...

  6. phpMoadmin CVE-2015-2208 远程代码执行漏洞分析

    原文:http://www.thinkings.org/2015/03/05/cve-2015-2208-phpmoadmin-exec-vul.html phpMoAdmin 是一个用PHP 开发的 ...

  7. oracle 全文检索创建脚本示例

    --创建全文索引 grant execute on ctx_ddl to username;--使用其他帐号对username授权exec ctx_ddl.create_preference('my_ ...

  8. C#_基础:委托速讲

    1定义:委托=函数指针 C# public delegate void Test(string str); 等价C++ public void (*Test)(string str): 委托赋值(初始 ...

  9. 免费开源分布式系统日志收集框架 Exceptionless

    前言 从去年就答应过Eric(Exceptionless的作者之一),在中国会帮助给 Exceptionless 做推广,但是由于各种原因一直没有做这件事情,在此对Eric表示歉意.:) Except ...

  10. 轻量级通信引擎StriveEngine —— C/S通信demo(2) —— 使用二进制协议 (附源码)

    在网络上,交互的双方基于TCP或UDP进行通信,通信协议的格式通常分为两类:文本消息.二进制消息. 文本协议相对简单,通常使用一个特殊的标记符作为一个消息的结束. 二进制协议,通常是由消息头(Head ...