zoukankan      html  css  js  c++  java
  • Hibernate 的saveOrUpdate方法(转)

    hibernate提供了saveOrUpdate的方法来进行数据库的操作。hibernate会根据对象的状态决定是insert还是update,
    其根本是通过xml文件中unsaved-value来确定的。如果设置null,系统会根据传入的对象的id的值判断,如果是null,
    则表示对象不存在,那么insert;如果不是Null,则表示已经存在,那么update.如果设置为none,那么表示对象不存在,
    会始终调用insert;如果设置为any,那么表示对象始终存在,会始终调用update


        数据库表主键的知识点:
        Generator 为每个 POJO 的实例提供唯一标识。一般情况,我们使用“native”。
    class 表示采用由生成器接口net.sf.hibernate.id.IdentifierGenerator 实现的某个实例,其中包括:

       “assigned” 主键由外部程序负责生成,在 save() 之前指定一个。

       “hilo” 通过hi/lo 算法实现的主键生成机制,需要额外的数据库表或字段提供高位值来源。

       “seqhilo”与hilo 类似,通过hi/lo 算法实现的主键生成机制,需要数据库中的 Sequence,
                适用于支持 Sequence 的数据库,如Oracle。

       “increment”主键按数值顺序递增。此方式的实现机制为在当前应用实例中维持一个变量,以保存着当前的最大值,
                之后每次需要生成主键的时候将此值加1作为主键。这种方式可能产生的问题是:不能在集群下使用。

       “identity”采用数据库提供的主键生成机制。如DB2、SQL Server、MySQL 中的主键生成机制。

       “sequence”采用数据库提供的 sequence 机制生成主键。如 Oralce 中的Sequence。

       “native”由 Hibernate 根据使用的数据库自行判断采用 identity、hilo、sequence 其中一种作为主键生成方式。

       “uuid.hex”由 Hibernate 基于128 位 UUID 算法 生成16 进制数值(编码后以长度32 的字符串表示)作为主键。

       “uuid.string”与uuid.hex 类似,只是生成的主键未进行编码(长度16),不能应用在 PostgreSQL 数据库中。

       “foreign”使用另外一个相关联的对象的标识符作为主键。

       以下举例:
       1、指定参数的情况:
          <id name="id" unsaved-value="0"> 
            <generator class="sequence">
              <param name="sequence">SEQ_CHILD</param>
            </generator>
          </id>
         使用的是sequence,适合oracle数据库;

       2、对于sql server2000中的数据库子增字段,在配置文件使用下列方法实现:
          <id name="id" type="long" unsaved-value="0">
            <column name="id" sql-type="numeric" not-null="true" />
            <generator class="identity" /> 
          </id>
        这里主要是:identity:代表由sql server2000数据库自己提供子增字段.如果要hibernate自己提供,则用increment关键字来实现

       3、如果表中的主键用字符串类型:可以用hibernate自己提供的方法实现主键唯一:
         <id name="id" type="string" unsaved-value="null">
             <column name="cid" sql-type="char(32)" not-null="true" />
             <generator class="uuid.hex" />
         </id>
         使用的是uuid.hex: 采用128位的算法来生成一个32位字符串。最通用的一种方式。适用于所有数据库。

       重要的知识点:
       1. 如果有部门表,有员工表,员工表中有dep_id,则表部门类和员工类是one-to-many的关系:
          可以使用: ( 在部门类department中使用下列)
          Department类: 
            /** 部门的所有员工   */
           private Set staffs = new TreeSet();
         
           xml的文件:
             <set name="staffs" >
                 <key column="dep_id"/>
                 <one-to-many class="hbp.sys.data.Staff"/>
             </set>
             如果是list,需要用索引<index> </index>,具体其中的含义,不是很明白.待以后研究
          
        2. 如果部门要有一个负责人,即部门表(tb_department)中有一个字段:staff_id.
            那么表示部门和负责人之间的关系是many-to-one的关系
            Department类: 
             /** 部门负责人id */
           private Staff staff;
        
           xml 文件
            <many-to-one name="staff" class="hbp.sys.data.Staff" column="staff_id"/> 

        3. 多对多关系,一般我们是做一个中间关联表.我用角色和权限做了个例子,
             Right(id,name)     Role(id,name)   中间表:tb_role_right(role_id,right_id)
             Right类中有一个Role的集合:private Set roles=new TreeSet();
             Role类中也有一个Right的集合:private Set rights=new TreeSet();
             则两者是明显的多对多关系.使用many-to-many来实现;
             xml文件中
             right.hbm.xml:如下:
               <set name="roles" table="tb_role_right" cascade="all">
                  <key column="right_id"/>
                  <many-to-many column="role_id" class="hbp.sys.data.Role"/>
               </set> 
             role.hbm.xml文件中类似:
               <set name="rights" table="tb_role_right" cascade="all">
                 <key column="role_id"/>
                 <many-to-many column="right_id" class="hbp.sys.data.Right"/>
               </set>

       4. 几个值得注意的问题:
               a)在xml?映射文件中,写类的名字时一定用类的全名:即:包+类名如:(hbp.sys.data.Staff),这个错误使我费了半天劲.:(
               b)我在写实现基本DAO操作时,写了
                    session.delete("from Right as right where right.id="+id); 
                    程序死活报错,我折腾了半天,跟踪到底,才恍然大悟,hibernate在解析sql语句的时候把
                    其中的right,当成了数据库中的右连接("保留字"),唉,这种关键字,不能随便用啊,:)

       5. hibernate中HQL语言的查询根据你的sql的不同而返回不同的对象类型.
                如果你使用session.find(String hql)
                一般会返回一个List,如:from Staff staff;返回的是包含所有的员工对象的集合
                如你的hql为:select count(*) from Staff staff;则返回的是一个Integer对象
                如果你使用的hql为:select count(distinct staff.name),count(*) from Staff staff;则返回的是一个Object
                即Object[],需要先把他转换成Object[],然后在取[0],[1].
                这种设计我不知道hibernate是如何处理的,感觉既好也不好.好的是可以使用一个find获得任意查询
                不好在于根据hql来处理返回结果,容易出错.

  • 相关阅读:
    archlinux .bash_history
    Ubuntu环境下挂载新硬盘
    软碟通 UltraISO U启替代品 Win32DiskImager 无设备 无盘符 无u盘 无优盘 解决方案 之diskpart
    delphi Integer overflow
    MSBuild Tools offline
    delphi synedit免费的拼写检查器dll
    git 自定义命令行
    lua编译
    gcc ar
    Windows Subsystem for Linux (WSL)挂载移动硬盘U盘 卸载 c d 盘
  • 原文地址:https://www.cnblogs.com/rixiang/p/5203422.html
Copyright © 2011-2022 走看看