Hibernate注解
最近正在学习Hibernate通过注解(annotation)来管理映射关系,以前都是通过XML映射文件。下面拿个小例子说一下。
v数据库物理模型:一篇博客随笔可以分到不同的类中,一个类中又可以包含许多不同的博客随笔。就如同博客园的设计。也就是上图中 博客-组 和 博客-消息是多对多的映射。
vHibernate关联映射方式:双向N-N关联, 两端都要使用Set集合属性,两端都增加对集合属性的访问。双向N-N关联没有太多的选择,只能采用连接表来建立两个实体之间的关联关系。
v生成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;vPO(persisent object)类:
PO = POJO(plain ordinary java object) + 注解
vPO : BlogGroup//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; } vPO : BlogMessage
@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; } vHibernate中数据的三种状态
补充一下:Dao层的操作,需要掌握Hibernate中数据的三种状态
1, 临时状态(Transient):用new创建的对象,它没有持久化,没有处于Session中,处于此状态的对象叫临时对象;
2, 持久化状态(Persistent):已经持久化,加入到了Session缓存中。如通过hibernate语句保存的对象。处于此状态的对象叫持久对象;
3, 游离状态(Detached):持久化对象脱离了Session的对象。如Session缓存被清空的对象。
盗图两张
1.对于刚创建的一个对象,如果session中和数据库中都不存在该对象,那么该对象就是瞬时对象(Transient)。
2.瞬时对象调用save方法,或者离线对象调用update方法可以使该对象变成持久化对象,如果对象是持久化对象时,那么对该对象的任何修改,都会在提交事务时才会与之进行比较,如果不同,则发送一条update语句,否则就不会发送语句。
3.离线对象就是,数据库存在该对象,但是该对象又没有被session所托管。
vDAO层:分别测试了不同方式的插入操作, 以及更新和删除。具体看函数的实现。
package com.blog.dao;v罗列所有持久化类的类名:
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 / mapping / /session-factory /hibernate-configuration如果整合了Spring:application.cfg.xml中的配置 bean id="sessionFactory"
!--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学习之Hibernate注解总结 Hibernate学习之Hibernate注解总结http://www.bieryun.com/3269.html 一、类级别的注解 @Entity name:表的名字(可选)一般表名和类名相同 必须指定主键属性@Id @Table name:映射表的名称(可选) catalog:目录(可选)默认为空 schema:模式(可选)默认为空 与@Entity注解配合使用,只能表示在实体类class定义处,表示实体类对应数据库表的信息 @Embeddable 表示一个非Entity类,不是一个实体类,可以嵌入到实体类中作为一个属性存在。
Hibernate主键生成策略及选择 1 .increment:适用于short,int,long作为主键,不是使用数据库自动增长机制 这是hibernate中提供的一种增长机制 在程序运行时,先进行查询:select max(id) from user; ...
相关文章
- Spring整合Hibernate JPA
- servlet的工作原理_hibernate工作原理
- hibernate框架BaseDao详解编程语言
- Hibernate持久化对象的状态详解编程语言
- hibernate validation内置注解及自定义注解详解编程语言
- Hibernate通过SQL查询常量时只返回第一个字符解决方法详解编程语言
- 使用Hibernate 拦截执行sql语句,并输出sql语句,获取sql语句详解编程语言
- hibernate+oracle+主键varchar2类型,增加序列策略注解失败详解编程语言
- Hibernate projectionList方法:创建多个投影列
- Hibernate Query接口 setEntity方法:用于绑定实体类参数
- Hibernate between方法:设置在两者之间的条件
- Hibernate isClosed方法:判断SessionFactory对象是否关闭
- Hibernate hibernate.max_fetch_depth属性:设置抓取深度
- Hibernate hibernate.order_updates属性:为SQL更新排序
- Hibernate show_sql属性:指定是否输出SQL语句
- MyBatis和Hibernate的区别
- hibernate常用方法介绍
- java扩展Hibernate注解支持java8新时间类型