一个关于hibernate 4 的简单的、独立的、完整例子

1 引言

最近读了一些书1或网络上的讲解,发现关于hibernate使用方法的讲解要么结合Web MVC框架讲解,要么没把运行例子所需的jar包讲解清楚。为克服上述不足,本文拟解决如下问题:

  1. 一个独立简单完整的关于hibernate的例子包含哪些内容;
  2. 运行上述例子时,究竟至少需要哪些jar包。

一些例子所需环境如下:

名称版本
JDK1.8.0_281
MySQL8.0.13
hibernate4.3.6

以下例子因为简单,使用手工编译和运行,没用任何IDE或Maven工具。

2 关于hibernate的一个简单独立完整的例子

项目的文件夹结构如下:

├── classes/
│   ├── com/
│   │	├──rob/entity/User.hbm.xml
│   └── hibernate.cfg.xml
├── lib/
├── src/
│   ├── com/
│   │	├──完整源代码文件

在MySQL中的数据库testweb中创建表如下:

CREATE TABLE tuser (
  id int(11) NOT NULL AUTO_INCREMENT,
  user_name varchar(45) DEFAULT NULL,
  user_pwd varchar(45) DEFAULT NULL,
  real_name varchar(45) DEFAULT NULL,
  sex varchar(45) DEFAULT NULL,
  birthday DATE DEFAULT NULL,
  create_datetime TIMESTAMP,
  remark varchar(45) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

User.java的代码如下:

package com.rob.entity;
import java.io.Serializable;
import java.sql.Timestamp;
import java.util.Date;

public class User implements Serializable{
	private Integer id;
	private String userName;
	private String userPwd;
	private String realName;
	private String sex;
	private Date birthday;
	private Timestamp createdatetime;
	private String remark;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getUserName() {
		return userName;
	}
	public void setUserName(String userName) {
		this.userName = userName;
	}
	public String getUserPwd() {
		return userPwd;
	}
	public void setUserPwd(String userPwd) {
		this.userPwd = userPwd;
	}
	public String getRealName() {
		return realName;
	}
	public void setRealName(String realName) {
		this.realName = realName;
	}
	public String getSex() {
		return sex;
	}
	public void setSex(String sex) {
		this.sex = sex;
	}
	public Date getBirthday() {
		return birthday;
	}
	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}
	public Timestamp getCreatedatetime() {
		return createdatetime;
	}
	public void setCreatedatetime(Timestamp createdatetime) {
		this.createdatetime = createdatetime;
	}
	public String getRemark() {
		return remark;
	}
	public void setRemark(String remark) {
		this.remark = remark;
	}
	
	public User() {
		
	}
	public User(Integer id, String userName, String userPwd, String realName, String sex, Date birthday,
			Timestamp createdatetime, String remark) {
		super();
		this.id = id;
		this.userName = userName;
		this.userPwd = userPwd;
		this.realName = realName;
		this.sex = sex;
		this.birthday = birthday;
		this.createdatetime = createdatetime;
		this.remark = remark;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", userName=" + userName + ", userPwd=" + userPwd + ", realName=" + realName
				+ ", sex=" + sex + ", birthday=" + birthday + ", createdatetime=" + createdatetime + ", remark="
				+ remark + "]";
	}
	
}

编译User.java的命令为:javac -d classes src\com\rob\entity\User.java

User类的与数据库表的映射文件User.hbm.xml为:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC 
    "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
    "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
	<!-- 实体类映射文件 -->
	<hibernate-mapping>
		<!-- 
			name:实体类全路径名
			table:实体类对应的数据库表名称
		 -->
		<class name="com.rob.entity.User" table="tuser">
			<!-- 
				id:用于设置数据库表结构中主键列的生成方式
				name:实体类中属性名称
				type:Jave的数据类型
				column:数据库表字段名称
			 -->
			<id name="id" type="java.lang.Integer" column="id">
				<!-- 
					class:定义主键列生成的方式:hibernate管理、数据库管理、开发者管理
					increment,identity,sequcene,native,assgine
				 -->
				<generator class="increment"></generator>
			</id>
			<!-- 与实体类相匹配 -->
			<property name="userName" type="java.lang.String" column="user_name"/>
			<property name="userPwd" type="java.lang.String" column="user_pwd"/>
			<property name="realName" type="java.lang.String" column="real_name"/>
			<property name="sex" type="java.lang.String" column="sex"/>
			<property name="birthday" type="java.util.Date" column="birthday"/>
			<property name="createdatetime" insert="false" update="false" type="timestamp"  column="create_datetime"/>
			<property name="remark" type="java.lang.String" column="remark"/>
		</class>
	</hibernate-mapping>

上面映射文件中的元素property中的属性type必须给出相应的值,否则,运行后会报如下错误:

