Hibernate,对于java来说很重要的一个东西,用于持久层。之前看了很多配置的,都不行,自己来写一个配置成功的。

  环境:jdk1.8,eclipse-jee-oxygen,mysql-connector-java-5.1.46,hibernate 5.2.

  首先要确保你的jdk,eclipse和mysql装好。然后下载jar包,mysql和hibernate的jar包。

  然后安装JBoss插件,eclipse中Help-----eclipse market里面输入JBoss并搜索,找到JBoss之后,install,这里只需要对应hibernate的那些即可。

  

  

  Confirm之后,accept,安装即可。

  先简单叙述一下开发流程,后面有详细地说明每一步在干什么以及为什么要这么做。

  1.准备开发环境,数据库中创建数据库及表。

  2.创建持久化类

  3.设计映射文件,也就是利用hibernate讲POJO映射到数据库。

  4.创建hibernate配置文件Hibernate.cfg.xml。

  5.编写辅助工具HibernateUtil类,用来实现对Hibernate的初始化并提供获得Session的方法,这一步是我们这次需要的,具体要看你的项目是否需要。

  6.编写DAO层。

  7.编写Service层。

  8.编写测试类,并用Junit测试。

  先上一张完整的目录:

  

  1.创建项目

创建Dynamic Web Project项目,命名为MyHibernate,在项目上右键,New---Other,在里面找Hibernate,选择Hibernate Configuration File(cfg.xml)。

  

点击Next按钮,在弹出的对话框中选择配置文件保存的目录,一般默认在src目录,同时需要输入配置文件的名称,一般默认为hibernate.cfg.xml即可。继续Next,在弹出的对话框中填写数据库方言(Database dialect)、数据库驱动(Driver class)、数据库URL、用户名、密码等。MySQL数据库的配置如下:

单击Finish,配置文件就创建成功了,后面有需要可以继续编辑该文件。

  2.创建数据库及表。

  在MySQL中创建一个名为mysqldb的数据库,在该数据库中创建一张名为USER的表。创建USER表的语句如下:

create table user(
id int(11),
name varchar(20),
password varchar(12),
type varchar(6),
primary key(id));

  3.编写POJO映射类User.java

  

package org.hibernate.entity;  

public class User {  

    private int id;//持久化类的标识属性,映射到数据表中的主键列
private String name;
private String password;
private String type;
public User() {
// TODO Auto-generated constructor stub
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
} }

  4.编写映射文件User.hbm.xml

  这一步可以通过设置直接生成。右键org.hibernate.entity包,new----other,找到hibernate,选择生成hbm.xml。这里只选择自己需要的POJO类生成hbm.xml。

生成之后的内容:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2018-3-16 9:16:18 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="org.hibernate.entity.User" table="USER">
<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="password" type="java.lang.String">
<column name="PASSWORD" />
</property>
<property name="type" type="java.lang.String">
<column name="TYPE" />
</property>
</class>
</hibernate-mapping>

5.编写hibernate.cfg.xml文件

  刚才新建了一个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>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.password">314159</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost:3306/mysqldb</property>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property> <property name="hibernate.hbm2ddl.auto">update</property>
<!-- 在控制台输出运行时生成的SQL语句,方便调试 -->
<property name="show_sql">true</property>
<!-- 连接池大小 -->
<property name="connection.pool_size">1</property>
<!-- 列出所有映射文件 -->
<mapping resource="org/hibernate/entity/User.hbm.xml" />
</session-factory>
</hibernate-configuration>

6.编写辅助工具类HibernateUtil.java

package org.hibernate.entity;

import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry; public class HibernateUtil { private static SessionFactory sessionFactory;
// 创建线程局部变量threadLocal,用来保存Hibernate的Session
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
// 使用静态代码块初始化Hibernate
static {
try {
// 读取配置文件方式1,hibernate4.3之前
// Configuration cfg = new Configuration().configure();
// // 创建服务注册对象
// StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
// .applySettings(cfg.getProperties()).build();
// // 创建会话工厂对象SessionFactory
// sessionFactory = cfg.buildSessionFactory(serviceRegistry);
//
// 读取配置文件方式2,hibernate4.3之后
ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().configure("/hibernate.cfg.xml").build();
//创建会话工厂对象
sessionFactory = new MetadataSources(serviceRegistry).buildMetadata().buildSessionFactory();
} catch (Throwable ex) {
throw new ExceptionInInitializerError(ex);
}
} // 获得SessionFactory的实例
public static SessionFactory getsSessionFactory() {
return sessionFactory;
} // 获得ThreadLocal对象管理的Session
public static Session getsSession() throws HibernateException {
Session session = (Session) threadLocal.get();
if (session == null || !session.isOpen()) {
if (sessionFactory == null) {
rebuildSessionFactory();
}
// 通过SessionFactory对象创建Session对象
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
// 将Session对象保存到线程局部变量threadLocal中
threadLocal.set(session);
}
return session;
} // 关闭Session实例
public static void closeSession() {
// 从线程局部变量threadLocal中获取之前存入的Session实例
Session session = (Session) threadLocal.get();
threadLocal.set(null);
if (session != null) {
session.close();
}
} // 重建SessionFactory
public static void rebuildSessionFactory() {
Configuration configuration = new Configuration();
configuration.configure("/hibernate.cfg.xml");
StandardServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder()
.applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
} // 关闭缓存和连接池
public static void shutdown() {
getsSessionFactory().close();
}
}

