Hibernate 经验使用总结

此前,本博中,已有几篇文章对Hibernate技术进行了介绍,Hibernate技术知识点总结, Hibernate配置文件hibernate.cfg.xml文件详解, 今天继续从实践中出发,在实践中遇到的问题,记录在此!


(1) 使用Hibernate的一定要引入SLF4J.jar Logger, 来看看它是什么,以及怎么使用,首先看一个异常:

log4j:WARN No appenders could be found for logger (com.car.common.util.PropertiesFile).
log4j:WARN Please initialize the log4j system properly.

SLF4J: slf4j-api 1.6.x (or later) is incompatible with this binding.
SLF4J: Your binding is version 1.5.5 or earlier.
SLF4J: Upgrade your binding to version 1.6.x. or 2.0.x
首先SLF4J:   The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framework at deployment time.  通过名称不难看出,这个SLF4J使用Facade设计模式, SLF4J的使用Mannual ,简单的说来,使用SLF4J是需要将slf4j-api-1.7.5.jar和slf4j-simple-1.7.5.jar导入CLass Path即可,但是它有一个功能binding, 来支持其他的log Jar,比如log4j, 根据log4j的版本,选择对应的binding包,slf4j-log4j12-1.7.5.jar 和log4j.jar放入class Path.

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

但是:

SLF4J is only a facade, meaning that it does not provide a complete logging solution. Operations such as configuring appenders or setting logging levels cannot be performed with SLF4J. Thus, at some point in time, any non-trivial application will need to directly invoke the underlying logging system. In other words, complete independence from the API underlying logging system is not possible for a stand-alone application. Nevertheless, SLF4J reduces the impact of this dependence to near-painless levels.

所以SLF4J是用于Logger迁移用的,而不是真正的logger。真正的logger有log4j, 所以要使用logger必须使用一个真正的logger,本项目使用log4j.jar. 

SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/D:/MyProject/CarMgt/lib/slf4j-log4j12.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/D:/MyProject/CarMgt/lib/slf4j-simple-1.7.5.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation.
SLF4J: slf4j-api 1.6.x (or later) is incompatible with this binding.
SLF4J: Your binding is version 1.5.5 or earlier.
SLF4J: Upgrade your binding to version 1.6.x.
上面遇到的ERROR是Multiple Bindings,有log4j和simple的绑定,去掉simple的即可。另外关于incompatible bindings的异常,是因为本项目中使用的slf4j-api 1.6.x,而用的Hibernate版本与slf4j不符合: Hibernate3.3.2版本应该与slf4j-1.5.8版本搭配使用。

最后关于引入Hibernate后,如何快速使用Logger的步骤:

  • 根据HIbernate的版本,使用相应的SLF4J,如 slf4j-api-1.5.8, 并将添加到Build Path
  • 在所有代码中使用Logger的地方,都使用SLF4J的接口,如final Logger logger = LoggerFactory.getLogger(className.class); 并import org.slf4j.Logger 和 org.slf4j.LoggerFactory,即可,不要在使用log4j的接口
  • 将具体的logger和相应的slf4j-longger也添加到Build Path,如log4j-1.2.15 和 slf4j-log4j12-1.5.8, SLF4J就会自动绑定这个真正的Logger了
  • 使用Logger的配置文件,即可进行对Logger行为的配置,如Logger的Level,是否使用File还是console输出log.

(2)使用 hibernate tools 进行建立表结构 hbm文件与 类之间的映射关系 , 百科上的:Hibernate Tools 英文版Mannual,和 Hibernate tools 入门教程

    添加Eclipse Hibernate tools插件 ,   http://download.jboss.org/jbosstools/updates/   和 http://download.jboss.org/jbosstools/updates/development

  如何改变默认Hibernate Tools自动生成的代码:

  •  有时候数据库的表名会有特定的标识作为开头,比如tbl_xxxx,当我们生成实例的时候,希望可以去掉tbl_。这时我们需要重写hibernate-tool.jar包中的DefaultReverseEngineeringStrategy方法:

 

package hibernatetools;

import org.hibernate.cfg.reveng.DefaultReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.ReverseEngineeringSettings;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.TableIdentifier;
import org.hibernate.util.StringHelper;

