hibernate 的自动生成工具

1. Middlegen
是用来从DB中已存在的表,生成相应的mapping file. 可以下载一个老外的middlegen的例子。

http://sourceforge.net/project/showfiles.php?group_id=40712

调用Middlegen很简单,例子中的middlegen自动生成ant指令如下

<middlegen
         appname="${name}"
         prefsdir="${src.dir}"
         gui="${gui}"
         databaseurl="${database.url}"
         initialContextFactory="${java.naming.factory.initial}"
         providerURL="${java.naming.provider.url}"
         datasourceJNDIName="${datasource.jndi.name}"
         driver="${database.driver}"
         username="${database.userid}"
         password="${database.password}"
         
      >
     <hibernate
            destination="${build.gen-src.dir}"
            package="${name}.hibernate"
      />
  </middlegen>

然后会有一个GUI,给我们专门设计各种表与表之间的关系(一对一,一对多以及单向双向关系)。需要说明的是,middlegen生成的代码没有直接写mapping file灵活性好,所以生成的mapping file有时还需要我们去修改。

2. XDoclet
它是用来从java文件自动生成hbm文件的,不过我们需要在java代码中写一些规定的tag,才能得到自动生成的hbm文件.

<hibernatedoclet
          destdir="src"
          excludedtags="@version,@author,@todo"
          force="true"
          verbose="true">
          <fileset dir="src">
              <include name="**/*.java"/>
              <exclude name="**/Product.java"/>
          </fileset>
          <hibernate version="2.0"/>
    </hibernatedoclet>

3. hbm2java

它是用来从mapping 文件生成java代码的工具,调用很简单,在参数中需要给出所有的hbm文件,如下:

<java classname="net.sf.hibernate.tool.hbm2java.CodeGenerator" fork="true">
      <classpath refid="classpath"/>
      <arg line="${build.gen-src.dir}/airline/hibernate/*.hbm.xml"/>
    </java>

4. Schema Export

如果写好了java文件和hbm文件,就可以用SchemaExport直接生成DDL文件,调用同样简单,只需在java代码中,加入如下:

     conf = new Configuration()
          .addClass(a.class)
          .addClass(b.class);
     SchemaExport dbExport = new SchemaExport(conf);
     dbExport.setOutputFile("myschema.sql");
     dbExport.create(true, true);

从这四种自动生成工具来看, mapping file, java file and DDL,只要知道任何一种文件,都可以得到另外两种文件,

如:

1. 只有mapping file:

mapping file---hbm2java----java---SchemaExport----DDL

2.只有DDL

DDL---Middlegen---hbm----hbm2java----java

3.只有Java

java---XDoclet---hbm----SchemaExport----DDL

从这里,大家也可以体会到, Hibernate强大的灵活性。


常见错误:
Caused by: org.dom4j.DocumentException: Invalid byte 2 of 2-byte UTF-8 sequence. Nested exception: Invalid byte 2 of 2-byte UTF-8 sequence.
如果出现这行错误说明你的xml配置文件有不规范的字符,检查下。

net.sf.hibernate.MappingException: Error reading resource: hibernate/Hello_Bean.hbm.xml


如果出现这行错误说明你的hibernate的XML配置文件有错

net.sf.hibernate.MappingException: Resource: hibernate/Hello_Bean.hbm.xml not found


如果出现这行错误说明hibernate的XML配置文件没有找到,你应该把XML文件放在与你的类文件同个目录下,本文中是放在hibernate\classes\hibernate\目录下,也就是跟Hello_Bean.class类文件一起。

net.sf.hibernate.PropertyNotFoundException: Could not find a setter for property name in class hibernate.Hello_Bean


如果出现这行错误说明你的xml文件里设置的字段名name的值与Hello_Bean.java类里的getXXX或setXXX方法不一致。