Exception in thread "main" org.hibernate.MappingException: Could not determine type for: , at table: tuser, for columns: [org.hibernate.mapping.Column(sex)]
        at org.hibernate.mapping.SimpleValue.getType(SimpleValue.java:336)
        at org.hibernate.mapping.SimpleValue.isValid(SimpleValue.java:310)
        at org.hibernate.mapping.Property.isValid(Property.java:241)
        at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:496)
        at org.hibernate.mapping.RootClass.validate(RootClass.java:270)
        at org.hibernate.cfg.Configuration.validate(Configuration.java:1358)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1849)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
        at com.rob.test.Demo.users(Demo.java:21)
        at com.rob.test.Demo.main(Demo.java:69)

Demo.java源文件的代码如下:

package com.rob.test;
import java.util.Date;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;

import com.rob.entity.User;

public class Demo {
	public void users() {
		//创建Hibernate核心类
		Configuration cfg=new Configuration();
		//读取核心配置文件
		cfg.configure("hibernate.cfg.xml");
        ServiceRegistry  sr = new StandardServiceRegistryBuilder().applySettings(cfg.getProperties()).build();  
		//创建session工厂
		SessionFactory sf = cfg.buildSessionFactory(sr);
		//获取session
		Session session = sf.openSession();
		
		//开启事务
		Transaction ts= session.beginTransaction();
		
		System.out.println("-------------增加-------------------");
		//新增
		User user=new User();
		user.setUserName("海王大大3");
		user.setUserPwd("6663");
		user.setRealName("丑");
		user.setSex("女");
		user.setBirthday(new Date());
		user.setRemark("你好");
		//新增操作
		session.save(user);
		
		System.out.println("-------------修改-------------------");
		//修改(根据id修改)
		/*user.setId(3);
		User user2 = session.get(User.class, user.getId());
		if(null!=user2) {
			user2.setUserName("二狗");
			session.update(user2);
		}	*/	
		
		System.out.println("-------------删除-------------------");
		//删除
		/*user.setId(1);
		User user2 = session.get(User.class, user.getId());
		if(null!=user2) {
			session.delete(user2);
		}*/
		System.out.println("-------------查询-------------------");
		List<User> lst = (List<User>)session.createQuery("from User").list();
		for (User usr : lst) {
			System.out.println(usr);
		}
		
		//提交事务
		ts.commit();
		//释放资源
		session.close();
        sf.close();
	}
	public static void main(String[] args) {
		Demo d=new Demo();
		d.users();
	}
}



编译Demo.java的命令为:javac -encoding utf-8 -classpath lib\hibernate-core-4.3.6.Final.jar;lib\mysql-connector-java-8.0.13.jar;classes;. -d classes src\com\rob\test\Demo.java

对上述两个源文件编译成功后,会在classes文件夹下生成相应的类文件。接下来,就具备运行该例子的条件了。

最后给出hibernate的整体配置文件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">
<hibernate-configuration>
	<session-factory>
		<!-- 数据库相关配置 -->
		<!-- connection.username|connection.password|connection.url|connection.driver_class|dialect -->
			<!-- 连接数据库账户名称 -->
			<property name="connection.username">root</property>
			<!-- 连接数据库密码(我的数据库没有登录密码,直接不用写) -->
			<property name="connection.password">123456</property>
			<!-- 连接的绝对路径(使用&需要解译&amp;) -->
			<property name="connection.url">
				jdbc:mysql://localhost:3306/testweb?useUnicode=true&amp;serverTimezone=Asia/Shanghai&amp;characterEncoding=UTF-8&amp;useSSL=false
			</property>
			<!-- 驱动的绝对路径 -->
			<property name="connection.driver_class">com.mysql.cj.jdbc.Driver</property>
			<!-- 数据库方言配置 -->
			<property name="dialect">
				org.hibernate.dialect.MySQLDialect
			</property>
			<!-- 配置本地事务 -->
			<property name="hibernate.current_session_context_class">thread</property>
		<!-- 调试相关配置 -->
		<!-- hibernate运行过程是否展示sql命令代码(自动生成) -->
			<property name="show_sql">true</property>
			<!-- 是否规范输出sql代码 -->
			<property name="format_sql">true</property>
		<!-- 实体映射相关配置 -->
		<mapping resource="com/rob/entity/User.hbm.xml"/>
	</session-factory>
</hibernate-configuration>

该例子以及完备了,只待运行了。

3 该例子所依赖的jar包

本小节给出本例子依赖的完整的jar包。这是方便学习的角度,实际开发中,将会使用Maven并配合IDE工具编译和运行。所依赖的完整的jar包如下图所示:
jar包
从上图可以看出,除了mysql-connector驱动外,其他的jar包都比较老。不过没关系,上述例子照样可以运行。感兴趣的读者,完全可以切换到新版本的jar包,没什么难度。至于我为什么用一些老版本的jar包,是因为手头上正好有这些jar包,同时因为我要对一个手头上的老项目抽丝剥茧的研究。

3.1 运行命令

