1. 下载安装JBossTools eclipse的插件
http://www.jboss.org/tools/download/ 也可以只安装
Update site (including sources) bundle of all Hibernate Tools
4.1.0.Final
78 MB
2013-07-22
update zip
Kepler版本 http://www.jboss.org/tools/download/stable/4_1.html
安装过程中eclipse要联网安装其他的东西,很慢。
2. 安装MariaDB
https://mariadb.org/ 下载速度比较慢,直接从国内的网站下载最新X64的 MariaDB 10.0.4 安装过程和MySQL一样,用户名和密码记住
https://downloads.mariadb.org/ 向下找
MariaDB Client Library for Java Applications 1.1 Series 目前版本为 MariaDB Client Library for Java Applications 1.1.5 Stable mariadb-java-client-1.1.5.tar.gz
下载MySQL的Java数据库连接jar包 http://dev.mysql.com/downloads/connector/j/#downloads 选择平台独立的版本即可Platform Independent (Architecture Independent)
3. 使用MariaDB自带的HeidiSQL新建数据库
-- 导出 gamestore 的数据库结构
DROP DATABASE IF EXISTS `gamestore`;
CREATE DATABASE IF NOT EXISTS `gamestore` /*!40100 DEFAULT CHARACTER SET utf8 */;
USE `gamestore`;
-- 导出 表 gamestore.company 结构
DROP TABLE IF EXISTS `company`;
CREATE TABLE IF NOT EXISTS `company` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COMMENT='game producer';
-- 正在导出表 gamestore.company 的数据:~4 rows (大约)
/*!40000 ALTER TABLE `company` DISABLE KEYS */;
INSERT INTO `company` (`id`, `name`) VALUES
(1, 'EA'),
(2, 'ActiveVision'),
(3, 'North RockStar'),
(4, 'TakeTwo');
/*!40000 ALTER TABLE `company` ENABLE KEYS */;
-- 导出 表 gamestore.game 结构
DROP TABLE IF EXISTS `game`;
CREATE TABLE IF NOT EXISTS `game` (
`id` int(10) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL,
`type` int(10) unsigned DEFAULT '0',
`company_id` int(10) unsigned DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `FK_game_company` (`company_id`),
CONSTRAINT `FK_game_company` FOREIGN KEY (`company_id`) REFERENCES `company` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8;
-- 正在导出表 gamestore.game 的数据:~4 rows (大约)
/*!40000 ALTER TABLE `game` DISABLE KEYS */;
INSERT INTO `game` (`id`, `name`, `type`, `company_id`) VALUES
(1, 'BattleField 4', NULL, 1),
(2, 'Call of Duty 10', NULL, 2),
(3, 'FIFA14', NULL, 1),
(4, 'GTA5', NULL, 3);
4. 新建Eclipse工程
在工程Java Build Path中加入Hibernate required的必备包,以及mariadb-java-client-1.1.5.jar和mysql-connector-java-5.1.26-bin.jar两个包
打开Eclipse的 DataSource Explorer视图, 新建一个Connection Profile, 选择MySQL类型,驱动选择MySQL的驱动,此时要找到工程中添加的mysql-connector-java-5.1.26-bin.jar 用来和数据库进行连接,
URL:jdbc:mysql://localhost:3306/gamestore
数据库:gamestore
5. 新建Hibernate配置文件
在src目录下,在新建向导的Hibernate目录下找到Hibernate Configuration File(cfg.xml),按照向导使用默认的名称即可,默认情况下Hibernate在初始化Configuration对象时,会在程序包所在的根目录下找名为Hibernate.cfg.xml文件作为配置文件,否则需要在configure()方法中设置配置文件。选择Get Values from Connection 后选择刚才新建的Connection Profile,此时会导入刚才的默认是指,不过是针对MySQL数据库的,之后在该配置基础上改为MariaDB的配置即可。需要注意插件自动生成的xml文件的DTD是否是正确的,建议从Hibernate官方例子中拷贝最新的模板进行修改。
<?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">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.driver_class">org.mariadb.jdbc.Driver</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.url">jdbc:mariadb://localhost:3306/gamestore</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.jdbc.batch_size">20</property>
<property name="show_sql">true</property>
<mapping resource="com/aquar/game/database/Game.hbm.xml"/>
<mapping resource="com/aquar/game/database/Company.hbm.xml"/>
</session-factory>
</hibernate-configuration>
6. 新建Hibernate Console Configuration
同创建配置文件一样,(可以在创建配置文件的最后一步,勾选创建Hibernate Console Configuration,就不用在进入新建文件向导了),当然选择Hibernate Core 4.0,Database connection 同样选择刚才的connection profile,设置Configuration file为刚才创建的hibernate.cfg.xml
7. 新建Hibernate Reverse Engineer File(reveng.xml)
选择刚才新建的Console Configuration 后,点击刷新就可以看到数据库和下面的表格,选择需要创建的POJO对象的表格finish。在eclipse中打开hibernante.reveng.xml文件后,有可视化编辑标签页。其中:
Type Mappings:用来将数据库数据类型和Hibernate的类型进行映射,例如可以把JDBC的INTEGER映射为Hibernate的integer。主键id最好映射为integer,这样java会生成Integer类型的id定义,通过判断id是否为null方便判断一个对象是否是数据库中获取的对象。
Table Filters:用来选择那些表格会映射
Table & Columns : 设置表格字段的映射规则
其实直接找一份模板,在源码的基础上修改更直接,使用可视化工具编辑主键和外键不够灵活。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-reverse-engineering PUBLIC "-//Hibernate/Hibernate Reverse Engineering DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-reverse-engineering-3.0.dtd" >
<hibernate-reverse-engineering>
<type-mapping>
<sql-type jdbc-type="INTEGER" hibernate-type="integer"
not-null="true">
</sql-type>
</type-mapping>
<table-filter match-name="company" match-catalog="gamestore"></table-filter>
<table-filter match-catalog="gamestore" match-name="game" />
<table catalog="gamestore" name="company">
<primary-key>
<generator class="increment"></generator>
<key-column name="id"></key-column>
</primary-key>
<column name="name"></column>
</table>
<table catalog="gamestore" name="game">
<primary-key>
<generator class="increment"></generator>
<key-column name="id"></key-column>
</primary-key>
<column name="name"></column>
<column name="type"></column>
<column name="company_id"></column>
</table>
</hibernate-reverse-engineering>
8. 生成POJO和Mappings
选择eclipse的window下Customize Perspective ,在Command Groups 中勾选Hibernate Code Generation。
打开Hibernate Code Generation Configurations,选择刚才创建的Console Configuration,输出目录为工程src目录,包目录为希望放置的java包目录,以及刚才的Hibernate.reveng.xml文件,执行run即可。这样会在指定的包目录下创建对应的JavaBean规范的类和hbm.xml文件。这些文件如果有不满足需要的可以手动修改。
package com.aquar.game.database;
// Generated Nov 3, 2013 7:49:14 PM by Hibernate Tools 4.0.0
import java.util.HashSet;
import java.util.Set;
/**
* Company generated by hbm2java
*/
public class Company implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1544255372285741722L;
private Integer id;
private String name;
private Set games = new HashSet(0);
public Company() {
}
public Company(Integer id, String name) {
this.id = id;
this.name = name;
}
public Company(Integer id, String name, Set games) {
this.id = id;
this.name = name;
this.games = games;
}
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public Set getGames() {
return this.games;
}
public void setGames(Set games) {
this.games = games;
}
}
对应的hmb.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping package="com.aquar.game.database">
<class name="Company" table="company" catalog="gamestore">
<id name="id" type="integer">
<column name="id" />
<generator class="increment"></generator>
</id>
<property name="name" type="string">
<column name="name" length="50" not-null="true" />
</property>
<set name="games" table="game" inverse="true" lazy="true" fetch="select">
<key>
<column name="company_id" not-null="true" />
</key>
<one-to-many class="Game" />
</set>
</class>
</hibernate-mapping>
简单测试
数据库操作Handler
package com.aquar.game.dataserver;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.LockOptions;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistryBuilder;
public class DataHandler {
private static DataHandler instance;
private SessionFactory sessionFactory;
private DataHandler() {
// TODO Auto-generated constructor stub
}
public static DataHandler getInstance() {
if (instance == null) {
instance = new DataHandler();
}
return instance;
}
public void init() {
// configures settings from hibernate.cfg.xml
Configuration cfg = new Configuration();
cfg.configure();
// A SessionFactory is set up once for an application
sessionFactory = cfg.buildSessionFactory(new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry());
}
public <T> boolean save(List<T> objs) {
boolean ret = false;
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
int count = 0;
for (T obj : objs) {
session.save(obj);
count++;
if (count == 20) { //20, same as the JDBC batch size
//flush a batch of inserts and release memory:
session.flush();
session.clear();
count = 0;
}
}
session.getTransaction().commit();
ret = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return ret;
}
@SuppressWarnings("unchecked")
public <T> List<T> query(T obj) {
List<T> result = null;
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
Criteria crit = session.createCriteria(obj.getClass());
result = crit.list();
session.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return result;
}
public <T> T load(T t) {
Session session = sessionFactory.openSession();
session.buildLockRequest(LockOptions.NONE).lock(t);
return t;
}
public <T> boolean delete(T obj) {
boolean ret = false;
Session session = sessionFactory.openSession();
try {
session.beginTransaction();
session.delete(obj);
session.getTransaction().commit();
ret = true;
} catch (Exception e) {
e.printStackTrace();
} finally {
session.close();
}
return ret;
}
public void release() {
if (sessionFactory != null) {
sessionFactory.close();
}
}
}
初始化注意要用
public void init() {
// configures settings from hibernate.cfg.xml
Configuration cfg = new Configuration();
cfg.configure(); //这个必须有,否则不会去获取cfg.xml中的属性配置,官方简单教程中的例子方法不能使用。
// A SessionFactory is set up once for an application
sessionFactory = cfg.buildSessionFactory(new ServiceRegistryBuilder().applySettings(cfg.getProperties()).buildServiceRegistry());
}
JUnit测试用例,需要依赖JUnit4
package com.aquar.game.test;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import com.aquar.game.database.Company;
import com.aquar.game.database.Game;
import com.aquar.game.dataserver.DataHandler;
public class DataHandlerTest extends TestCase {
@Before
public void setUp() throws Exception {
DataHandler.getInstance().init();
}
@After
public void tearDown() throws Exception {
DataHandler.getInstance().release();
}
@Test
public void testSave() {
boolean ret = false;
List<Game> games = new ArrayList<Game>();
String[] names = {"BattleField 4", "Call of Duty 10", "FIFA14", "GTA5"};
for (String name : names) {
Game game = new Game();
game.setName(name);
games.add(game);
}
ret = DataHandler.getInstance().save(games);
assertTrue(ret);
}
@Test
public void testQuery() {
List<Company> list = DataHandler.getInstance().query(new Company());
assertNotNull(list);
assertFalse(list.isEmpty());
assertTrue(true);
}
}
source code on github:GameStore