欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

log4j

程序员文章站 2022-05-23 23:22:14
...

  概述     

         Log4j是Apache的一个开源项目,通过使用Log4j,我们可以控制日志信息输送的目的地是控制台、文件、GUI组件,甚至是套接口服务器、NT的事件记录器、UNIX Syslog守护进程等;我们也可以控制每一条日志的输出格式;通过定义每一条日志信息的级别,我们能够更加细致地控制日志的生成过程(百度百科-log4j).

         Log4j现已更新至2.8.2(也就是Log4j2-index.html)

入门案例

pom.xml

		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-api</artifactId>
			<version>2.8.2</version>
		</dependency>
		<dependency>
			<groupId>org.apache.logging.log4j</groupId>
			<artifactId>log4j-core</artifactId>
			<version>2.8.2</version>
		</dependency>
log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
  <Appenders>
    <Console name="Console" target="SYSTEM_OUT">
      <PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
    </Console>
  </Appenders>
  <Loggers>
    <Root level="info">
      <AppenderRef ref="Console"/>
    </Root>
  </Loggers>
</Configuration>
helloworld
package log4j;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class HelloWorld {
    private static final Logger logger = LogManager.getLogger("HelloWorld");
    public static void main(String[] args) {
        logger.info("Hello, World!");
    }
}
     访问打印:10:38:51.978 [main] INFO  HelloWorld - Hello, World!
     简单解释下:log4j的2版本之后,其配置文件名需更改log4j2.xxx,上述的入门案例中,配置info级别的控制台Console日志.

log4j详解

log4j配置属性

        log4j2配置支持多种方式properties,xml,json,yaml,以xml配置为例进行讲解

基本架构(xml)

<?xml version="1.0" encoding="UTF-8"?>;
<Configuration>
  <Properties>
    <Property name="name1">value</property>
    <Property name="name2" value="value2"/>
  </Properties>
  <filter  ... />
  <Appenders>
    <appender ... >
      <filter  ... />
    </appender>
    ...
  </Appenders>
  <Loggers>
    <Logger name="name1">
      <filter  ... />
    </Logger>
    ...
    <Root level="level">
      <AppenderRef ref="name"/>
    </Root>
  </Loggers>
</Configuration>
        基本解释
  • Loggers:配置不同的logger对象,root表示根对象,logger为普通对象(与root为父子关系,获取不到logger则使用root)
  • Appenders:输出形式,console,file....
  • filter:过滤
  • properties:通用属性命名
       此configuration没有进行配置,可以关注其中的两个属性status(与level取值一样,不过针对的是log4j本身内部处理,一般在启动报错时使用)与monitorInterval(间隔一段时间加载log4j2.xml)

输出级别(level)

      log4j定义的级别有OFF,FATAL,ERROR,WARN,INFO,DEBUG,TRACE,ALL,各个级别通过都有其对应intLevel,值越小,级别越高
log4j
        用户可在xml中自定义level级别
  <CustomLevels>
    <CustomLevel name="NOTICE" intLevel="450" />
  </CustomLevels>
       注:name是大小写敏感,使用level API获取时name必须一致,name有两种命名规则,一个是按照name(API LogManager.getLogger(String name)),一个按照包名(API LogManager.getLogger(Class class))

输出形式(appender)

       log4j的输出形式有多种File,Console,Async,JDBC...以常用的Console(主要调试使用),File(记录日志),Async(异步日志)为例

console

log4j
         属性:
  • filter:过滤,通过level,onMatch,onMismath控制(filter)
  • layout:输出格式,可以通过PatternLayout进行覆盖定义PatternLayout
  • follow.direct:是否输出转移(可以system输出流,以及重定向),两者不能同时使用.此属性基本不使用
  • name:名称标识(配置中要设置唯一)
  • ignoreExceptions:默认false,设置true时,要设置错误处理Appender-FailoverAppender
  • target:控制台输出SYSTEM_OUT or SYSTEM_ERR
示例见入门案例

file

        file有多种,FileAppender,RandomAccessFileAppender,RollingFileAppender,RollingRandomAccessFileAppender,file与randomAccessFile的主要区别在写入流上,前者使用BufferedOutputStream,后者则是ByteBuffer + RandomAccessFile,都开启缓存的前提下后着效率有20-200%的提升(appender效率测评),file与rollingFile的区别在生成策略上,前者仅只有一个log文件,后者则是根据策略生成多个日志文件.项目开发中,file用的相对比较少(一次性日志或日志量比较小),持续的日志打印,基本都是使用RollingRandomAccessFileAppender.

randomAccessFileAppender
log4j
       这里重点关注几个属性
  • append:是否追加,一般设置true,不然每次都会覆盖
  • immediateFlush:是否立即刷新,同步日志用的多些
  • bufferSize:缓存量
        这个appender应用最为广泛,重点解释下

 log4j              重点关注strategy(TriggeringPolicies)policy(RolloverStrategies)两个属性,strategy指的是日志rollover(日志合并,比如讲一天的日志压缩一个zip)策略,policy指触发生成新文件策略.以压缩zip为例
policy
  • CompositeTriggeringPolicy:通过Policies定义
  • CronTriggeringPolicy:cron表达式(cron expression)触发
  • OnStartupTriggeringPolicy:初始文件创建,日志创建时间晚于jvm启动时间,则生成一个文件
  • SizeBasedTriggeringPolicy:容量触发,设置size,超过则触发(针对单个文件大小)
  • TimeBasedTriggeringPolicy :周期性触发压缩,interval设置周期间隔(默认1,没有单位,单位已pattern的最小时间单元),modulate-时间调整,为true,将以0点作为边界偏移(false以第一个file文件生成时间为边界偏移)--此属性要配置filePattern使用
       常用SizeBasedTriggeringPolicy,TimeBasedTriggeringPolicy 
        strategy常用DefaultRolloverStrategy,DirectWriteRolloverStrategy用的少
        DefaultRolloverStrategy属性
  • fileIndex:默认min,可选max,针对pattern中的%i属性,设置min,最新的日志文件i最小,max反之
  •  min:最小压压缩文件(此处指zip)数,默认1
  • max:最大压缩文件数,默认无上限,设置了达到阈值将会删除最老的一个
  • compressionLevel:压缩级别0-9.只对zip有效
        当不配置DefaultRolloverStrategy,默认的max=7,值得一提的是,当同时配置SizeBasedTriggeringPolicy,TimeBasedTriggeringPolicy只要满足一个就可以,当只满足SizeBasedTriggeringPolicy,生成的压缩文件数为max-1.

        异步日志是log4j2的一个特色,另外单独开一个线程记录日志,但是是否能提升性能应针对具体的应用场景(Log4j异步)
log4j
        重点关注其中的bufferSize,记录日志事件的队列长度,当值设置过小时,当日志的打印到文件的速度赶不上调用端传给AsyncAppender的速度时, AsyncAppender就把未输出到文件的日志信息存放到这个队列中,当这个队列塞满后,AsyncAppender就会丢弃新传入的日志信息.
        其基本使用配置,在Appenders>配置
<Async name="Async">
     <AppenderRef ref="MyFile"/>
</Async>

PatternLayout

      其参数格式太多,仅列基础参考
 %p: 输出日志信息优先级,即DEBUG,INFO,WARN,ERROR,FATAL,
 %d: 输出日志时间点的日期或时间,默认格式为ISO8601,也可以在其后指定格式,比如:%d{yyy MMM dd HH:mm:ss,SSS},输出类似:2002年10月18日 22:10:28,921
 %r: 输出自应用启动到输出该log信息耗费的毫秒数
 %c: 输出日志信息所属的类目,通常就是所在类的全名
 %t: 输出产生该日志事件的线程名
 %l: 输出日志事件的发生位置,相当于%C.%M(%F:%L)的组合,包括类目名、发生的线程,以及在代码中的行数。举例:Testlog4.main (TestLog4.java:10)
 %x: 输出和当前线程相关联的NDC(嵌套诊断环境),尤其用到像java servlets这样的多客户多线程的应用中。
 %%: 输出一个"%"字符
 %F: 输出日志消息产生时所在的文件名称
 %L: 输出代码中的行号
 %m: 输出代码中指定的消息,产生的日志具体信息
 %n: 输出一个回车换行符,Windows平台为"/r/n",Unix平台为"/n"输出日志信息换行
 