这里面有一个地方要注意,就是上面的红色注释,创建SessionFactory的方式因为hibernate版本有点不一样,如果选择了不适合的版本,在后面Junit测试的时候,会报“org.hibernate.MappingException: Unknown entity:XXXXXXXXXXXXXXX"的错。

7.编写DAO层接口UserDAO.java

package org.hibernate.dao;

import java.util.List;

import org.hibernate.entity.User;

public interface UserDAO {

    public void save(User user);

    public User findByIdGet(int id);

    public User findByIdLoad(int id);

    public List<User>  findByHQL(String hql);

    public void delete(User user);

    public void update(User user);
}

8.编写DAO层实现类UserDAOImpl

package org.hibernate.dao;

import java.util.ArrayList;
import java.util.List; import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.entity.HibernateUtil;
import org.hibernate.entity.User; public class UserDAOImpl implements UserDAO { // 添加用户,需要事务管理
@Override
public void save(User user) {
// 创建Session实例
Session session = HibernateUtil.getsSession();
// 创建Transaction实例
Transaction tx = session.beginTransaction(); try {
// 使用Session的save方法将持久化对象保存到数据库
session.save(user);
// 提交事务
tx.commit();
} catch (Exception e) {
e.printStackTrace();
// 出现异常,回滚事务
tx.rollback();
} finally {
// 关闭Session连接
HibernateUtil.closeSession();
} } // 根据id查找用户 ,可以不需要事务管理 Get方式
@Override
public User findByIdGet(int id) {
User user = null;
Session session = HibernateUtil.getsSession();
// 使用session的get方法获取指定id的用户
user = (User) session.get(User.class, id);
if (user == null || "".equals(user)) {
System.out.println("查询id为:" + id + "无结果....");
}
session.close();
return user;
} // 根据id查找用户 ,可以不需要事务管理 Load方式
@Override
public User findByIdLoad(int id) {
User user = null;
Session session = HibernateUtil.getsSession();
// 使用session的方法获取指定id的用户
user = (User) session.load(User.class, id);
if (user == null || "".equals(user)) {
System.out.println("查询id为:" + id + "无结果....");
}
session.close();
return user;
} // 根据HQl语句查询
@Override
public List<User> findByHQL(String hql) {
List<User> list = new ArrayList<>();
Session session = HibernateUtil.getsSession();
list = session.createQuery(hql).list();
session.close();
return list;
} // 删除用户 ,需要事务管理
@Override
public void delete(User user) {
Session session = HibernateUtil.getsSession();
Transaction tx = session.beginTransaction();
try {
session.delete(user);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
} // 修改用户
@Override
public void update(User user) {
Session session = HibernateUtil.getsSession();
Transaction tx = session.beginTransaction();
try {
session.update(user);
tx.commit();
} catch (Exception e) {
e.printStackTrace();
tx.rollback();
} finally {
HibernateUtil.closeSession();
}
}
}

到这里整个Hibernate项目就完成了,下面需要的是测试。

9.编写测试类UserTest.java

这里用Junit测试,如果没有导入Junit的要先导入。在HibernateDemo项目名称上右击,选择Properties,在弹出的窗口左侧选择Java Build Path选项,然后在右侧界面中选择Libraries标签,点击Add Library按钮,在弹出的窗口中选择Junit,如下图所示。

然后点击Next,在version一栏选择Junit 4,然后点击Finish。这样Junit包就引入到项目中了。

接下来在项目中新建org.hibernate.test包,在包名上右击,依次选择New->Junit Test Case菜单,在弹出的窗口中填写测试类的名称和需要测试的类的名称(这个需要填写完整包名),如下图所示:

点击Next按钮,可以选择需要测试的方法,根据需要选择即可。

这时候会生成一个UserTest类,里面包含的是一些空方法,我们要测哪些就给哪些加上方法体。

例如重写testSave,下面是重写之后的类:

package org.hibernate.test;

import static org.junit.Assert.*;

import org.hibernate.dao.UserDAO;
import org.hibernate.dao.UserDAOImpl;
import org.hibernate.entity.User;
import org.junit.Test; public class UserTest { @Test
public void testSave() {
UserDAO userDAO=new UserDAOImpl();
try{
User u=new User();
// 设置User对象的各个属性
u.setId(20);
u.setName("zhangsan");
u.setPassword("123456");
u.setType("admin");
// 使用UserDAOImpl的save方法将User对象存入到数据库
userDAO.save(u);
}catch(Exception e){
e.printStackTrace();
}
} @Test
public void testFindByIdGet() {
fail("Not yet implemented");
} @Test
public void testFindByIdLoad() {
fail("Not yet implemented");
} @Test
public void testFindByHQL() {
fail("Not yet implemented");
} @Test
public void testDelete() {
fail("Not yet implemented");
} @Test
public void testUpdate() {
fail("Not yet implemented");
} }

接下来在UserTest.java文件名称上右击,依次选择Run As ->Junit Test菜单。再查看数据库中就会发现多了一条记录。

这里可能有报错,像上面说的

1.“org.hibernate.MappingException: Unknown entity:XXXXXXXXXXXXXXX”这个是因为SessionFactory获取的方式不对,因为hibernate的版本问题,根据上面对应的红色注释改一下就好了。

2.ERROR: Field 'id' doesn't have a default value。这个是因为字段的问题,自动生成的User.hbm.xml可能不太一样。

<id name="id" type="int">
<column name="ID" />
<generator class="assigned" />
</id>

这里的generator对应的是数据库中的id字段是否自动增长,assigned就是我写进去20就是20,如果有的自动生成了native,表示的是从1开始自增,如果数据库中没有相应的设定的话可能会报错,所以这里注意一下。

参照原文地址:http://blog.csdn.net/fxdaniel/article/details/42420779

到这里整个项目的创建到测试都完成了,现在来说一下我对每个步骤在干什么和为什么要这么做的理解。

1.创建项目。这里由于使用了JBoss,所以简化了很多。hibernate.cfg.xml是hibernate中非常重要的一个xml文件,里面是一些hibernate的配置,其中session-factory最重要。试想一下我们以前用JDBC连接数据库时候的操作,加载驱动、url、用户名、密码等等,这里也是一样,你既然要操作数据库,最根本的就是连接数据库,所以hibernate的根就是在这个xml中,这里面让jvm知道用的驱动、url、用户名、密码、以及数据库方言(也就是数据库种类mysql啊还是oracle还是sqlserver啊)。hibernate简化了jdbc中一系列操作,直接通过xml配置文件来配置这些信息。

2.编写POJO类(持久化类)。首先要明确hibernate是服务于持久层,什么是持久层,持久层就是存储数据的,在一个项目中,数据要持久地保存。操作数据库实际上是在操作我们面向的对象也就是POJO类,比如我们有一堆桌子,面向对象设计这个桌子,桌子的重量啊,形状啊等信息会被看作是桌子的属性,而数据库里存的也是这些东西。

3.生成映射文件User.hbm.xml。数据库和我们的类(也就是POJO类)是对应的,但是即使我们知道对应,jvm不知道啊,怎么让他知道,用mapping来匹配。一个POJO类对应一个table,既然对应了,那POJO里面的属性和table的字段肯定也是要对应的,因为属性和字段表示的都是桌子的实际性质。所以映射文件的配置,就是让jvm知道那个POJO类对应哪个table。所以看看这个xml里面的配置,是不是和数据库中的字段配置很相似。

4.编写hibernate.cfg.xml文件。一开始生成了一个xml文件,但是这个xml只是在有数据库的时候生成的,但是我们要具体操作哪一个表的时候,xml就不知道了。现在我们的目的是添加一个user进入,那也就是说我们要操作user类,user类对应数据库里的user表,但是jvm现在只知道要操作mysql数据库,而上一步里面,我们让jvm知道了user类和user表是对应的,可是user表在哪个数据库里面存着呢?mysql还是oracle?mysql下的db还是oracle下的db?很自然的,现在只需要让jvm把mysql数据库和mapping对应起来,而这个mapping就是user类和user表的映射。现在整个逻辑通了,操作user类---映射到mysql数据库--映射到user表。

5.编写辅助工具类。刚才我们说的那些东西,都是保存在hibernate.cfg.xml下面,而那下面的标签是<session-factory>,这个SessionFactory是很重要也很重的一个东西,既然刚才说的东西都保存在这里面,我们用的时候肯定也都是从这里面取,所以这个辅助工具类的就是为了取处这个SessionFactory。

6.编写DAO层接口。在三层视图层、业务层、持久层的逻辑中,DAO也就是database access object,直接面向数据库。成熟的编程方式是先写接口,再写实现类。所以DAO层接口和实现分开。

7.DAO层实现类。这个就是利用取出的SessionFactory,再取出SessionFactory中我们需要的元素,操作这些元素也就是直接面向了数据库,通过这个实现类来完成我们的目的。

8.一个Junit测试类。没啥说的,测试项目。

希望通过这个配置来理解简单的hibernate原理。

Hibernate——配置并访问数据库的更多相关文章

  1. 十八、springboot中hibernate配置sessionFactory访问数据库

    前提 在yml或properties文件中配置数据库与数据库连接池 Hibernate配置 几种方式: 方式一: @Configuration public class HibernateConfig ...

  2. 06-编写Hibernate API编写访问数据库的代码,使用Junit进行测试

    用到的注解: @Test:测试方法 @Before:初始化方法. @After:是否资源. 先执行Befere,然后执行Test,最后执行After. 第一步:新建一个Junit目录. 第二步:取名 ...

  3. Hibernate初探之单表映射——通过Hibernate API编写访问数据库的代码

    编写一个Hibernate例子 第五步:通过Hibernate API编写访问数据库的代码 初始化方法要实现以下功能:

  4. 通过Hibernate API编写访问数据库的代码

    private Configuration config;// 1.声明私有配置对象类private ServiceRegistry serviceRegistry;// 2.声明私有服务注册对象类p ...

  5. [原创]java WEB学习笔记78:Hibernate学习之路---session概述,session缓存(hibernate 一级缓存),数据库的隔离级别,在 MySql 中设置隔离级别,在 Hibernate 中设置隔离级别

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. SSH hibernate 使用时最好添加访问数据库的编码

    SSH hibernate 使用时最好添加访问数据库的编码 如下所示:第13行为设置hibernate访问数据库的编码(&是&的转义序列) <!DOCTYPE hibernate ...

  7. 【JAVA - SSM】之MyBatis与原生JDBC、Hibernate访问数据库的比较

    首先来看一下原生JDBC访问数据库的代码: public static void main(String[] args) { // 数据库连接 Connection connection = null ...

  8. Sybase数据库的连接,JNDI配置,Hibernate配置

    最近的一个项目就是移植老项目的代码,有一个模块用的是Sybase数据库,我表示从来没接触过,更不用说怎么用了.再者这东西都是几乎被淘汰的东西了,而且网上搜到的东西简直了,全是复制粘贴的. 一.使用工具 ...

  9. 【JavaEE】之MyBatis与原生JDBC、Hibernate访问数据库的比较

    首先来看一下原生JDBC访问数据库的代码: public static void main(String[] args) { // 数据库连接 Connection connection = null ...

随机推荐

  1. 芝麻HTTP: Learning to Rank概述

    Learning to Rank,即排序学习,简称为 L2R,它是构建排序模型的机器学习方法,在信息检索.自然语言处理.数据挖掘等场景中具有重要的作用.其达到的效果是:给定一组文档,对任意查询请求给出 ...

  2. google浏览器插件推荐

    http://www.tuicool.com/articles/eQ32Ur http://blog.jobbole.com/1386/ https://www.oschina.net/news/46 ...

  3. 异常-----freemarker.core.ParseException: Encountered

    1.错误描述 freemarker.core.ParseException: Encountered " " at line 14, column 12 in myself.ftl ...

  4. Web开发工具——Jupyter notebook

    jupyter-notebook 安装及远程访问 Introduction Jupyter Notebook(此前被称为 IPython notebook)是一个交互式笔记本,支持运行 40 多种编程 ...

  5. [SDOI2015]约数个数和

    Sol 首先有个结论 \(\sum_{i=1}^{m}\sum_{j=1}^{n}d(i*j)=\sum_{i=1}^{m}\sum_{j=1}^{n}\sum_{x|i}\sum_{y|i}[gcd ...

  6. .net core 2使用ef core 2.0以db first方法创建实体类

    先安装以下三个包: Install-Package Microsoft.EntityFrameworkCore.SqlServer Install-Package Microsoft.EntityFr ...

  7. Lintcode221 Add Two Numbers II solution 题解

    [题目描述] You have two numbers represented by a linked list, where each node contains a single digit. T ...

  8. 开启第一个Node.js的Express项目

    手动创建一个Express.js的应用可大致分为以下步骤: 1.创建文件夹 a. 创建一个项目根文件夹,如helloWord b.在项目的根目录下创建项目的目录结构,依次创建{public,publi ...

  9. Silverlight的认识

    Microsoft Silverlight是一个跨浏览器的.跨平台的插件.Silverlight提供灵活的编程模型,并可以很方便地集成到现有的网络应用程序中.Silverlight可以对运行在Mac或 ...

  10. Maven 项目生成jar运行时提示“没有主清单属性”

    新建了一个Maven的项目,mvn compile和mvn package后生成了jar文件,然后直接到target目录下去执行java -jar xxx.jar命令运行jar包时出现了"x ...