net.sf.hibernate.HibernateException: JDBC Driver class not found: org.gjt.mm.mysql.Driver
如果出现这行错误说明你的MYSQL驱动没有加进JB库里或者不在CLASSPATH里。
调试出现 net.sf.hibernate.MappingException 很有可能是由于
类库文件没有找到,类库的版本不同,他的名字会不同 要重新配置 setenv.bat
类库的路径。
[ERROR] CodeGenerator - Error parsing XML: file:/C:/projects/hibernate/javasampl
e/(1) <org.xml.sax.SAXParseException: Document root element "title", must match
DOCTYPE root "null".>org.xml.sax.SAXParseException: Document root element "title
", must match DOCTYPE root "null".

生成文件的路径不对
Middlegen工具 连接数据库把数据结构导为 hbm2.xml 文件
Middlegen-Hibernate-r5\config\database
mysql.xml 修改 数据库的连接文件

修改 Middlegen-Hibernate-r5\builder.xml 文件
<!ENTITY database SYSTEM "file:./config/database/mysql.xml">
执行ant 会出现 gui 的界面
hbm2java 配置 build.xml 文件 

<property name="src.dir" value="src/java"/>
源文件路径

.........
........

.....
<taskdef name="hbm2java"
classname="net.sf.hibernate.tool.hbm2java.Hbm2JavaTask"
classpathref="project.class.path"/>

<!-- Generate the java code for all mapping files in our source tree -->

<target name="codegen" description="Generate Java source from the O/R mapping files"> --任务名称
<echo message="运行 Hbm2Java 任务, 利用 hbm.xml 文件生成Java类文件"/>

<hbm2java output="${src.dir}"> -- 源文件目录
<fileset dir="${src.dir}">
<include name="**/*.hbm.xml"/> --输出目录
</fileset>
</hbm2java>
</target>

执行:
ant codegen
有*.java 文件生成 hbm 文件
<property name="hbm_src.dir" value="src"/>

<target name="config" description="Generate hbm files">
<taskdef name="hibernatedoclet" classpathref="classpath.build"
classname="xdoclet.modules.hibernate.HibernateDocletTask"/>
<echo>+---------------------------------------------------+</echo>
<echo>| |</echo>
<echo>| java 2 hbm |</echo>
<echo>| |</echo>
<echo>+---------------------------------------------------+</echo>

<hibernatedoclet destDir="${hbm_src.dir}">
<fileset dir="${hbm_src.dir}">
<include name="**/*.java"/>
</fileset>
<hibernate version="2.1"/>
</hibernatedoclet>

</target>

java 文件 和 hbm 放在一个目录下

需要配置hibernate.cfg.xml

<?xml version='1.0' encoding='GBK'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-2.0.dtd">

<hibernate-configuration>

<session-factory name="session">

<property name="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</property>

<!-- local connection properties -->
<property name="hibernate.connection.url">
jdbc:oracle:thin:@192.168.1.239:1521:beecool
</property>
<property name="hibernate.connection.driver_class">
com.mysql.jdbc.Driver
</property>
<property name="hibernate.connection.username">mailsys</property>
<property name="hibernate.connection.password">mailsys</property>


<property name="hibernate.show_sql">true</property>
<property name="hibernate.transaction.factory_class">
net.sf.hibernate.transaction.JDBCTransactionFactory
</property>

<property name="hibernate.use_outer_join">false</property>
<property name="hibernate.max_fetch_depth">0</property>

<property name="hibernate.jdbc.fetch_size">100</property>
<property name="hibernate.jdbc.batch_size">100</property>
<property name="hibernate.jdbc.use_streams_for_binary">true</property>

<property name="hibernate.cglib.use_reflection_optimizer">true</property>
<mapping resource="cn/sh/online/dreamtree/model/Blessing.hbm.xml" />
<mapping resource="cn/sh/online/dreamtree/model/Prize.hbm.xml" />
<mapping resource="cn/sh/online/dreamtree/model/Admin.hbm.xml" />
</session-factory>
</hibernate-configuration>


java 和 hbm 文件的命名空间要一致

hbm 和 class 文件输出 *.sql 文件

