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强大的灵活性。

[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 课程

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 - 不属于任何其他种类的原生异常

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值