可以在%与模式字符之间加上修饰符来控制其最小宽度、最大宽度、和文本的对齐方式。
如:
%20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,默认的情况下右对齐。
%-20c:指定输出category的名称,最小的宽度是20,如果category的名称小于20的话,"-"号指定左对齐。
%.30c:指定输出category的名称,最大的宽度是30,如果category的名称大于30的话,就会将左边多出的字符截掉,但小于30的话也不会有空格。
%20.30c:如果category的名称小于20就补空格,并且右对齐,如果其名称长于30字符,就从左边较远输出的字符截掉。

归类与级别控制

       好的日志管理必须实现日志的归类存储,横向归类一般指业务归类,纵向归类就是级别的归类,不同的级别应有独立的处理.

归类

        示例
	<loggers>
		<root level="info">
			<appender-ref ref="console" />
			<appender-ref ref="info" />
			<appender-ref ref="error" />
		</root>
		<logger name="serviceOne" level="info" additivity="fasle">
			<appender-ref ref="serviceOne" />
		</logger>
	</loggers>
       通过loggers设置所有的logger对象,root是根对象,logger是普通对象,当使用api获取logger的时候,当得不到logger,会使用root logger,并执行root里面所有的appender.
级别控制,logger中的additivity=false表示不传递给父logger处理(此处指的root logger)

级别控制

       级别的过滤控制主要通过level与filter实现,level有继承性,即子标签的level会继承父类的标签
level与filter
          有level的标签Logger,Filter有ThresholdFilter,BurstFilter(用户控制日志时间的 处理速率,它会在日志事件达到最大限制是丢弃日志事件filter),关注其中的门槛过滤器ThresholdFilter,此filter是对logger级别的补充.
ThresholdFilter
log4j

         filter可以配置在configuration,appender,logger,配置多个用fiters标签包裹       
         onMatch与onMismatch都有三个返回值(返回值决定是否继续向下传递)
  • ACCEPT:接收,表示有此过滤器处理,进入下个级别的过滤器
  • DENY :丢弃,终止在同级的过滤器中传递,在configuration或logger中丢弃后,其他也不会处理
  • NEUTRAL:中立 表示会传递给同级别的过滤器处理(也就是同一个一个filters标签下的filter)

log4j使用

基本使用       