<property name="build.dir" location="WebRoot/WEB-INF/classes"/>
<target name="schemaexport">
<taskdef name="schemaexport" classpathref="classpath.build"
classname="net.sf.hibernate.tool.hbm2ddl.SchemaExportTask" />
<schemaexport
properties="${build.dir}/hibernate.properties"
quiet="no"
text="yes"
drop="no"
delimiter=";"
output="schema-export.sql">
<fileset dir="${build.dir}">
<include name="**/*.hbm.xml"/>
</fileset>
</schemaexport>

</target>

源目录要选择 classes hbm 和 class 文件

全部编译

<path id="classpath.build">
<fileset dir="hibernate-lib"/>
hibernate-lib 类库
<fileset dir="xdoclet-lib"/>
</path>



<target name="java" description="Compile Java">
<mkdir dir="${build.dir}"/>
<javac srcdir="${src.java}"
destdir="${build.dir}"
classpathref="classpath.build"
debug="true"/>

<copy todir="${build.dir}">
<fileset dir="${src.java}">
<exclude name="**/*.java"/>
</fileset>
</copy>
</target>

hibernate.cfg.xml

指定生成的数据库
<property name="hibernate.dialect">net.sf.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.dialect">net.sf.hibernate.dialect.OracleDialect</property>
<property name="hibernate.dialect">net.sf.hibernate.dialect.SybaseDialect</property>


oracle 包驱动
oracle.jdbc.driver.OracleDriver



net.sf.hibernate.util.JDBCExceptionReporter
No suitable driver
是由于数据库的hsql 语句有问题


jbuilder 执行程序 调用的是 classes 目录下的程序 所以要先builder 一下
所以要 copy hbm 文件到 classes 目录下面



Batch Size是设定对数据库进行批量删除,批量更新和批量插入的时候的批次大小,有点相当于设置Buffer缓冲区大小的意思。Batch Size越大,批量操作的向数据库发送sql的次数越少,速度就越快。我做的一个测试结果是当Batch Size=0的时候,使用Hibernate对Oracle数据库删除1万条记录需要25秒,Batch Size = 50的时候,删除仅仅需要5秒!!! 可见有多么大的性能提升!很多人做Hibernate和JDBC的插入性能测试会奇怪的发现Hibernate速度至少是JDBC的两倍,就是因为 Hibernate使用了Batch Insert,而他们写的JDBC没有使用Batch的缘故。以我的经验来看,Oracle数据库 Batch Size = 30 的时候比较合适,50也不错,性能会继续提升,50以上,性能提升的非常微弱,反而消耗内存更加多,就没有必要了。

hibernate 如何解决死锁的
pc 机 用 java 服务器 一般同时在线 1000人左右
list 在 空的时候 list.get(0) 错误 造成 weblogic 的系统 挂起

No suitable driver 引起的原因 数据库连接失败
在classes 查找 hibernate.cfg.xml 文件
<property name="hibernate.connection.url">
jdbc:oracle:thin:@192.168.1.239:1521:beecool
</property>
<property name="hibernate.connection.driver_class">
oracle.jdbc.driver.OracleDriver
</property>
主键自动生成
<id
name="announceid"
type="int"
column="ANNOUNCEID"
>
<generator class="vm" />
</id> 

Ant 的概念:

Ant 配置用 XML 的格式。XML非常适合用?表?多??的???料??。Ant 的?法也承?了????。

要? Ant ?自?化我?的工作,我?就必?在?案的目?中,撰? build.xml。

?然你可以使用其他的?案名?,如果使用其他?名,就必?在命令列指定???名。
假??名?abc.xml,命令列就必?改成:


ant -buildfile abc.xml。

build.xml 基本的??,包含了一?文件的根??:project;至少一? target ??;target???再包含 task ???指定 Ant 所要?行的任?。?情?需要,?可以使用 property ??,?定? Ant 的??。以下,分?介?每???的功用。


--------------------------------------------------------------------------------

project ??:

project ??是 build.xml 的文件根??。一?文件之中,只能有一?根??。project ??有以下三??性。

?性 ?明 是否必要
name ?案名? No
default 假?命令列未指定 target ?,???行的 target ?? Yes.
basedir 用?指定?案的根目?,???性可以使用"basedir" property ???改?,如果定? basedir的 property ??,在 project ??中,就不可以定????性。假使未使用???性或 property ???定? basedir的?,? Ant ?使用???案 build.xml 的目?,作? basedir。 No



