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. 【SPOJ】Substrings(后缀自动机)

    [SPOJ]Substrings(后缀自动机) 题面 Vjudge 题意:给定一个长度为\(len\)的串,求出长度为1~len的子串中,出现最多的出现了多少次 题解 出现次数很好处理,就是\(rig ...

  2. $CDQ$分治总结

    A.\(CDQ\) 分治 特别基础的教程略. \(CDQ\)分治的优缺点: ( 1 )优点:代码量少,常数极小,可以降低处理维数. ( 2 )缺点:必须离线处理. \(CDQ\)分治与其他分治最本质的 ...

  3. [Luogu3455][POI2007]ZAP-Queries

    BZOJ(权限题) Luogu 题目描述 Byteasar the Cryptographer works on breaking the code of BSA (Byteotian Securit ...

  4. 使用 vscode将本地项目上传到github以及删除github上的某个文件夹

    安装Git后,可以看到windows环境下有两个命令输入窗口Git CMD 和Git Bash Git GUI是可视化图形界面 Git中的Bash是基于CMD的,在CMD的基础上增添一些新的命令与功能 ...

  5. js改变盒子大小(上下左右)分析

    js改变盒子大小 知识点 三个mouse事件:mousedown mousemove mouseup css的定位和cursor 思路 先解决单边问题识别范围,得到所选区域 event. 根据距离,判 ...

  6. jQuary学习の一の初期准备

    jQuery 的功能概括: 1.html 的元素选取 2.html的元素操作 3.html dom遍历和修改 4.js特效和动画效果 5.css操作 6.html事件操作 7.ajax异步请求方式 通 ...

  7. Hadoop2.x 体系结构和源码编译

    体系结构 Hadoop1的核心组成包括HDFS和MapReduce.HDFS和MapReduce的共同点就是他们都是分布式的. HDFS是包括主节点NameNode,只有一个,还有很多从节点DataN ...

  8. NYOJ 题目12喷水装置(二)

    #include<iostream> #include<algorithm> #include<cmath> using namespace std; struct ...

  9. Android 的自动化测试资源

    环境预备阶段: win7下jdk+eclipse android应用开发环境建立 android genymotion模拟器怎么使用以及和google提供的模拟器性能对比

  10. 用js写动态时钟 2017-03-23

    45每隔1秒变一次: 代码如下: <body onLoad="show()" >   ------------表示当页面载入时执行该事件,可以没有 <div id ...