首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 数据库 > SQL Server >

应用 hibernate SQL Query实现动态表

2012-10-06 
使用 hibernate SQL Query实现动态表????privateInteger userId????privateInteger year????privateInte

使用 hibernate SQL Query实现动态表

????privateInteger userId;
????privateInteger year;
????privateInteger month;
????privateInteger day;
????privateInteger point;

那么相应的 ReadInfo.hbm.xml 的片段是

????<classname="ReadInfo" table="tblReadInfo"mutable="false">
????????<composite-id>
????????????<key-propertyname="userId" column="userId" type="integer"/>
????????????<key-propertyname="year" column="year"type="integer"/>
????????????<key-propertyname="month" column="month" type="integer"/>
????????????<key-propertyname="day" column="day"type="integer"/>
????????</composite-id>
????????<propertyname="point" column="point" type="integer"/>
????</class>

上面的xml,注意 2 个细节

1. pojo 所映射的 table tblReadInfo 实际上是不存在的。实际的表是 tblRead200710之类的;

2. mutable 要设置为?false,即是说,关闭 hibernate 对这个 pojo的任何持久化操作,以避免 hibernate 把数据写到 tblReadInfo中(这个表是不存在的嘛)。因此,所有的持久化操作,都是需要自己通过 SQLQuery 来处理。

现在可以看一下 ado 中的操作了,先看一个 select 操作

public ReadInfoselectReadInfo(Integer userId, Integer year,
????????????Integermonth, Integer day) throws HibernateException
????{
????????ReadInforeadInfo = null;

????????Sessionsession = getSession();
????????Transactiontx = session.beginTransaction();

????????try
????????{
????????????Stringsql = "select *from tblRead"
????????????????+Misc.formatMoon(year,month)
????????????????+" where userId=? andday=?";

????????????SQLQueryquery = session.createSQLQuery(sql);
????????????query.addEntity(ReadInfo.class);

????????????query.setLong(0,userId);
????????????query.setInteger(1,day);

????????????readInfo= (ReadInfo) query.uniqueResult();

????????????tx.commit();
????????}
????????catch(HibernateExceptione)
????????{
????????????log.error("catchexception:",e);

????????????if(tx !=null)
????????????{
????????????????tx.rollback();
????????????}

????????????throwe;
????????}
????????returnreadInfo;
????}

上面的代码,关键是以下几点:

1. 通过函数参数的 year, month 来确定要操作的表名,我自己写了一个 Misc.formatMoon(year,month) 来生成 "yyyyMM" 格式的字串;

2. 使用了 SQLQuery ,再通过 query.addEntity(ReadInfo.class); 建立与ReadInfo 的映射关系;

3. query.setXxx() 与 PreparedStatement 的类似,不过索引是从0 开始;

4. 其它的就跟一般的 Query 操作类似的了。

再看一个 insert 操作

????publicvoid insertReadInfo(ReadInfo readInfo) throws HibernateException
????{
????????Sessionsession = getSession();
????????Transactiontx = session.beginTransaction();

????????try
????????{
????????????Stringsql = "insert intotblRead"
????????????????+Misc.formatMoon(readInfo.getYear(),readInfo.getMonth())
????????????????+" (userId, year, month, day, point)values (?, ?, ?, ?, ?)";

????????????SQLQueryquery = session.createSQLQuery(sql);

????????????query.setLong(0,readInfo.getUserId());
????????????query.setInteger(1,readInfo.getYear());
????????????query.setInteger(2,readInfo.getMonth());
????????????query.setInteger(3,readInfo.getDay());
????????????query.setInteger(4,readInfo.getPoint());

????????????query.executeUpdate();

????????????tx.commit();
????????}
????????catch(HibernateExceptione)
????????{
????????????log.error("catchexception:",e);

????????????if(tx !=null)
????????????{
????????????????tx.rollback();
????????????}

????????????throwe;
????????}
????}

同理,update, delete 等操作也是这样实现的。

hmm.. 这种处理方式的麻烦的地方是需要手工写 sql ,因此要尽量写通用的标准sql,不然在数据库兼容方面会有问题。当然,有时是会出现无法兼容的情况,那么可以考虑把 sql写到配置文件中,根据不同的数据库,装载相应的配置文件咯。

热点排行