--------------------------------------------------------------------------------

target ??:

target ??是 Ant ?行的目?,我?可以把各?命令(在 Ant 中的??,叫任? task),放在 target 的??中。所以,你可以把他想成是一?命令的?合,以程式????,接近副程式或不?回值的函式。

target 和 target 之?,可以使用 depends?性?定?彼此?的依存??。藉由定??些依存的??,我?可以改? target 的?行?序。也可以定? if 以及 unless ?性,??定是否?行?? target ??的工作。?有定? if 和 unless ?性的 target ??,一定?按照?序?行。

?性 ?明 是否必要
name target 的名? Yes
depends 在?行?? target ??之前,先要?行其他??的名?。如果是多????,以逗??隔各???。 No
if 指定 property 名?。必?定??? property ,才??行?? target的工作。 No
unless 指定 property 名?。必?不定??? property ,才??行?? target的工作。 No
description 文字?明 No



--------------------------------------------------------------------------------

task ??:

task ??,是 Ant ?行工作最基本的?位,?似程式??中的命令句。可分? core tasks 和 optional tasks ??,你也可以使用 java ?撰?自定的 task。

task 的??很?,各??性也不相同,要?用 task?,可?考 Ant 的?上?明。


--------------------------------------------------------------------------------

property ??:

property ??,定??案的?性值,?似程式??中的??。最常用的?性有 name 和 value。name 定??? property 的名?,value 定???property 的值。要?取 property 的值?,必?使用 ${property名?}的格式。

?例:

<project name="ex" default="hello">

<property name="who" value="Bush"/>

<task name="hello">

<echo message="Hello, ${who} "/>

</task>

</project>

?例演?:使用 Ant 上??案

我?在???用程式?,常常面?需要?理很多繁?的工作。使用 Ant 可以?助我??化???程。在使用 Ant 之前,你必?要先知道,你所要?理的工作有哪些。

以上??程?例,我?要把?完的 PHP ??程式,上?到伺服器。上??案???事,就可以交? Ant ??理。一般??,??是以FTP工具??行上?的工作,Ant ?面所使用的 FTP task 功能不??大,在初次上?的情??好,但是,在???程?中,常常需要不?的更新上?,Ant 的 FTP task 就容易因?目??限的??,?生?法?行的??。?了避免??困?,我?可以在????的主?中,安? Samba,然後,在你的 windows ?器上,建立??磁碟?,使用 Ant 的 copy task ,就可以解?????。



??工作:

在桌面上的?路上的芳?,按右滑鼠?,在??中?????路磁碟?。指定磁碟?的名?? F:,路???入\\主?名?或 IP\??,如:\\libdns.lib.ncyu.edu.tw\lib13。然後,?入??和密?。??,在你的?器上,就有一台?路磁碟?了。

撰? build.xml:

?入到你的 115 ?料?之?,使用 editplus,?生一? build.xml ?案。

?容如下:

<project name="115" default="upload"> <property name="dest_drive" value="F:\" /> <property name="dest_dir" value="${dest_drive}\public_html\115" />

<target name="create_dir">
<mkdir dir="${dest_dir}" />
</target>

<target name="upload" depends="create_dir">
<copy todir="${dest_dir}">
<fileset dir=".">
<exclude name="**\build.xml"/>
</fileset>
</copy>
</target>

</project>

?行 Ant 程式:

?入 DOS 命令列,cd 到 115?料?,然後,在命令提示下,打 ant 按 enter ?。

?例演?:使用 Ant 存取?料?

<project name="main" default="getdata"> <property name="host" value="libdns.lib.ncyu.edu.tw" /> <property name="database" value="lib13" /> <property name="userid" value="lib13" /> <property name="password" value="password" /> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://${host}/${database}" />

