備忘:hibernate, logback, slf4j實際應用一例

用hibernate寫一些簡單的數據庫的Java應用。主要是溫習一下。以前弄過的一些都忘了。發現仍是得記下來,否則很快就忘。java

1. Eclipse版本,用Juno, J2EE版本。最好下載zip版本的,直接解壓就運行。mysql

2. JDK安裝,到Oracle上搜索jdk, 而後下載。安裝JDK後,設置JAVA_HOME,指到JDK安裝目錄,將%JAVA_HOME%\bin放到PATH變量的最前面。sql

3. Maven。到Eclipse marketplace上搜索maven, 會有一個Maven Integration for Eclipse (Juno or newer), by Eclipse.org, 安裝它。它裏面有maven。數據庫

4. Jboss tools. 到Eclipse marketplace上搜索jboss tools,會有一個jboss tools (Juno), by Red hat Inc. 安裝它。它裏面有hibernate tools, 固然也有別的工具。暫時是隻用hibernate tools。apache

5. 根據數據庫來生成hibernate的類文件或者hbm.xml,cfg.xml等。api

Windows->Open Perspectives->Other, 而後選hibernate perspective,而後鼠標右鍵點擊左邊的hibernate Configurations窗口,出來一個彈出菜單,選Add Configuration。如圖:網絡

以後出現這個窗口:session

若是沒有配置數據庫鏈接就New一個,若是已經有的話就選擇一個。Configuration file沒有的話就Setup一個。app

 

在這個hibernate視圖裏有一個Hibernate Code Generation 按鈕。如圖:異步

 固然了,在Run菜單裏也有一個。Run-> Hibernate Code Generation->Hibernate Code Generation Config。如圖:

 以後是這樣的配置窗口:

在Console configuration那裏選擇以前創建的Console configuration。再輸入package name等。點擊Exporters Tab.

 

若是你想用Entity class加*.hbm.xml文件的方式,那就去掉Generate EJB3 annotation的鉤,並勾上hbm.xml和cfg.xml的選項。如今這樣的選擇是採用,有EJB3 annotation的class和cfg.xml就能夠了。相對比較簡潔和漂亮。因此就這樣了。

這個Hibernate code generation的配置創建好了。隨後運行它。而後就在咱們剛指定的路徑裏產生了多個java文件。

這是其中一個類:

 看到沒有,Id字段有EJB3的annotation. 其餘的字段也有。

以後咱們要將pom.xml文件準備好。

<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>mymaven</groupId>
  <artifactId>mymaven</artifactId>
  <version>0.0.1-SNAPSHOT</version>
  <dependencies>
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate</artifactId>
          <version>3.5.4-Final</version>
          <type>pom</type>
      </dependency>
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-annotations</artifactId>
          <version>3.5.4-Final</version>
      </dependency>
      <dependency>
          <groupId>org.hibernate</groupId>
          <artifactId>hibernate-core</artifactId>
          <version>3.5.4-Final</version>
      </dependency>
      <dependency>
          <groupId>org.javassist</groupId>
          <artifactId>javassist</artifactId>
          <version>3.18.2-GA</version>
      </dependency>
      <dependency>
          <groupId>org.slf4j</groupId>
          <artifactId>slf4j-api</artifactId>
          <version>1.7.7</version>
      </dependency>
      <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-classic</artifactId>
          <version>1.1.2</version>
      </dependency>
      <dependency>
          <groupId>ch.qos.logback</groupId>
          <artifactId>logback-core</artifactId>
          <version>1.1.2</version>
      </dependency>
      <dependency>
          <groupId>mysql</groupId>
          <artifactId>mysql-connector-java</artifactId>
          <version>5.1.31</version>
      </dependency>
  </dependencies>
</project>

