一、需求

如题,当建好Model 时,不想自己手工建表,可以采取hibernate进行自动建表。下面将用一个小例子来说明如何将其实现。

二、实现

说明:1)这里用的是4.3.1.Final版本的hibernate,mysql-connector-java用的是5.1.26版本的;

        2)这里要手工新那一个数据库ssh,建库语句为:

create database ssh;

1.新建maven项目

都填写好了,点击finish即可。

2.项目架构图

下面是maven默认的目录,如果没有main/java 和test/java那么自己手工建吧。

3.代码

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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.amos</groupId>
<artifactId>spring_mvc_hibernate</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>spring_mvc_hibernate Maven Webapp</name>
<url>http://maven.apache.org</url>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.1.Final</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.26</version>
</dependency>
</dependencies>
<build>
<finalName>spring_mvc_hibernate</finalName>
</build>
</project>

hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"> <hibernate-configuration>
<session-factory>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">root</property>
<property name="hibernate.connection.url">jdbc:mysql://127.0.0.1:3306/ssh?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;transformedBitIsBoolean=true
</property>
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="hibernate.cache.use_second_level_cache">false</property>
<mapping class="com.amos.model.Person" />
</session-factory>
</hibernate-configuration>

自动建表的关键是在<property name="hibernate.hbm2ddl.auto">update</property>,看hibernate的文档就发现还有其它几个选项:

 validate               加载hibernate时,验证创建数据库表结构
 create                  每次加载hibernate,重新创建数据库表结构,这就是导致数据库表数据丢失的原因。
 create-drop        加载hibernate时创建,退出是删除表结构
 update                 加载hibernate自动更新数据库结构,如果没有,那就新建数据结构。

model中的Person.java

package com.amos.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table; import org.hibernate.annotations.GenericGenerator;
@Entity
@Table(name
= "person2")
public class Person {
@Id
@GenericGenerator(name
= "generator", strategy = "increment")
@GeneratedValue(generator = "generator", strategy = GenerationType.TABLE)
@Column(unique = true, nullable = false)
private
Long id;
@Column(name = "name", length = 50)
private String name;
@Column
private Integer age; public Long getId() {
return id;
} public void setId(Long 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;
}
}

注:这里使用注解的方式,使用自增的方式,注意加粗的地方的配置。

PersonDao.java

package com.amos.dao;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration; import com.amos.model.Person; /**
* @ClassName: PersonDao
* @Description: 用户dao
* @author: amosli
* @email:amosli@infomorrow.com
* @date 2014年2月28日 下午6:01:19
*/
public class PersonDao {
private static SessionFactory sessionFactory = null; public static void main(String[] args) {
// SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
createSessionFactory();
Session session = sessionFactory.openSession();
session.beginTransaction();
Person person = new Person();
person.setAge(18);
person.setName("amos");
session.save(person);
session.getTransaction().commit();
session.close();
System.exit(0);
} public static SessionFactory createSessionFactory() {
Configuration cfg = new Configuration().configure();
System.out.println("cfg.getProperties():" + cfg.getProperties());
StandardServiceRegistry build = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();
sessionFactory = cfg.buildSessionFactory(build);
return
sessionFactory;
}

}

注: 加粗的部分是重点,这里建议用未过时的就是新建一个ServiceRegistry。

用 new Configuration().configure().buildSessionFactory()会提示:Deprecated. Use buildSessionFactory(ServiceRegistry) instead

看源码,就会发现Configuration类中的buildSessionFactory()用的就是

final ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings( properties )
.build();

这里模仿其用法,也用StandardServiceRegistryBuilder实现ServiceRegistry,经测试是没问题的。

另,如果hibernate.cfg.xml自己更改为hibernate_test.xml那么应改怎么办?

只需要在new Configuration().configure("hibernate_test.xml")即可,这样可以指定其去加载classpath下的.xml文件。

4.效果

5.遇到的问题

Exception in thread "main" org.hibernate.AnnotationException: No identifier specified for entity: com.amos.model.Person
at org.hibernate.cfg.InheritanceState.determineDefaultAccessType(InheritanceState.java:277)
at org.hibernate.cfg.InheritanceState.getElementsToProcess(InheritanceState.java:224)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:775)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:3790)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3744)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1410)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
at com.amos.dao.PersonDao.main(PersonDao.java:11)

出现个主要是因为在建model 时没有定义id为其主键,所以报错了,在其前面加上@Id即可。

6.补充