public class CustomReverseEngineeringStrategy extends
        DefaultReverseEngineeringStrategy {

    public CustomReverseEngineeringStrategy(ReverseEngineeringStrategy delegate) {
        super();
    }
    public CustomReverseEngineeringStrategy(){
    }
    private ReverseEngineeringSettings settings;
    @Override
    public String tableToClassName(TableIdentifier table) {
        String tableName = table.getName();
        if (tableName != null && tableName.toUpperCase().startsWith("TBL_")) {
            String pkgName = settings.getDefaultPackageName();
            int lastIndex = tableName.indexOf("_");
            tableName = tableName.substring(lastIndex + 1);
            String className = toUpperCamelCase(tableName);
            if (pkgName.length() > 0)
                return StringHelper.qualify(pkgName, className);
            return className;
        } else {
            return super.tableToClassName(table);
        }
    };
    public void setSettings(ReverseEngineeringSettings settings) {
        super.setSettings(settings);
        this.settings = settings;
    }
}
  在输出设置中,reveng strategy这一项选择这个子类。
 
  •   在生成出来的代码中,我们也许需要自定义一些内容。这时我们需要修改hibernate-tools的输出模版,解压hibernate-tools.jar文件,找到daoTemplate这个中文件,里面的包含了所有的模版文件,可按照需求进行修改,修改完成后,在输入设置中,勾选user custom templates,在下面的Template directory中选择修改后的daoTemplate这个文件夹。
  •   自动生成的dao只是实现类,没有接口,且文件结尾为Home并非我们需要的DaoImpl。这种情况下我们提供两种思路: (1)修改hibernate-tools源码,修改完成后打成jar包,覆盖hibernate-tools插件所在文件目录下的文件。(2)使用自定义模版,做两套dao的模版,一个是接口,一个是实现类,互相替换,生成两次dao;命名方面可写一个简单的java程序批量修改文件名。
  •   生成出来的实例在一对多的情况下,属性没有泛型。这是因为我们在输出设置中没有勾选User Java 5 syntax。



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

 <id name="id" type="string" unsaved-value="null">
         <column name="cid" sql-type="char(32)" not-null="true" />
         <generator class="uuid.hex" />
 </id>

下面的query的关于时间方面如果使用q.setDate,则插入到数据库中后就丧失了时分秒,使用q.setTimesstamp则保留,注意!

public boolean GeneralTaskRemindUpd(int generalTaskId, int rmdStatusId,
			Date expectRemindDate) throws RemoteException {
		boolean flag = false;
		try {

			Date UpdateTs = DateUtils.GetcurrentTimestamp();
			String hql = "update GeneralTask set recFlag=:recFlag ,updateTs=:UpdateTs ,expectRemindDate =:expectRemindDate ,rmdStatusId =:rmdStatusId where generalTaskId=:generalTaskId";
			Query q = getSession().createQuery(hql);
			q.setInteger("recFlag", UPD);
			q.setTimestamp("UpdateTs", UpdateTs);
			q.setTimestamp("expectRemindDate", expectRemindDate);
			q.setParameter("rmdStatusId", rmdStatusId);
			q.setInteger("generalTaskId", generalTaskId);

			log.debug("GeneralTask UpdateDate:" + UpdateTs + ", RemindDate:"
					+ expectRemindDate);

			ServerSerivces.updateDate(RmiUtil.GeneralTaskDao, UpdateTs);
			Transaction trans = getSession().beginTransaction();
			q.executeUpdate();
			trans.commit();
			flag = true;
		} catch (HibernateException e) {
			log.error("", e);
		} finally {

		}
		return flag;

	}








  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Hibernate使用技巧汇总<br><br>1.两种配置文件: <br> A.hibernate.cfg.xml 和 B.hibernate.properties <br> A中可含映射文件的配置,而B中hard codes加映射文件。 <br> A。Configuration config=new Configuration().config(); <br> B. Configuration config=new Configuration(); <br> config.addClass(TUser.class); <br><br>2.你不必一定用hibernate.cfg.xml或hibernate.properties这两文件名, <br> 你也不一定非得把配置文件放在Classes下, <br> File file=new File("c:\\sample\\myhibernate.xml"); <br> Configuration config=new Configuration().config(file); <br>3. session.Flush() <br> 强制数据库立即同步,当用事务时,不必用flush,事务提交自动调用flush <br> 在session关闭时也会调用flush <br><br>4. Hibernate总是使用对象类型作为字段类型 <br>5. XDoclet专门建立了hibernate doclet,就是在java代码上加上一些 <br> java docTag,后来再让XDoclet分析该java代码,生成映射文件; <br>6.HQL子句本身大小写无关,但是其中出现的类名和属性名必须注意大小写区分。 <br>7.关系: <br> Constrained : 约束,表明主控表的主键上是否存在一个外键(foreigh key) <br> 对其进行约束。 <br> property-ref:关联类中用于与主控类相关联的属性名,默认为关联类的主键属性名 <br> 单向一对多需在一方配置,双向一对多需在双方进行配置 <br>8.lazy=false:被动方的记录由hibernate负责记取,之后存放在主控方指定的 <br> Collection类型属性中 <br><br>...............<br><br><br>...............<br><br><br>27.Spring的参数化事务管理功能相当强大,笔者建议在基于Spring Framework的应用 <br>开发中,尽量使用容器管理事务,以获得数据逻辑代码的最佳可读性。 <br> <br>public class UserDAO extends HibernateDaoSupport implements IUserDAO <br>{ <br>public void insertUser(User user) { <br>getHibernateTemplate().saveOrUpdate(user); <br>} <br>} <br><br> 上面的UserDAO实现了自定义的IUserDAO接口,并扩展了抽象类: <br>HibernateDaoSupport <br>HibernateSupport实现了HibernateTemplate和SessionFactory实例的关联。 <br>HibernateTemplate对Hibernate Session操作进行了封装,而 <br>HibernateTemplate.execute方法则是一封装机制的核心 <br> *在spring的配置文件里,移植了整个hibernate.cfg.xml的内容。<br>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值