這裏得說javassist必須得要。hibernate須要這個庫。要不就會出錯。那個錯誤是說不能初始化PojoTuplizer的實例。找了本人很久啊。別的庫也都是要的。
既然用了logback,就要一個logback.xml:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <!--定義日誌文件的存儲地址 勿在 LogBack 的配置中使用相對路徑-->  
    <property name="LOG_HOME" value="c:/log" />  
    <!-- 控制檯輸出 -->   
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
       <!-- 日誌輸出編碼 -->  
       <Encoding>UTF-8</Encoding>   
        <layout class="ch.qos.logback.classic.PatternLayout">   
             <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日誌消息,%n是換行符--> 
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n   
            </pattern>   
        </layout>   
    </appender>   
    <!-- 按照天天生成日誌文件 -->   
    <appender name="FILE"  class="ch.qos.logback.core.rolling.RollingFileAppender">   
        <Encoding>UTF-8</Encoding>   
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--日誌文件輸出的文件名-->
            <FileNamePattern>${LOG_HOME}/myApp.log.%d{yyyy-MM-dd}.log</FileNamePattern>   
            <MaxHistory>30</MaxHistory>
        </rollingPolicy>   
        <layout class="ch.qos.logback.classic.PatternLayout">  
            <!--格式化輸出:%d表示日期,%thread表示線程名,%-5level:級別從左顯示5個字符寬度%msg:日誌消息,%n是換行符--> 
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n   
            </pattern>   
       </layout> 
        <!--日誌文件最大的大小-->
       <triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
         <MaxFileSize>10MB</MaxFileSize>
       </triggeringPolicy>
    </appender> 
   <!-- show parameters for hibernate sql 專爲 Hibernate 定製 -->  
    <logger name="org.hibernate.type.descriptor.sql.BasicBinder"  level="TRACE" />  
    <logger name="org.hibernate.type.descriptor.sql.BasicExtractor"  level="DEBUG" />  
    <logger name="org.hibernate.SQL" level="DEBUG" />
    <logger name="org.hibernate.type" level="TRACE" />
    <logger name="org.hibernate.engine.QueryParameters" level="DEBUG" />  
    <logger name="org.hibernate.engine.query.HQLQueryPlan" level="DEBUG" />  
    
    <!-- 日誌輸出級別 -->
    <root level="INFO">   
        <appender-ref ref="STDOUT" />   
        <appender-ref ref="FILE" />   
    </root> 
     
     <!--日誌異步到數據庫 -->  
    <!-- <appender name="DB" class="ch.qos.logback.classic.db.DBAppender">
        <connectionSource class="ch.qos.logback.core.db.DriverManagerConnectionSource">
           <dataSource class="com.mchange.v2.c3p0.ComboPooledDataSource">
              <driverClass>com.mysql.jdbc.Driver</driverClass>
              <url>jdbc:mysql://127.0.0.1:3306/databaseName</url>
              <user>root</user>
              <password>root</password>
            </dataSource>
        </connectionSource>
  </appender> -->
</configuration>

這裏說明一下。在別的網絡文章能找到別的配置項,卻沒有這個:

    <logger name="org.hibernate.type" level="TRACE" />

加上這個才真正能讓SQL 中的參數被打印出來。僅有其他的設置沒有用。

這裏有一些log:

2014-06-23 21:47:01.748 [main] INFO  org.hibernate.impl.SessionFactoryObjectFactory - Not binding factory to JNDI, no JNDI name configured
2014-06-23 21:47:01.787 [main] DEBUG org.hibernate.SQL -
    select
        category0_.CategoryId as CategoryId5_0_,
        category0_.CategoryName as Category2_5_0_,
        category0_.ParentCategoryId as ParentCa3_5_0_,
        category0_.ShortName as ShortName5_0_
    from
        mikelij.category category0_
    where
        category0_.CategoryId=?
Hibernate:
    select
        category0_.CategoryId as CategoryId5_0_,
        category0_.CategoryName as Category2_5_0_,
        category0_.ParentCategoryId as ParentCa3_5_0_,
        category0_.ShortName as ShortName5_0_
    from
        mikelij.category category0_
    where
        category0_.CategoryId=?
