为什么hibernate会插入两条相同的记录(偶尔) 如何将Hibernate生成的SQL语句打印到日志文件
为什么hibernate会插入两条相同的记录(偶尔)
flysnowxf 写道除了写数据库,定时任务在其他业务上也容易出现这种重复执行的问题。 我之前有个项目是发短信的,定时任务的配置在core包中。原先只有一个web1工程,它依赖于core,定时任务没问题。后来新加了一个web2工程,它也依赖于core。这样就会同时跑2个相同的任务了。 后来解决的方法是:对任务启动加入一个开关。web1开启,web2关闭。并且保证,web1不会出现集群。A表中加入一个IP字段,集群中各定时任务只执行包含自己IP的记录 这样都互不干扰,很好的运用集群环境.
如何将Hibernate生成的SQL语句打印到日志文件
如何将Hibernate生成的SQL语句打印到日志文件
只要加上下面这个语句就可以了
Log4j.propreties代码
#输出sql语句到日志
log4j.logger.org.hibernate.SQL=debug
#将对应的参数占位符?换成传入的参数
log4j.logger.org.hibernate.type=trace
如何处理hibernate打印一些无关的日志信息
步骤
1. 在项目中创建4个包,分别是 log4.debug/error/info/warning
2. 在每个包下创建输出日志的测试代码:
Java代码
log.debug("Debug in Debug Level")
log.info("Info in Debug Level")
log.warn("Warn in Debug Level")
log.error("Error in Debug Level")
3. 在MainClass中调用日志输出:
Java代码
package lv.showcase.log4j
import lombok.extern.log4j.Log4j
import lv.showcase.log4j.debug.DebugLog
import lv.showcase.log4j.error.ErrorLog
import lv.showcase.log4j.info.InfoLog
import lv.showcase.log4j.warning.WarnLog
@Log4j
public class Main {
public static void main(String[] args) {
log.info("========== Log4j Showcase :")
log.debug("You can not see this message in info level.")
DebugLog.log()
InfoLog.log()
WarnLog.log()
ErrorLog.log()
}
}
4. 采用如下log4j配置来控制日志输出:
Java代码
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
log4j.appender.file=org.apache.log4j.FileAppender
log4j.appender.file.File=log4j_showcase.log
log4j.appender.file.layout=org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
log4j.appender.R1=org.apache.log4j.FileAppender
log4j.appender.R1.File=main.log
log4j.appender.R1.layout=org.apache.log4j.PatternLayout
log4j.appender.R1.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss,SSS} %5p %c{1}:%L - %m%n
log4j.logger.lv.showcase.log4j.debug=debug, stdout, file
log4j.logger.lv.showcase.log4j.error=error, stdout, file
log4j.logger.lv.showcase.log4j.info=info, stdout, file
log4j.logger.lv.showcase.log4j.warning=warn, stdout, file
#Main函数的日志会输出到main.log文件中
log4j.logger.lv.showcase.log4j.Main=info, stdout, R1
上述log4j配置做了这几个事情
定义3中输出方式: stdout(标准输出), file(输出到log4_showcase.log), R1(输出到main.log)
使用log4j.logger.{package}=? 方式控制每个包的输出等级, 输出方式采用stdout, file这两种输出方式
使用log4j.logger.{package}.{className}=? 方式控制单个类的输出等级,输出方式采用stdout, main
输出结果
控制台:
Java代码
[java] 2013-08-06 10:22:01,684 INFO Main:? - ========== Log4j Showcase :
[java] 2013-08-06 10:22:01,688 DEBUG DebugLog:? - Debug in Debug Level
[java] 2013-08-06 10:22:01,689 INFO DebugLog:? - Info in Debug Level
[java] 2013-08-06 10:22:01,689 WARN DebugLog:? - Warn in Debug Level
[java] 2013-08-06 10:22:01,690 ERROR DebugLog:? - Error in Debug Level
[java] 2013-08-06 10:22:01,691 INFO InfoLog:? - Info in Info Level
[java] 2013-08-06 10:22:01,691 WARN InfoLog:? - Warn in Info Level
[java] 2013-08-06 10:22:01,692 ERROR InfoLog:? - Error in Info Level
[java] 2013-08-06 10:22:01,693 WARN WarnLog:? - Warn in Warning Level
[java] 2013-08-06 10:22:01,693 ERROR WarnLog:? - Error in Warning Level
[java] 2013-08-06 10:22:01,694 ERROR ErrorLog:? - Error in Error Level
Main.log 输出:
Java代码
2013-08-06 10:22:01,688 DEBUG DebugLog:? - Debug in Debug Level
2013-08-06 10:22:01,689 INFO DebugLog:? - Info in Debug Level
2013-08-06 10:22:01,689 WARN DebugLog:? - Warn in Debug Level
2013-08-06 10:22:01,690 ERROR DebugLog:? - Error in Debug Level
2013-08-06 10:22:01,691 INFO InfoLog:? - Info in Info Level
2013-08-06 10:22:01,691 WARN InfoLog:? - Warn in Info Level
2013-08-06 10:22:01,692 ERROR InfoLog:? - Error in Info Level
2013-08-06 10:22:01,693 WARN WarnLog:? - Warn in Warning Level
2013-08-06 10:22:01,693 ERROR WarnLog:? - Error in Warning Level
总结
实际应用中可以配置多个appender,按照模块将日志分成不同文件
Log4j的日志输出支持按包/类制定级别, 配置方式(log4j.logger.{package}.{className} )
随着项目的演进需要对日志文件进行划分,否则这样生成的日志会让后期日志分析工作变成噩梦
怎么让Hibernate不打印日志
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean"> org.hibernate.dialect.OracleDialect true--- 这里改成false
如何关闭hibernate产生的大量日志
要关闭hibernate的日志,首先要把hibernate.show_sql设置为false然后设置log4j.properties。
# Control logging for other open source packages
log4j.logger.com.opensymphony.oscache=ERROR
log4j.logger.net.sf.navigator=ERROR
log4j.logger.net.sf.acegisecurity=WARN
log4j.logger.net.sf.acegisecurity.intercept.event.LoggerListener=WARN
log4j.logger.org.apache.commons=ERROR
log4j.logger.org.apache.struts=WARN
log4j.logger.org.displaytag=ERROR
log4j.logger.org.springframework=WARN
log4j.logger.com.ibatis.db=WARN
log4j.logger.org.apache.velocity=WARN
# Dont show debug logs for WebTest
log4j.logger.com.canoo.webtest=WARN
# All hibernate log output of "info" level or higher goes to stdout.
# For more verbose logging, change the "info" to "debug" on the last line.
log4j.logger.org.hibernate.ps.PreparedStatementCache=WARN
log4j.logger.org.hibernate=WARN
# Changing the log level to DEBUG will result in Hibernate generated
# SQL to be logged.
log4j.logger.org.hibernate.SQL=ERROR
# Changing the log level to DEBUG will result in the PreparedStatement
# bound variable values to be logged.
log4j.logger.org.hibernate.type=ERROR
hibernate防止重复插入数据
有一个方法可以提供
在建一个字段叫hashcode int类型
在插入数据时,把每一列数据的hashcode值通过hashCode()方法取得,并且相加,得到的结果写入数据库的hashcode字段
插入数据时,取得所有字段hashcode值然后查询该值是否在数据库存在,不存在就插入
但是这样做也有小概率事件发生,也就是2个实际不重复的数据其hashcode的值是相同的,不过这概率应该很小
你可以试试
参考如下:
class Person {
String name
int age
public int hashCode() {
final int prime = 31
int result = 1
result = prime * result age
result = prime * result ((name == null) ? 0 : name.hashCode())
return result
}
}
补充一点,你甚至可以让hashcode字段成为主键