背景:本文所涉及的IDE如标题所示:IntelliJ IDEA. Java编译器史上最强大的IDE,对,你没有看错,没有之一。没试过的赶紧放下手中的Eclipse去尝试下他吧。我们常见的Android Studio就是基于他定制而来(他本身也可以开发Android)
一. 项目添加Hibernate框架
这里没什么好说的,对于新建项目时要勾选Hibernate框架。如果项目已经建好了就在项目上右击Add Framework.
算了,展开说下吧。也当是个笔记。
1.新建Hibernate项目
Paste_Image.png下面红框里的文件就是生成的Hibernate配置文件,后期很多配置都需要他。
Paste_Image.png
2.在现有项目上添加Hibernate框架
右击项目,点击 Add Framework Support
Paste_Image.png
看下图,记得勾选创建默认Hibernate 配置文件
Paste_Image.png
点击OK 下载Hibernate依赖库文件
Paste_Image.png下载依赖库时可能会失败,因为在天朝,原因你我懂的。嗯,相信你已经知道该怎么做了:给IDE设置proxy
下图是我的项目在下载依赖库时的网络流量情况,很显然需要爬城墙。
Paste_Image.png
二. 项目配置
你以为把Hibernate框架加入就可以用ORM了嘛。 年轻人,naive. 还要加入从maven中获取你所对应的数据库的依赖库,例如我这里的MySQL,那就需要依赖MySQL Connector.其他数据库类似
选中项目,点击菜单 File ~ Project Structure ~ Libraries ~
Paste_Image.png Paste_Image.png三.hibernate.cfg.xml 配置
默认生成的hibernate.cfg.xml 内容如下:
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.url"/>
<property name="connection.driver_class"/>
<property name="connection.username"/>
<property name="connection.password"/>
<!-- DB schema will be updated if needed -->
<!-- <property name="hbm2ddl.auto">update</property> -->
</session-factory>
</hibernate-configuration>
关于Hibernate的配置及其详尽用法,可以自行Google之。
下面介绍MySql常用的hibernate.cfg.xml配置
<?xml version='1.0' encoding='utf-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/workdiary?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.username">root</property>
<property name="connection.password">123456</property>
<!-- JDBC connection pool (use the built-in) -->
<property name="connection.pool_size">4</property>
<!-- SQL dialect -->
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- Enable Hibernate's automatic session context management -->
<property name="current_session_context_class">thread</property>
<!-- Disable the second-level cache -->
<property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>
<!--以格式良好的方式显示SQL语句-->
<property name="format_sql">true</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Drop and re-create the database schema on startup -->
<property name="hbm2ddl.auto">update</property>
<mapping class="com.threshold.hibernate.bean.DiaryEntity"/>
<mapping class="com.threshold.hibernate.bean.UserEntity"/>
<!-- <mapping resource="org/hibernate/tutorial/domain/Event.hbm.xml"/> -->
</session-factory>
</hibernate-configuration>
注意上面的
<mapping class="com.threshold.hibernate.bean.DiaryEntity"/>
<mapping class="com.threshold.hibernate.bean.UserEntity"/>
这个在你的项目中是需要删除的,不然会报错的(因为你数据库可能没有这两个表)。而且这个也是hibernate自动生成的。下一节我将介绍怎么自动生成。
还有一点需要注意:那就是每次自动生成实体类后,hibernate.cfg.xml中关于数据库连接那一块总是被替换重置,建议还是改回
<property name="connection.url"/>
<property name="connection.driver_class"/>
<property name="connection.username"/>
<property name="connection.password"/>
这种形式,否则你就会遇到 HHH-000319 HHH-000231 Could not get database metadata 等等奇奇怪怪的报错信息。
四. hibernate生成数据库实体类
重点来了,在这一节,我将介绍怎么使用hibernate生成实体类。
-
首先将上一节生成的Main.java 重命名一下。
Paste_Image.png、
将它命名成** HibernateSessionFactory**
其实这一步可做可不做,只是Main.java 我个人觉得不适合我的项目命名,而且这个Main.java的主要功能就是提供Hibernate的Session的。 -
建个entities包,存放数据库的实体类。
-
添加Database连接
在IDE右侧找到Database标签页。点开
Paste_Image.png
Paste_Image.png
Paste_Image.png
连接成功:
Paste_Image.png
点击OK即可。
现在我们到IDE左下角找到 Persistence 标签页,并点开它。
Paste_Image.png右击菜单:
Paste_Image.png
点击 Generate Persistence Mapping ~ By Database Schema.
Paste_Image.png然后我们再操作一次。注意图中的红框和字。
Paste_Image.png
生成成功
Paste_Image.png
记得把连接字符串改回来。
- 修改HibernateSessionFactory.java 类文件
public class HibernateSessionFactory {
private static final Logger logger = Logger.getLogger(HibernateSessionFactory.class.getName());
private static final SessionFactory ourSessionFactory;
private static final ServiceRegistry serviceRegistry;
static {
logger.setLevel(Level.ALL);
try {
Configuration configuration = new Configuration();
configuration.configure();
//一定要记得在这里把生成的实体类加入到Configuration里。否则调用的时候肯定报错。
//Hibernate 4.x版本的不需要。5.x才需要这样。而且5.x的hibernate必须要生成.hbm.xml文件,否则还是会报错。4.x只需要把生成的实体类在hibernate.cfg.xml中声明即可。
configuration.addClass(UserEntity.class)
.addClass(DiaryEntity.class);
serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
ourSessionFactory = configuration.buildSessionFactory(serviceRegistry);
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
}
public static Session getSession() throws HibernateException {
return ourSessionFactory.openSession();
}
public static void main(final String[] args) throws Exception {
final Session session = getSession();
try {
session.beginTransaction();
UserEntity entity = session.load(UserEntity.class, 1);
//只有在使用对象时,它才发出查询SQL语句,加载对象。
System.out.println("User.Password="+entity.getPassword());
logger.log(Level.FINEST, entity.getCellphone());
//因为此的user为persistent状态,所以数据库进行同步
entity.setIdentityCard("342401199209081211");
session.getTransaction().commit();
//下面的代码是IntelliJ IDEA自动生成的,适用于Hibernate4.x,5.x不再可用,执行会报错。
// System.out.println("querying all the managed entities...");
// Map<String, ClassMetadata> map = (Map<String, ClassMetadata>) ourSessionFactory.getAllClassMetadata();
// for(String entityName : map.keySet()){
// SessionFactoryImpl sfImpl = (SessionFactoryImpl) ourSessionFactory;
// String tableName = ((AbstractEntityPersister)sfImpl.getEntityPersister(entityName)).getTableName();
// System.out.println(entityName + "\t" + tableName);
// }
// final Map metadataMap = session.getSessionFactory().getAllClassMetadata();
// for (Object key : metadataMap.keySet()) {
// final ClassMetadata classMetadata = (ClassMetadata) metadataMap.get(key);
// final String entityName = classMetadata.getEntityName();
// final Query query = session.createQuery("from " + entityName);
// System.out.println("executing: " + query.getQueryString());
// for (Object o : query.list()) {
// System.out.println(" " + o);
// }
// }
} catch (Exception e) {
Transaction transaction = session.getTransaction();
if (transaction != null) {
transaction.rollback();
}
e.printStackTrace();
} finally {
if (session != null && session.isOpen()) {
session.close();
}
}
}
}
好了。配置完成了。
下一节将介绍Hibernate的简单使用方法。
四. Hibernate简单使用示例
Paste_Image.png泛泛而谈一点吧,以上图为例,dao 就是对数据库表操作的封装类的包。
先创建接口,再在dao.impl包中创建实现类。
就是这么简单。Easy.
还有个小坑在这里一笔带过一下吧:Hibernate在save(新增插入)数据时,如果这个Entity有自增长主键,那么请不要对这个新建的Entity的主键字段做任何更改,比如题主我就画蛇添足将Entity主键字段设成-1,心想数据库会自增长的嘛,但是Hibernate不这么想,你如果对主键字段设置了值,他就将这个值一并代入并插入数据库,而往往我们不需要这样。
还有对于更新数据,请先用Session从数据库将这个Entity查出来,再将更改的字段应用到这个查出来的Entity里,最后再调用Hibernate去update这个Entity.千万不要new Entity然后去更新,否则你没更新的字段都会被Hibernate置为null了,这显然和我们想要的不同。
有时间再开辟新的文章详细叙述吧。
五. 排错/debug
- NoSuchMethodError 错误。
例如
java.lang.NoSuchMethodError: org.jboss.logging.Logger.debugf(Ljava/lang/String;I)
你的项目是不是Jersey RESTful架构,是不是用的Glassfish服务器。
Glassfish 版本是不是4.1.1或者4.1.0 .
如果是,恭喜你中奖了。jboss-logging在Glassfish服务器的Modules里有jar包。但是跟你lib里的不一致。你需要将项目lib目录中jboss-logging.jar拷贝到Glassfish服务器目录中。
就是拷贝替换到这个目录中。
- Debug都能查询到数据,但是偏偏Jersey返回json格式数据时就报错。
还是Glassfish的问题,Glassfish4.1.1有个bug,在返回json数据的时候就报错了,返回TEXT_PLAIN和XML都是没问题的,这个bug官方已经知道了,会在下个版本修复,目前可以使用Glassfish4.1.0版本的。
关注我的公众号.jpg
网友评论