一、需求

如题,当建好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. background: inherit制作倒影、单行居中两行居左超过两行省略

    1.background: inherit;制作倒影 方法很多,但是我们当然要寻找最快最便捷的方法,至少得是无论图片怎么变化,div 大小怎么变化,我们都不用去改我们的代码. -webkit-box- ...

  2. 揭秘uc浏览器二

    这节,四个议题: ①一个网页显示在webview控件中 ②如何正常隐藏显示标题栏. ③如何用runnable来隐藏标题栏,这样子就更加的专业化. ④上节我们说道了QuickActionGrid,看他长 ...

  3. Laravel学习笔记之Session源码解析(中)

    说明:在上篇中学习了session的启动过程,主要分为两步,一是session的实例化,即\Illuminate\Session\Store的实例化:二是从session存储介质redis中读取id ...

  4. 最新自然语言处理(NLP)四步流程:Embed->Encode->Attend->Predict

    http://blog.csdn.net/jdbc/article/details/53292414 过去半年以来,自然语言处理领域进化出了一件神器.此神器乃是深度神经网络的一种新模式,该模式分为:e ...

  5. java根据图片路径下载到服务器方案 (转)

    http://www.cnblogs.com/thinkingandworkinghard/articles/5589484.html 平常做的工作中,有一部分是同步数据的.但是同步的过程中碰到个问题 ...

  6. 清空npm缓存

    nodejs 清空 npm 缓存 npm cache clean -f

  7. 启动项目时出现Not a JAR.......Find JAR........一指循环就是起不来

    出现问题原因就是mapper的映射文件有问题,里面的返回类型如是实体找不到或者找重复的就会这样 解决办法就是:确保在用的实体(路径)能找到,切记不能有重名的实体

  8. js undefined易错分析

    undefined 以下是错误写法: data = undefined; alert(undefined==false);//这样判断会输出false; if(data!=undefined || d ...

  9. Office办公 WPS如何设置页边距

    打开页眉页脚,在选项里面可以设置顶部的一行文字距离边界的距离   此外在页面布局,页边距也可以查看和修改                        

  10. 轻松python文本专题-字符与字符值转换

    场景: 将字符转换成ascii或者unicode编码 在转换过程中,注意使用ord和chr方法 >>> print(ord('a')) 97 >>> print(c ...