java  -classpath lib\antlr-2.7.7.jar;lib\javassist-3.18.1-GA.jar;lib\hibernate-jpa-2.1-api-1.0.0.Final.jar;lib\jboss-transaction-api_1.2_spec-1.0.0.Final.jar;lib\jboss-logging-3.1.3.GA.jar;lib\hibernate-commons-annotations-4.0.5.Final.jar;lib\dom4j-1.6.1.jar;lib\hibernate-core-4.3.6.Final.jar;lib\mysql-connector-java-8.0.13.jar;classes;. com/rob/test/Demo

上面导入类路径时,可以用通配符*替代,从而简写上面命令。为了学习的目的,给出了完整的路径。

3.2 运行结果

在这里插入图片描述

3.3 按顺序给出缺少相关jar的运行报错

缺少dom4j-1.6.1.jar包时,会报错如下:

Exception in thread "main" java.lang.NoClassDefFoundError: org/dom4j/DocumentException
        at com.rob.test.Demo.users(Demo.java:17)
        at com.rob.test.Demo.main(Demo.java:69)
Caused by: java.lang.ClassNotFoundException: org.dom4j.DocumentException
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 2 more

缺少hibernate-commons-annotations-4.0.5.Final.jar包时,会报错如下:

Exception in thread "main" java.lang.NoClassDefFoundError: org/hibernate/annotations/common/reflection/MetadataProvider
        at com.rob.test.Demo.users(Demo.java:17)
        at com.rob.test.Demo.main(Demo.java:69)
Caused by: java.lang.ClassNotFoundException: org.hibernate.annotations.common.reflection.MetadataProvider
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 2 more

缺少jboss-logging-3.1.3.GA.jar包时,会报错如下:

Exception in thread "main" java.lang.NoClassDefFoundError: org/jboss/logging/BasicLogger
        at java.lang.ClassLoader.defineClass1(Native Method)
        at java.lang.ClassLoader.defineClass(Unknown Source)
        at java.security.SecureClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.defineClass(Unknown Source)
        at java.net.URLClassLoader.access$100(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.net.URLClassLoader$1.run(Unknown Source)
        at java.security.AccessController.doPrivileged(Native Method)
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:192)
        at com.rob.test.Demo.users(Demo.java:17)
        at com.rob.test.Demo.main(Demo.java:69)
Caused by: java.lang.ClassNotFoundException: org.jboss.logging.BasicLogger
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 15 more

缺少jboss-transaction-api_1.2_spec-1.0.0.Final.jar包时,会报错如下:

Exception in thread "main" java.lang.NoClassDefFoundError: javax/transaction/SystemException
        at java.lang.Class.forName0(Native Method)
        at java.lang.Class.forName(Unknown Source)
        at org.jboss.logging.Logger$1.run(Logger.java:2252)
        at java.security.AccessController.doPrivileged(Native Method)
        at org.jboss.logging.Logger.getMessageLogger(Logger.java:2227)
        at org.jboss.logging.Logger.getMessageLogger(Logger.java:2214)
        at org.hibernate.cfg.Configuration.<clinit>(Configuration.java:192)
        at com.rob.test.Demo.users(Demo.java:17)
        at com.rob.test.Demo.main(Demo.java:69)
Caused by: java.lang.ClassNotFoundException: javax.transaction.SystemException
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 9 more

缺少hibernate-jpa-2.1-api-1.0.0.Final.jar包时,会报错如下:

Exception in thread "main" java.lang.NoClassDefFoundError: javax/persistence/EntityListeners
        at org.hibernate.cfg.annotations.reflection.JPAMetadataProvider.getDefaults(JPAMetadataProvider.java:100)
        at org.hibernate.annotations.common.reflection.java.JavaReflectionManager.getDefaults(JavaReflectionManager.java:252)
        at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1386)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1844)
        at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:1928)
        at com.rob.test.Demo.users(Demo.java:21)
        at com.rob.test.Demo.main(Demo.java:69)
Caused by: java.lang.ClassNotFoundException: javax.persistence.EntityListeners
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 7 more

缺少antlr-2.7.7.jar包时,会报错如下:

Exception in thread "main" java.lang.NoClassDefFoundError: antlr/RecognitionException
        at org.hibernate.hql.internal.ast.ASTQueryTranslatorFactory.createQueryTranslator(ASTQueryTranslatorFactory.java:57)
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:124)
        at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:88)
        at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:167)
        at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:301)
        at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:236)
        at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1800)
        at com.rob.test.Demo.users(Demo.java:57)
        at com.rob.test.Demo.main(Demo.java:69)
Caused by: java.lang.ClassNotFoundException: antlr.RecognitionException
        at java.net.URLClassLoader.findClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
        at java.lang.ClassLoader.loadClass(Unknown Source)
        ... 9 more

上述讲解漏掉了一个javassist-3.18.1-GA.jar包的报错讲解,请读者补充。

4 总结

本文给出了一个独立的完整的简单的hibernate的例子,能帮助我们对hibernate框架更聚焦地学习;同时,也给出了所依赖的、完备的jar包,便于我们更深刻地理解。


  1. 李刚. Struts 2.x 权威指南. 第3版. 北京: 电子工业出版社, 2012.10: 29. ↩︎

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值