2014-06-23 21:47:01.800 [main] TRACE org.hibernate.type.IntegerType - binding '5' to parameter: 1
2014-06-23 21:47:01.806 [main] TRACE org.hibernate.type.StringType - returning '情感' as column: Category2_5_0_
2014-06-23 21:47:01.806 [main] TRACE org.hibernate.type.IntegerType - returning '5' as column: ParentCa3_5_0_
2014-06-23 21:47:01.806 [main] TRACE org.hibernate.type.StringType - returning 'qinggan' as column: ShortName5_0_
2014-06-23 21:47:01.809 [main] INFO  org.nf.myfirst - Found
2014-06-23 21:47:01.816 [main] INFO  org.nf.myfirst - End

看到沒有:binding '5' to parameter: 1, 這是SQL的輸入參數。後面幾個是返回的字段值。

 

<?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="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="connection.release_mode">on_close</property>
        <property name="transaction.auto_close_session">false</property>
        <property name="connection.autocommit">false</property>
        <property name="hibernate.bytecode.use_reflection_optimizer">false</property>
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <property name="hibernate.connection.password">dddd</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mikelij</property>
        <property name="hibernate.connection.username">root</property>
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.search.autoregister_listeners">false</property>
        <property name="hibernate.current_session_context_class">thread</property>
        <mapping class="org.nf.model.Sensitivekeyword" />
        <mapping class="org.nf.model.Comment" />
        <mapping class="org.nf.model.Group" />
        <mapping class="org.nf.model.Post" />
        <mapping class="org.nf.model.User" />
        <mapping class="org.nf.model.Category" />
        <mapping class="org.nf.model.Message" />
    </session-factory>
</hibernate-configuration>

這裏的說明比較多。首先mapping 都是用mapping class來配置hibernate的。若是是hbm.xml,那麼就是用的mapping 文件來作的。
另外這句<property name="hibernate.current_session_context_class">thread</property>是爲了Java application準備的。它沒有JNDI環境。不象有Tomcat那樣的容器,默認提供了一個JNDI環境。因此Java application,這個context的class就得這個設置。不過,若是是Spring,就得用Spring提供的Context class。

        <property name="show_sql">true</property>
        <property name="format_sql">true</property>
        <property name="connection.release_mode">on_close</property>
        <property name="transaction.auto_close_session">false</property>
        <property name="connection.autocommit">false</property>

這幾句是爲了顯示sql和格式化sql。另外是爲了讓Session不自動close。不自動提交。

如今這裏是Java代碼:

package org.nf;
import org.hibernate.*;
import org.hibernate.cfg.*;
import org.nf.model.*;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class myfirst {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Logger logger = LoggerFactory.getLogger(myfirst.class);
        logger.info("Start");
        Configuration config = new AnnotationConfiguration();
        config.configure();
        SessionFactory factory = config.buildSessionFactory();
        Session session = factory.openSession();
        Transaction transaction = session.beginTransaction();
        Category category = (Category) session.get(Category.class, 5);
        if (category.getCategoryName() != "")
             logger.info("Found");
        transaction.commit();
        session.close();
        logger.info("End");
    }

}

由於用的是Annotation,因此用的是AnnotationConfiguration類。factory的openSession和openCurrentSession方法有一個區別。openCurrentSession獲得的Session會被Transaction.Commit自動關閉Session。而openSession獲得的Session不會由於Transaction.Commit而自動關閉。因此能夠創建另一個Transaction。鏈接仍是同一個。沒有關閉過。這個有什麼用嗎?固然有用,當有大批量數據操做的時候,能夠提交一部分到數據庫去處理,而後繼續後續的數據處理。這樣能夠提升整個大批量數據的數據處理速度。

logback.xml和hibernate.cfg.xml都是屬於資源文件。在maven中,默認把這類字段文件放到src/main/resources目錄下最好:

若是是測試工程的資源文件,能夠放在src/test/resources目錄下。

相關文章
相關標籤/搜索