下面是:hibernate.cfg.xml一些可参考的配置,主要将部分配置外包化,这样考虑主要是项目有可能在测试环境测一段时间然后才部署到生产环境上去。

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<!-- Generated by MyEclipse Hibernate Tools. -->
<hibernate-configuration> <session-factory>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">${hibernate.credit.url}</property>
<property name="connection.username">${hibernate.credit.username}</property>
<property name="connection.password">${hibernate.credit.password}</property>
<!--数据库连接池的大小 20 -->
<!-- <property name="hibernate.connection.pool.size">1 </property> -->
<property name="connection.provider_class">org.hibernate.service.jdbc.connections.internal.C3P0ConnectionProvider</property>
<!-- 最大连接数 -->
<property name="hibernate.c3p0.max_size">50</property>
<!-- 最小连接数 -->
<property name="hibernate.c3p0.min_size">${hibernate.credit.min_size}</property>
<!-- 获得连接的超时时间,如果超过这个时间,会抛出异常,单位毫秒 -->
<property name="hibernate.c3p0.timeout">9000</property>
<!-- 最多高速缓存 20 个预编译语句 不为0会报APPARENT DEADLOCK!!!死锁警告 -->
<property name="hibernate.c3p0.max_statements">0</property>
<!-- 当连接池里面的连接用完的时候,C3P0一下获取的新的连接数 -->
<property name="hibernate.c3p0.acquire_increment">2</property>
<!-- 每隔600秒检查连接池里的空闲连接 ,单位是秒 -->
<property name="hibernate.c3p0.idle_test_period">180</property> <property name="hibernate.c3p0.automaticTestTable">Test</property> <!-- 在checkout一个connection时候,判断这个connection没有被使用的时间是否大于maxIdleTime,来决定是关闭它,还是被checkout -->
<!-- <property name="maxIdleTime">1800</property> --> <!--定义在从数据库获取新连接失败后重复尝试的次数。Default: 30 -->
<property name="acquireRetryAttempts">30</property>
<!--两次连接中间隔时间,单位毫秒。Default: 1000 -->
<property name="acquireRetryDelay">1000</property>
<!--连接关闭时默认将所有未提交的操作回滚。Default: false -->
<property name="autoCommitOnClose">true</property> <!-- -jdbc.fetch_size是指Hibernate每次从数据库中取出并放到JDBC的Statement中的记录条数.Fetch
Size设的越大,读数据库的次数越少,速度越快, -->
<!-- Fetch Size越小,读数据库的次数越多,速度越慢 -->
<property name="jdbc.fetch_size">30 </property>
<!--jdbc.batch_size是指Hibernate批量插入,删除和更新时每次操作的记录数。Batch Size越大,批量操作的向数据库发送Sql的次数越少,速度就越快,同样耗用内存就越大 -->
<property name="jdbc.batch_size">30 </property>
<!--jdbc.use_scrollable_resultset是否允许Hibernate用JDBC的可滚动的结果集。对分页的结果集。对分页时的设置非常有帮助 -->
<property name="jdbc.use_scrollable_resultset">true </property>
<!--connection.useUnicode连接数据库时是否使用Unicode编码 -->
<property name="Connection.useUnicode">true </property>
<!--connection.characterEncoding连接数据库时数据的传输字符集编码方式,最好设置为gbk,utf-8,用gb2312有的字符不全 -->
<property name="connection.characterEncoding">utf-8 </property>
<!-- 执行事务的方式 -->
<property name="current_session_context_class">thread</property>
<!-- <property name="current_session_context_class">jta</property> -->
<!-- 事物隔离-防止查询出现缓存 Read Committed(读取提交内容) 1,2,4,8 -->
<property name="hibernate.connection.isolation">2</property>
<!-- 是否更新表 TODO 需要关闭! update false -->
<property name="hibernate.hbm2ddl.auto">update</property>
<property name="show_sql">false</property>
<property name="format_sql">false</property>
<mapping class="com.amos.model.Person" />
</session-factory>
</hibernate-configuration>

test.properties

hibernate.credit.url=jdbc:mysql://127.0.0.1:3306/juxinli_credit?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;transformedBitIsBoolean=true
hibernate.credit.username=root
hibernate.credit.password=root
hibernate.credit.min_size=5

在pom.xml 中 </dependencies>之后,</project>加上如下配置:

</dependencies>

   <build>
<finalName>hibernate</finalName>
<defaultGoal>compile</defaultGoal>
<plugins>
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.1</version>
<configuration>
<source>1.7</source>
<target>1.7</target>
<encoding>UTF-8</encoding>
<compilerArguments>
<extdirs>src/main/webapp/WEB-INF/lib</extdirs>
</compilerArguments>
</configuration>
</plugin>
</plugins>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources> </build> <profiles>
<profile>
<id>development</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<build>
<filters>
<filter>src/main/resources/environment/test.properties</filter>
</filters>
</build>
</profile>
<profile>
<id>production</id>
<build>
<filters>
<filter>src/main/resources/environment/production.properties</filter>
</filters>
</build>
</profile>
</profiles></project>