<target name="create_database">
<sql
driver="${driver}"
url="${url}"
userid="${userid}"
password="${password}"
src="lib13.sql"
encoding="iso-8859-1"
/>
</target>
<target name="getdata" depends="create_database">
<sql
driver="${driver}"
url="${url}"
userid="${userid}"
password="${password}"
showheaders="true"
print="true"
encoding="iso-8859-1">
select id, name from Guestbook
</sql>
</target>
</project>

ant 课程

java.sql.SQLException: Io 异常: The Network Adapter could not e

数据库 连接 驱动 出错


ant 的 部署 

File file = new File("dreamtree.cfg.xml");
// File file = new File(".");
System.out.println(file.getPath());
conf = new Configuration().configure(file);


获得的当前目录在 web_info\classes\ 目录下面

hiberate 数据库的基础配置

Fetch Size 是设定JDBC的Statement读取数据的时候每次从数据库中取出的记录条数。例如一次查询1万条记录,对于Oracle的JDBC驱动来说,是不会 1次性把1万条取出来的,而只会取出Fetch Size条数,当纪录集遍历完了这些记录以后,再去数据库取Fetch Size条数据。因此大大节省了无谓的内存消耗。当然Fetch Size设的越大,读数据库的次数越少,速度越快;Fetch Size越小,读数据库的次数越多,速度越慢。这有点像平时我们写程序写硬盘文件一样,设立一个Buffer,每次写入Buffer,等Buffer满了 以后,一次写入硬盘,道理相同。

Oracle数据库的JDBC驱动默认的Fetch Size=10,是一个非常保守的设定,根据我的测试,当Fetch Size=50的时候,性能会提升1倍之多,当Fetch Size=100,性能还能继续提升20%,Fetch Size继续增大,性能提升的就不显著了。因此我建议使用Oracle的一定要将Fetch Size设到50。

不过并不是所有的数据库都支持Fetch Size特性,例如MySQL就不支持。MySQL就像我上面说的那种最坏的情况,他总是一下就把1万条记录完全取出来,内存消耗会非常非常惊人!这个情况就没有什么好办法了 
hibernate 阅读资料
这里要注意的是,在sessionFactory.openSession()中,hibernate会初始化
数据库连接,与此同时,将其AutoCommit 设为关闭状态(false)。而其后,在
Session.beginTransaction 方法中,Hibernate 会再次确认Connection 的
AutoCommit 属性被设为关闭状态( 为了防止用户代码对session 的
Connection.AutoCommit属性进行修改)。
这也就是说,我们一开始从SessionFactory获得的session,其自动提交属性就
已经被关闭(AutoCommit=false),下面的代码将不会对数据库产生任何效果:
session = sessionFactory.openSession();
session.save(user);
session.close();
这实际上相当于 JDBC Connection的AutoCommit属性被设为false,执行了若
干JDBC操作之后,没有调用commit操作即将Connection关闭。
如果要使代码真正作用到数据库,我们必须显式的调用Transaction指令:
session = sessionFactory.openSession();
Transaction tx = session.beginTransaction();
session.save(user);
tx.commit();
session.close(); 

hibernate 并发控制的问题
在和数据库进行交互时,Hibernate把捕获的SQLException封装为Hibernate的 JDBCException。事实上,Hibernate尝试把异常转换为更有实际含义 的JDBCException异常的子类。底层的SQLException可以 通过JDBCException.getCause()来得到。Hibernate通过使用关联到 SessionFactory上的SQLExceptionConverter来 把SQLException转换为一个对应的JDBCException 异常的子类。默认情况下,SQLExceptionConverter可以通过配置dialect 选项指定;此外,也可以使用用户自定义的实现类(参考javadocs SQLExceptionConverterFactory类来了解详情)。标准的 JDBCException子类型是:

JDBCConnectionException - 指明底层的JDBC通讯出现错误

SQLGrammarException - 指明发送的SQL语句的语法或者格式错误

ConstraintViolationException - 指明某种类型的约束违例错误

LockAcquisitionException - 指明了在执行请求操作时,获取 所需的锁级别时出现的错误。

GenericJDBCException - 不属于任何其他种类的原生异常

你可能感兴趣的:(oracle,Hibernate,xml,ant,jdbc)