基本配置 
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="error" monitorInterval="300">
	<properties>
		<property name="LOG_HOME">C:/Users/admin/Desktop/temp</property>
	</properties>
	<appenders>
		<!-- 控制台打印,调试使用 -->
		<Console name="console" target="SYSTEM_OUT">
			<ThresholdFilter level="info" onMatch="ACCEPT"
				onMismatch="DENY" />
			<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%-4p] [%l] - %m%n" />
		</Console>

		<RollingRandomAccessFile name="error"
			immediateFlush="true" fileName="${LOG_HOME}/error.log" append="true"
			bufferSize="1024" filePattern="${LOG_HOME}/error/%d{yyyy-MM-dd}/%d{HH}-%i.log.zip">
			<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%-4p] [%l] - %m%n" />

			<!--只处理error级别及以上 -->
			<ThresholdFilter level="error" onMatch="ACCEPT"
				onMismatch="DENY" />
			<Policies>
				<!--每个文件不超过100M -->
				<SizeBasedTriggeringPolicy size="100Mb" />
				<!--每个24小时进行一次压缩zip -->
				<TimeBasedTriggeringPolicy interval="24"
					modulate="true" />
			</Policies>
			<!--最多只保存100压缩文件,结合上面的24小时压缩一次,也就是只保留100天的操作日志 -->
			<DefaultRolloverStrategy max="100" />
		</RollingRandomAccessFile>

		<RollingRandomAccessFile name="info"
			immediateFlush="false" fileName="${LOG_HOME}/info.log" append="true"
			bufferSize="10240" filePattern="${LOG_HOME}/info/%d{yyyy-MM-dd/%d{HH}-%i.log.zip">
			<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%-4p] [%l] - %m%n" />
			<ThresholdFilter level="info" onMatch="ACCEPT"
				onMismatch="DENY" />
			<Policies>
				<SizeBasedTriggeringPolicy size="100M" />
				<TimeBasedTriggeringPolicy interval="24"
					modulate="true" />
			</Policies>
			<DefaultRolloverStrategy max="100" />
		</RollingRandomAccessFile>

		<!-- 业务logger -->
		<Console name="serviceOne" target="SYSTEM_OUT">
			<Filters>
				<ThresholdFilter level="info" onMatch="ACCEPT"
					onMismatch="DENY" />
			</Filters>
			<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%-4p] [%l] - %m%n" />
		</Console>

		<!-- 异步日志 -->
		<Async name="asyncService">
			<AppenderRef ref="asyncService" />
		</Async>
		<RollingRandomAccessFile name="asyncService"
			immediateFlush="false" fileName="${LOG_HOME}/asyncService.log" append="true"
			bufferSize="10240" filePattern="${LOG_HOME}/info/%d{yyyy-MM-dd/%d{HH}-%i.log.zip">
			<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}] [%-4p] [%l] - %m%n" />
			<ThresholdFilter level="info" onMatch="ACCEPT"
				onMismatch="DENY" />
			<Policies>
				<SizeBasedTriggeringPolicy size="100M" />
				<TimeBasedTriggeringPolicy interval="24"
					modulate="true" />
			</Policies>
			<DefaultRolloverStrategy max="100" />
		</RollingRandomAccessFile>
	</appenders>

	<loggers>
		<root level="info">
			<!--根处理logger -->
			<appender-ref ref="console" />
			<appender-ref ref="info" />
			<appender-ref ref="error" />
		</root>
		<logger name="serviceOne" level="info" additivity="false">
			<appender-ref ref="serviceOne" />
		</logger>
		<logger name="asynclog" level="info" additivity="false">
			<AppenderRef ref="asyncService" />
		</logger>
	</loggers>
</Configuration>


        
       log4j在代码中可显示调用

package log4j;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class HelloWorld {
	/*获取logger
	 *通过name获取,在logger标签中以name进行匹配(name区分大小写),没有将使用root logger
	 *通过class匹配,最终class将转换为package.Class作为name进行匹配(此处就是log4j.HelloWorld,但匹配规则与前者不一样,是根据包名来匹配)
	 * */
    private static final Logger logger = LogManager.getLogger("serviceOne");
    
    public static void main(String[] args) {
    	/*logger使用api很广泛,摘取几处简单说明*/
    	/*调用不同的level*/
    	logger.trace("trace");
    	logger.debug("debug");
    	logger.info("info");
    	logger.warn("warn");
    	logger.error("error");
    	logger.fatal("fatal");
    	
    	/*输出不同的内容格式*/
    }
}

mybatis 打印日志

       搭建个简单的mybatis运行环境(mybatis log):
       mybatis数据库新建表blog,内置id,name两个字段
pom.xml引入
		<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
		<dependency>
			<groupId>org.mybatis</groupId>
			<artifactId>mybatis</artifactId>
			<version>3.4.4</version>
		</dependency>
		<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
		<dependency>
			<groupId>mysql</groupId>
			<artifactId>mysql-connector-java</artifactId>
			<version>5.1.43</version>
		</dependency>
blogMapper
package mybatis;

import org.apache.ibatis.annotations.Select;

public interface BlogMapper {
	  @Select("SELECT * FROM blog WHERE id = #{id}")
	  Blog selectBlog(int id);
}

blog
package mybatis;

public class Blog {
	private Integer id;
	private String name;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	
}
mybtis-config.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>  
        <setting name="logImpl" value="LOG4J2" />  
    </settings>  
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC" />
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true" />
				<property name="username" value="root" />
				<property name="password" value="123" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<package name="mybatis" />
		<!-- 采用注解 -->
		<!-- <mapper resource="org/mybatis/example/BlogMapper.xml"/> -->
	</mappers>
