Hibernate注解

简介:

v前言:

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

v数据库物理模型:

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 


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;
    }
}

vPO : 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;
    }
}

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;


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();
        }
    }
}

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

  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>

目录
相关文章
|
存储 安全 开发工具
oss加密存储
阿里云OSS为数据安全提供多种加密机制,包括服务器端的SSE-S3(AES-256透明加密)、SSE-C(用户管理密钥)和CSE-KMS(结合KMS进行密钥管理)。此外,OSS支持客户端加密SDK和HTTPS传输加密,确保数据在传输和存储时的安全。通过ACL、Bucket策略和访问密钥身份验证,实现权限控制与身份验证,全方位保障用户数据的安全性和隐私。用户可按需选择适合的加密方式。
1273 2
|
7月前
|
存储 弹性计算 人工智能
2026年阿里云服务器新手指南:配置选购、费用价格及使用全流程(图文教程)
2026年阿里云服务器新手指南:详解三大产品线、最新价格及选型攻略。轻量服务器低至38元/年,ECS经济型99元起,GPU服务器满足AI高性能需求。教你按身份、业务、带宽、存储四维度精准选配,避开隐形成本,三步完成购买,花小钱用好云服务。
|
10月前
|
JSON API 数据安全/隐私保护
Python采集淘宝拍立淘按图搜索API接口及JSON数据返回全流程指南
通过以上流程,可实现淘宝拍立淘按图搜索的完整调用链路,并获取结构化的JSON商品数据,支撑电商比价、智能推荐等业务场景。
|
存储 Java 文件存储
微服务——SpringBoot使用归纳——Spring Boot使用slf4j进行日志记录—— logback.xml 配置文件解析
本文解析了 `logback.xml` 配置文件的详细内容,包括日志输出格式、存储路径、控制台输出及日志级别等关键配置。通过定义 `LOG_PATTERN` 和 `FILE_PATH`,设置日志格式与存储路径;利用 `&lt;appender&gt;` 节点配置控制台和文件输出,支持日志滚动策略(如文件大小限制和保存时长);最后通过 `&lt;logger&gt;` 和 `&lt;root&gt;` 定义日志级别与输出方式。此配置适用于精细化管理日志输出,满足不同场景需求。
3324 1
|
11月前
|
人工智能 监控
被遗忘的 OODA 循环:这是一个令人惊叹的军事决策框架和给企业的绝佳礼物
OODA循环(观察、定位、决策、行动)源自空战策略,现成企业应对快速变化环境的关键框架。通过实时数据驱动与迭代反馈,提升决策敏捷性,打破对手节奏,实现持续竞争优势。
|
Unix Linux iOS开发
【换行符】Windows、Unix、Mac不同操作系统的回车符\r和换行符\n
【换行符】Windows、Unix、Mac不同操作系统的回车符\r和换行符\n
|
人工智能 运维 云计算
专家对谈|AI推动文化传媒行业向“新”发展
随着“人工智能+”行动的深入推进,文化传媒行业正经历深刻变革。云计算与AI深度融合,重构内容生产、分发全流程,为行业注入新动能。预计到2025年,我国AI核心产业规模将破万亿,文化传媒作为技术应用先锋,以两位数增速迈向智能化。在CCBN活动现场,中央广播电视总台与阿里云探讨了大模型如何驱动行业升级,展望未来新图景。汪莹指出,大模型将重构文化消费形态,助力生产力与传播力倍增,推动中国文化走向世界。同时,解决AI应用“最后一公里”问题需产业链各方协同发力,基于现有大模型能力进行二次开发是切实可行路径。
859 4
|
监控 网络安全 网络虚拟化
在 Cisco 设备上配置 GRE 隧道
【8月更文挑战第31天】
1435 1
在 Cisco 设备上配置 GRE 隧道
|
API 数据库 网络架构
深入浅出:使用Python Flask实现RESTful API
【10月更文挑战第7天】在数字化时代,掌握如何高效构建和部署RESTful API是后端开发者的必备技能。本文将引导你了解如何使用Python Flask框架快速打造一个简单而强大的RESTful服务。从基础环境搭建到API设计原则,再到实际代码示例,我们将一步步揭开Flask框架的神秘面纱,让你轻松上手,并能够自信地处理更复杂的项目。

热门文章

最新文章