在使用maven打war包时:

1)可以手动运行命令:

mvn package -Ptest 

这样表示的是打id为test的war包。

2)也可以采用:项目名称,鼠标右键Run As--> Maven install 进行打包。

 7.本文源码

https://github.com/amosli/hibernate_auto_create_table

Hibernate+maven+eclipse 实现自动建表的更多相关文章

  1. 配置hibernate根据实体类自动建表功能

    Hibernate支持自动建表,在开发阶段很方便,可以保证hbm与数据库表结构的自动同步. 如何使用呢?很简单,只要在hibernate.cfg.xml里加上如下代码 Xml代码<propert ...

  2. 【原创】Hibernate通过实体类自动建表时type=MyISAM的问题

    ι 版权声明:本文为博主原创文章,未经博主允许不得转载. 当使用的mysql数据库为5.5版本时,方言需要设置为 <property name="hibernate.dialect&q ...

  3. 关于Hibernate 连接mysql不能自动建表的问题

    最近看旧书,李刚那本<轻量级J2EE>在讲解hibernate的时候遇到一个问题,就是与mysql连接后,明明配置了自动建表,却老是建不了表,上网查了发现是方言的原因,到底什么是方言?这里 ...

  4. 【SSH】——Hibernate实现简单的自动建表

    [与ORM] Object Relational Mapping,对象关系映射,将对象和关系联系了起来.面向对象是从耦合.聚合.封装等的基础上发展起来的,而关系数据库则是从数学理论发展而来的,两套理论 ...

  5. spring和hibernate整合时无法自动建表

    在使用spring整合hibernate时候代码如下: <property name="dataSource" ref="dataSource" /> ...

  6. hibernate连接mysql,自动建表失败

    hibernate的列名使用了mysql的关键字.

  7. Springboot 之 Hibernate自动建表(Mysql)

    Springboot 之 Hibernate自动建表(Mysql) 2016年10月21日 10:39:44 阅读数:8180 本文章来自[知识林] 引入Maven依赖包 <dependency ...

  8. Hibernate不能自动建表解决办法

    最近开始学Hibernate,看的是李刚的那本<轻量级java ee企业应用实战>.头一个hibernate程序,我原原本本的按照书上例子写下来,同时只是改动了些mysql的连接参数,并且 ...

  9. [转]Hibernate不能自动建表解决办法及Hibernate不同数据库的连接及SQL方言

    最近开始学Hibernate,看的是李刚的那本<轻量级java ee企业应用实战>.头一个hibernate程序,我原原本本的按照书上例子写下来,同时只是改动了些mysql的连接参数,并且 ...

随机推荐

  1. 以快板之名说Android 应用程序电源管理

    当里个当,当里个当.Android开发UE(用户体验)为导向,首要任务便是省电量. 当里个当,当里个当.有一设备立足于墙边,这个设备唤固定电话.你的app造成这样,用户很快把你弃墙角.你咆哮耗电奈何与 ...

  2. bp算法中为什么会产生梯度消失?

    作者:维吉特伯链接:https://www.zhihu.com/question/49812013/answer/148825073来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请 ...

  3. unity3d Player Settings 中的Stripping Level(剥离等级)对应每个等级具体剥离了哪些库

    http://docs.unity3d.com/410/Documentation/ScriptReference/MonoCompatibility.html

  4. Javascript常用语法 (一)

    判断成员是否是一个函数: if (typeof options.sourceMapName === 'function') { mapNameGenerator = options.sourceMap ...

  5. [Functional Programming] Using Last monoid with Maybe

    Imaging we have a deck of cards, eveytimes we need to pick one card from deck, the result we want to ...

  6. OpenGL ES3.0

    到今天,喜欢上了非常酷的图片处理和游戏,经了解,大部分都要使用opengl es,所以准备开始学习,然后深入学习cocos2d,GPUImage.平台为IOS OpenGL ES OpenGL ES ...

  7. Try Before Choosing

     Try Before Choosing Erik Doernenburg CREATing An AppliCATion REquiRES MAKing MAny dECiSionS. Some ...

  8. Android 获得图片并解码成缩略图以减少内存消耗

    本文内容 环境 演示 下载 Demo 环境 Windows 2008 R2 64 位 Eclipse ADT V22.6.2,Android 4.4.3 SAMSUNG GT-I9008L,Andro ...

  9. python 读取单所有json数据写入mongodb(单个)

    <--------------主函数-------------------> from pymongo import MongoClientfrom bson.objectid impor ...

  10. 批量删除SQL数据库中的所有表【笔记】

    use OTRJiraDB GO ) begin SELECT @sql='drop table ' + name FROM sysobjects WHERE (type = 'U') ORDER B ...