</configuration>
log4j2.xml中<loggers>标签下添加
		<logger name="mybatis.BlogMapper"  level="TRACE"  additivity="false">
				<AppenderRef ref="mybatis" />
		</logger>
<appenders>标签下添加
		<!-- mybatis logger -->
		<Console name="mybatis" target="SYSTEM_OUT">
			<Filters>
				<ThresholdFilter level="TRACE" onMatch="ACCEPT"
					onMismatch="DENY" />
			</Filters>
			<PatternLayout pattern="[%d{yyyy-MM-dd}] [%-4p] [%l] - %m%n" />
		</Console>
test
package mybatis;

import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class TestMyBbatis {
public static void main(String[] args) throws Exception {
	String resource = "mybatis-config.xml";
	InputStream inputStream = Resources.getResourceAsStream(resource);
	SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
	SqlSession session = sqlSessionFactory.openSession();
	try {
		  BlogMapper mapper = session.getMapper(BlogMapper.class);
		  Blog blog = mapper.selectBlog(1);
		  System.out.println(blog.getName());
	} finally {
	  session.close();
	}
	
	//结果打印
/*	[2017-08-18] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] - ==>  Preparing: SELECT * FROM blog WHERE id = ? 
	[2017-08-18] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] - ==> Parameters: 1(Integer)
	[2017-08-18] [TRACE] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)] - <==    Columns: id, name
	[2017-08-18] [TRACE] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.trace(BaseJdbcLogger.java:165)] - <==        Row: 1, 张三
	[2017-08-18] [DEBUG] [org.apache.ibatis.logging.jdbc.BaseJdbcLogger.debug(BaseJdbcLogger.java:159)] - <==      Total: 1
*/
}
}

hibernate 打印日志

         搭建hibernate运行环境(hibernate log,官网的配置不生效(hibernate 官方log),尴尬)
pom.xml中新增
		<!--hibernate所需依赖 -->
		<dependency>
			<groupId>org.hibernate</groupId>
			<artifactId>hibernate-core</artifactId>
			<version>5.1.3.Final</version>
		</dependency>
model
package hibernate;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
public class Blog {
	private Integer id;
	private String name;
	private Integer age;
	@Id
	@GeneratedValue(strategy = GenerationType.IDENTITY)
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public Integer getAge() {
		return age;
	}
	public void setAge(Integer age) {
		this.age = age;
	}
	
	
}
hibernate.cfg.xml
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">

<hibernate-configuration>
	<session-factory>
		<!-- 数据库连接配置 -->
		<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
		<property name="connection.url">jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&rewriteBatchedStatements=true</property>
		<property name="connection.username">root</property>
		<property name="connection.password">123</property>
		<!-- 数据库连接池的大小 -->
		<property name="connection.pool_size">5</property>
		<!-- 每次从数据库中取出并放到JDBC的Statement中的记录条数。Fetch Size设的越大,读数据库的次数越少,速度越快,Fetch 
			Size越小,读数据库的次数越多,速度越慢 -->
		<property name="jdbc.fetch_size">50 </property>
		<!--批量插入,删除和更新时每次操作的记录数。Batch Size越大,批量操作的向数据库发送Sql的次数越少,速度就越快,同样耗用内存就越大 -->
		<property name="jdbc.batch_size">23 </property>
		<!-- SQL 方言 -->
		<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
		<!-- Enable Hibernate's automatic session context management -->
		<property name="current_session_context_class">thread</property>
		<!-- 是否显示sql -->
		<property name="show_sql">true</property>
		<!-- 是否格式化sql -->
		<property name="format_sql">true</property>
		<!-- 是否使用注释 -->
		<property name="use_sql_comments">false</property>
		<!-- 在启动时根据配置更新数据库 -->
		<!-- <property name="hbm2ddl.auto">update</property> -->
		
		<!-- 注册我们的实体映射类 -->
		<mapping class="hibernate.Blog" />
	</session-factory>
</hibernate-configuration>
log4j2.xml中<loggers>新增
		<logger name="org.hibernate.type.descriptor.sql"  level="TRACE"  additivity="false">
				<AppenderRef ref="hibernate" />
		</logger>
