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


用hibernate寫一些簡單的數據庫的Java應用。主要是溫習一下。之前弄過的一些都忘了。發現還是得記下來,不然很快就忘。

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

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

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。

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

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

之后出現這個窗口:

如果沒有配置數據庫連接就New一個,如果已經有的話就選擇一個。Configuration file沒有的話就Setup一個。

 

在這個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目錄下。

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM