Hibernate操作MySQL视图

来源:互联网 发布:淘宝手机端无缝拼接 编辑:程序博客网 时间:2024/05/16 13:02

Hibernate以对象的方式操作数据库,符合OOP的编程模式。这种操作方式大大的简化了程序员与数据库交互的流程,减少了大量操作数据库的代码(不用自己拼写sql语句),通过实体与数据库之间的映射,程序员只需像操作对象及其属性一项操作一个实体就可以完成对数据的增删改查操作,十分方便。

通过Hibernate操作数据库虽然简便高效,但是在某些特殊需求面前,这种方式有显得不是那么灵活,例如从多个表中查询需要的信息。如果利用hibernate从多个表格中查询,结果及为多个表格的笛卡尔积,例如从表A(5个字段)和表B(3个字段)中查询,结果是包含表A和表B的所有字段(8个字段)的多条记录,也就是说相当于生成了一个新的实体,这样就需要一个新的实体与之相对应才能操作查询结果。当然,我们可以在hql中通过new一个实体的方式来取得查询结果,但是如果查询结果记录中海包括其他实体(也就是结果记录与其他表有外键关系),那将会更复杂。

为了解决以上问题,本人采用了hibernate操作视图的方式。

视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含一系列带有名称的列和行数据。但是,视图并不在数据库中以存储的数据值集形式存在。行和列数据来自由定义视图的查询所引用的表,并且在引用视图时动态生成。

对其中所引用的基础表来说,视图的作用类似于筛选。定义视图的筛选可以来自当前或其它数据库的一个或多个表,或者其它视图。通过视图进行查询没有任何限制,通过它们进行数据修改时的限制也很少。

视图是存储在数据库中的查询的SQL 语句,它主要出于两种原因:安全原因, 视图可以隐藏一些数据,如:社会保险基金表,可以用视图只显示姓名,地址,而不显示社会保险号和工资数等,另一原因是可使复杂的查询易于理解和使用。

视图:查看图形或文档的方式。

视图是从一个或多个表或视图中导出的表,其结构和数据是建立在对表的查询基础上的。和表一样,视图也是包括几个被定义的数据列和多个数据行,但就本质而言这些数据列和数据行来源于其所引用的表。

所以视图不是真实存在的基础表而是一张虚表,视图所对应的数据并不实际地以视图结构存储在数据库中,而是存储在视图所引用的表中。

视图一经定义便存储在数据库中,与其相对应的数据并没有像表那样又在数据库中再存储一份,通过视图看到的数据只是存放在基本表中的数据。对视图的操作与对表的操作一样,可以对其进行查询、修改(有一定的限制)、删除。

当对通过视图看到的数据进行修改时,相应的基本表的数据也要发生变化,同时,若基本表的数据发生变化,则这种变化也可以自动地反映到视图中。

视图有很多优点,主要表现在:
  •视点集中
  •简化操作
  •定制数据
  •合并分割数据
  •安全性
当然视图也存在一些缺点,最大的缺点就是视图带来的更新负担,比如源数据改了,那么视图中要做相应更新,视图中数据改了源数据也要做同步,这和MySQL的Cache差不多。

操作视图与操作实际存在的表基本相同,但是视图映射产生的实体文件会把视图中所有字段当做视图的id,也就是会生成一个符合主键,这样就会产生一个新问题,如果查询结果中有一个字段为null,则整条记录就为null,这就是为什么很多情况下查询出来结果对象全都是null。

我们可以通过修改配置文件,以一个唯一的标志作为视图的主键来解决此问题,代码如下所示。

我的roleInfo表没有主键,hibernate生成如下映射: 
<hibernate-mapping> 
    <class name="model.Roleinfo"table="ROLEINFO" schema="`FILE`"> 
        <composite-id name="id"class="model.RoleinfoId"> 
            <key-property name="id"type="java.lang.String"> 
                <columnname="ID" length="32" /> 
            </key-property> 
            <key-propertyname="purview" type="java.lang.String"> 
                <columnname="PURVIEW" length="10" /> 
            </key-property> 
            <key-propertyname="role" type="java.lang.String"> 
                <columnname="ROLE" length="10" /> 
            </key-property> 
            <key-propertyname="remark" type="java.lang.String"> 
                <columnname="REMARK" /> 
            </key-property> 
            <key-propertyname="fileid" type="java.lang.String"> 
                <columnname="FILEID" length="20" /> 
            </key-property> 
            <key-propertyname="islock" type="java.lang.String"> 
                <columnname="ISLOCK" length="10" /> 
            </key-property> 
        </composite-id> 
    </class> 
</hibernate-mapping> 

修改以上映射文件中的复合主键为唯一主键:

<hibernate-mapping> 
    <class name="model.Roleinfo"table="ROLEINFO" schema="`FILE`">    
        <composite-id name="id"class="model.RoleinfoId"> 
            <key-property name="id"type="java.lang.String"> 
                <columnname="ID" length="32" /> 
            </key-property>           
        </composite-id> 
        <property name="purview"type="java.lang.String"> 
            <column name="PURVIEW"length="10" /> 
        </property> 
        <property name="role" type="java.lang.String"> 
            <column name="ROLE"length="10" /> 
        </property> 
        <property name="remark"type="java.lang.String"> 
            <column name="REMARK"/> 
        </property> 
        <property name="fileid"type="java.lang.String"> 
            <column name="FILEID"length="20" /> 
        </property> 
        <property name="islock"type="java.lang.String"> 
            <column name="ISLOCK"length="10" /> 
        </property> 
    </class> 
</hibernate-mapping> 
同时在Roleinfo实体类(Roleinfo.java)中加上了相应的get、set方法。

这样就可以通过视图来找到想要的结果
原创粉丝点击