<appenders>标签新增
		<!-- hibernate logger -->
		<Console name="hibernate" target="SYSTEM_OUT">
			<Filters>
				<ThresholdFilter level="TRACE" onMatch="ACCEPT"
					onMismatch="DENY" />
			</Filters>
			<PatternLayout pattern="[%d{yyyy-MM-dd}] [%-4p] [%l] - %m%n" />
		</Console>
test
package hibernate;

import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.criterion.PropertyExpression;
import org.hibernate.criterion.Restrictions;

public class TestHibernate {
	public static void main(String[] args) {
		   //相对于3.x.x版本hibernate,我们在4.x.x采用如下方式获取我们的会话工厂:
	    //1. 解析我们在hibernate.cfg.xml中的配置
//	      Configuration configuration = new Configuration().configure();
	    //2. 创建服务注册类,进一步注册初始化我们配置文件中的属性
//	      ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry();
	    //3. 创建我们的数据库访问会话工厂
//	      SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);

	    //但在5.1.0版本汇总,hibernate则采用如下新方式获取:
	    //1. 配置类型安全的准服务注册类,这是当前应用的单例对象,不作修改,所以声明为final
	    //在configure("cfg/hibernate.cfg.xml")方法中,如果不指定资源路径,默认在类路径下寻找名为hibernate.cfg.xml的文件
	    final StandardServiceRegistry registry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build();
	    //2. 根据服务注册类创建一个元数据资源集,同时构建元数据并生成应用一般唯一的的session工厂
	    SessionFactory sessionFactory = new MetadataSources(registry).buildMetadata().buildSessionFactory();

	    /****上面是配置准备,下面开始我们的数据库操作******/
	    Session session = sessionFactory.openSession();//从会话工厂获取一个session
	    session.get(Blog.class, 1);
	    
	    Criteria criteria = session.createCriteria(Blog.class);
	    criteria.add(Restrictions.eq("name", "lisi"));
	    criteria.add(Restrictions.eq("age", 1));
	    criteria.uniqueResult();
	    
	    session.createQuery("From Blog where name='lisi' and age=1").uniqueResult();
	    
/*	    Transaction transaction = session.beginTransaction();//开启一个新的事务
	    transaction.commit();//提交事务
*/
	    
	    
	    //打印
/*	    Hibernate: 
	        select
	            blog0_.id as id1_0_0_,
	            blog0_.age as age2_0_0_,
	            blog0_.name as name3_0_0_ 
	        from
	            Blog blog0_ 
	        where
	            blog0_.id=?
	    [2017-08-18] [TRACE] [org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:65)] - binding parameter [1] as [INTEGER] - [1]
	    [2017-08-18] [TRACE] [org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:61)] - extracted value ([age2_0_0_] : [INTEGER]) - [2]
	    [2017-08-18] [TRACE] [org.hibernate.type.descriptor.sql.BasicExtractor.extract(BasicExtractor.java:61)] - extracted value ([name3_0_0_] : [VARCHAR]) - [张三]
	    Hibernate: 
	        select
	            this_.id as id1_0_0_,
	            this_.age as age2_0_0_,
	            this_.name as name3_0_0_ 
	        from
	            Blog this_ 
	        where
	            this_.name=? 
	            and this_.age=?
	    [2017-08-18] [TRACE] [org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:65)] - binding parameter [1] as [VARCHAR] - [lisi]
	    [2017-08-18] [TRACE] [org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:65)] - binding parameter [2] as [INTEGER] - [1]
	    [2017-08-18 16:17:14] [INFO] [org.hibernate.hql.internal.QueryTranslatorFactoryInitiator.initiateService(QueryTranslatorFactoryInitiator.java:47)] - HHH000397: Using ASTQueryTranslatorFactory
	    Hibernate: 
	        select
	            blog0_.id as id1_0_,
	            blog0_.age as age2_0_,
	            blog0_.name as name3_0_ 
	        from
	            Blog blog0_ 
	        where
	            blog0_.name='lisi' 
	            and blog0_.age=1*/
	}
}
相关标签: log4j2