Hibernate 经验使用总结
2013-11-22 11:06
253 查看
此前,本博中,已有几篇文章对Hibernate技术进行了介绍,Hibernate技术知识点总结, Hibernate配置文件hibernate.cfg.xml文件详解,
今天继续从实践中出发,在实践中遇到的问题,记录在此!
(1) 使用Hibernate的一定要引入SLF4J.jar Logger, 来看看它是什么,以及怎么使用,首先看一个异常:
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.
但是:
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.
最后关于引入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方法:
在输出设置中,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。
下面的query的关于时间方面如果使用q.setDate,则插入到数据库中后就丧失了时分秒,使用q.setTimesstamp则保留,注意!
今天继续从实践中出发,在实践中遇到的问题,记录在此!
(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; }
相关文章推荐
- generator中使用increment经验总结(hibernate)
- hibernate的二级缓存项目使用经验总结
- Struts2 + Spring 3 + Hibernate 4 + Java 使用经验总结
- 基于Metronic的Bootstrap开发框架经验总结(3)--下拉列表Select2插件的使用
- 基于Metronic的Bootstrap开发框架经验总结(2)--列表分页处理和插件JSTree的使用
- VC中使用ListCtrl经验总结(1)
- VC/MFC之ListCtrl控件使用经验总结
- 总结使用Unity 3D优化游戏运行性能的经验
- Eclipse 使用经验总结
- JTree用法及JTree使用经验总结<转>
- VC/MFC之ListCtrl控件使用经验总结(一)
- JTree用法及JTree使用经验总结
- Flask-admin使用经验技巧总结
- VC中使用ListCtrl经验总结
- 功能强大的打包工具 NSIS,全部用脚本搞定 使用经验总结帖(持续更新中。。。)
- 基于MVC4+EasyUI的Web开发框架经验总结(4)--使用图表控件Highcharts
- dll使用经验总结
- VISTA 使用经验总结
- [转]总结使用Unity 3D优化游戏运行性能的经验
- 基于MVC4+EasyUI的Web开发框架经验总结(3)- 使用Json实体类构建菜单数据