使用HIBERNATE调用自定义函数

    最近的项目打算用SPRINGMVC+HIBERNATE来实现,因为我们打算把这个项目做成一个产品,所以使用HIBERNATE希望

可以部署在不同的数据库服务器上。

    但是使用HQL调用自定义函数的时候却出现了问题。比如 select user.id, my_function(user.id) from USER u,执行这个HQL

会报如下的错误:

java.lang.IllegalStateException: No data type for node: org.hibernate.hql.ast.tree.MethodNode
 \-[METHOD_CALL] MethodNode: '('
    +-[METHOD_NAME] IdentNode: 'my_function' {originalText=my_function}

    在网上找了下,解决方法是重写对应的数据库方言,然后配置到hibernate.dialect上,但是考虑到以后切换到不同的数据库,

需要重写对应的方言,反而影响程序的跨平台性。因为如果我的函数采用标准SQL,HIERNATE调用本地SQL的时候并不影响跨平台

性(我想的没问题吧?)。

    所以我打算直接用HIBERNATE调用本地SQL,这个方法有很多,我用的是采用NAMED-SQL方式,把SQL写在配置文件里,

这样也方便维护。

<bean id="sessionFactoryCzyw" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
        <property name="dataSource" ref="dataSourceCzyw" />
        <property name="mappingLocations">
            <list>
                <value>classpath:com/wei/liu/springmvc/czyw/**/*.hbm.xml</value><!-- 加载hibernate的映射文件*.hbm.xml -->
            </list>
        </property>
        <property name="hibernateProperties">
            <props>
                <prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
                <prop key="hibernate.dialect">${hibernate.dialect}</prop>
                <prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
                <prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
            </props>
        </property>
        <property name="packagesToScan">
            <value>com.xxx.xxx..</value>
        </property>
    </bean>

    因为我采用的是注解的方式映射的实体类,所以XXX.hbm.xml只有SQL语句,如下:

<!DOCTYPE hibernate-mapping PUBLIC  
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">  
 
<hibernate-mapping package="com.xxx.xxx.xxx.xxx">  
    <sql-query name="selectXXX">   
        <return alias="t" class="xxx.xxx.xxx.xxx.User"></return>  
        <![CDATA[   
                 SELECT id,my_function(id) from user
        ]]>  
  </sql-query>  
</hibernate-mapping>

    这样在java中就可以直接通过session来调用这条语句了 

session.getNamedQuery("selectXXX").setFirstResult(begin).setMaxResults(pageSize).list();

    这里要注意的是,select后面要把所有的字段都写出来,不然的话会报如下的错误:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not execute query; nested exception is org.hibernate.exception.SQLGrammarException: could not execute query
Caused by: org.hibernate.exception.SQLGrammarException: could not execute query
Caused by: java.sql.SQLException: Invalid column name XXXX(少的那个列名).

    如果不想写映射文件,也可以把SQL写在对应的实体类中,如下:

@Entity
@Table(name = "XXX", schema = "XXX", catalog = "XXX")
@NamedNativeQuery(name = "XXX", query = "XXX")
public class XXXimplements java.io.Serializable {

    把对应的XXX替换掉即可。


   


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值