欢迎阅读我的开源项目《迷你微信》服务器《迷你微信》客户端

Hibernate是一个开放源代码的对象关系映射框架,它对JDBC进行了非常轻量级的对象封装,使得Java程序员可以随心所欲的使用对象编程思维来操纵数据库。 Hibernate可以应用在任何使用JDBC的场合,既可以在Java的客户端程序使用,也可以在Servlet/JSP的Web应用中使用,最具革命意义的是,Hibernate可以在应用EJB的J2EE架构中取代CMP,完成数据持久化的重任。——百度百科

序言

博主在《迷你微信》项目上对Hibernate的使用是通过注解方式配置进行增删改查操作、使用c3p0连接池、使用ehcache缓存。

配置

hibernate.cfg.xml配置文件

主要是有关和MySQL数据库连接的配置、Ehcache、C3P0的配置

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- Database connection settings -->
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://127.0.0.1:3306/MiniWechat?useUnicode=true&amp;characterEncoding=UTF-8</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="javax.persistence.validation.mode">none</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>
<!-- C3P0连接池 -->
<property name="c3p0.acquire_increment">1</property>
<property name="c3p0.idle_test_period">100</property>
<property name="c3p0.max_size">5</property>
<property name="c3p0.max_statements">0</property>
<property name="c3p0.min_size">2</property>
<property name="c3p0.timeout">90</property>
<property name="c3p0.preferredTestQuery ">SELECT CURRENT_USER</property>
<property name="c3p0.idleConnectionTestPeriod ">18000</property>
<property name="c3p0.maxIdleTime">25000</property>
<property name="c3p0.testConnectionOnCheckout">true</property>
<!-- Echo all executed SQL to stdout -->
<property name="show_sql">true</property>
<!-- Ehcache 缓存配置 -->
<property name="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</property>
<property name="hibernate.cache.use_second_level_cache">true</property>
<property name="hibernate.cache.use_query_cache">true</property> <mapping class="model.User"/>
<mapping class="model.Chatting"/>
<mapping class="model.Group"/>
</session-factory> </hibernate-configuration>

加载hibernate.cfg.html配置文件并获取Session

public class HibernateSessionFactory {
private static String CONFIG_FILE_LOCATION = "/hibernate.cfg.xml";
private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
private static Configuration configuration = new Configuration();
public static SessionFactory sessionFactory;
private static String configFile = CONFIG_FILE_LOCATION; static {
try{
configuration.configure(configFile);
ServiceRegistry sr = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
sessionFactory = configuration.buildSessionFactory(sr);
}catch(Exception e){
e.printStackTrace();
}
}
private HibernateSessionFactory() {
}
public static Session getSession() {
Session session = threadLocal.get();
if (session == null || !session.isOpen()) {
session = (sessionFactory != null) ? sessionFactory.openSession() : null;
threadLocal.set(session);
}
return session;
}
}

对象的注解配置

主要是类的注解配置、成员变量的注解配置、多对多的注解配置

1.在需要在数据库中建表存储的类型需要在类名前添加注解

@Entity
@Table(name="user")

2.在相关成员变量添加注解

 @Column(name="user_id",columnDefinition = "char(20)  COMMENT '微信号'")

如果是数据库对应的主键需要添加注解:

@Id

如果是自增主键需要添加主键:

@GeneratedValue(strategy = GenerationType.AUTO)

3.多对多关联注解配置

在数据库中我们需要好友关系、聊天群的成员表,但在项目代码中我们并没有定义这样的对象,这是通过多对多的注解配置实现的

例如:

@ManyToMany(targetEntity=User.class)
@JoinTable(name = "user_friends",
joinColumns = @JoinColumn(name = "user_id"),
inverseJoinColumns = @JoinColumn(name = "friend_id"))
public List<User> getFriends() {
return friends;
}
public void setFriends(List<User> friends) {
this.friends = friends;
}

增删改查

在项目中为了更好的将有关数据库的操作和业务逻辑分离,同时也有利于BUG和异常的捕获,我们将有关数据库的操作进行了封装,下面的代码只展示了有关Hibernate的增删改查操作的代码,没有展示封装的代码。

具体的增删改查代码

增:

public void add(Object obj){
Session session = HibernateSessionFactory.getSession();
Transaction trans = session.beginTransaction();
session.save(obj);
trans.commit();
session.close();
}

删:

public  void delete(Object obj){
Session session = HibernateSessionFactory.getSession();
Transaction trans = session.beginTransaction();
session.delete(o);
trans.commit();
session.close();
}

改:

public  void update(Object obj){
Session session = HibernateSessionFactory.getSession();
Transaction trans = session.beginTransaction();
session.update(o);
trans.commit();
session.close();
}

查:

public  void query(String paramName, Object paramValue, Class outputClass){
Session session = HibernateSessionFactory.getSession();
Criteria criteria = session.createCriteria(outputClass);
// 使用缓存
criteria.setCacheable(true);
criteria.add(Restrictions.eq(paramName, paramValue));
List list = criteria.list();
session.close();
}

注意:

1.使用了缓存 后面会更加详细的介绍

2.paramValue的类型需要和查询对象定义的类型相匹配,否则会出现类型无法转换的报错

数据库操作的封装

1.将所有的数据库操作放在同一个类中,并声明为静态方法

2.对所有的操作进行异常捕获 避免抛出数据库、Hibernate相关的异常

3.定义枚举类型的ResultCode 返回操作是否成功

4.重要:在项目中 聊天群类型中定义了 聊天成员对象的List,当查询一个聊天群对象时,Hibernate并没有将聊天成员对象的List也查询出来,而是当需要使用的时候再查询,但前面提到的查询方法中调用了session.close(),这时无法再用原来的聊天群对象直接get聊天成员对象的List(Hibernate的延迟加载导致)。所以在封装的数据库操作类中重载了需要使用到延迟加载的相关方法,即:调用相关方法时传入session,在查询等操作时不立即close掉session,待调用者的方法结束时再close。Session是通过sessionFactory.openSession()方法获取,其实通过这种方式获取的ession时Hibernate会自动关闭。

连接池

在项目开始时并没有使用连接池,但出现过一次数据库无法访问的异常。经过查阅资料发现了问题所在:Mysql服务器默认的“wait_timeout”是8小时,也就是说一个connection空闲超过8个小时,Mysql将自动断开该 connection。Hibernate默认的连接池并不知道该connection已经失效,如果这时有 Client请求connection,Hibernate将该失效的Connection提供给Client,将会造成上面的异常。

解决办法:使用C3P0连接池,有关C3P0连接池的配置在hibernate.cfg.xml配置文件中可以查看,需要的jar包可以在Hibernate的安装包可以找到。

其实一开始使用的是C3P0连接池,使用的是Proxool连接池,但使用过程中遇到了连接池销毁连接时的相关报错,而且没有找到很好的解决办法。所以就改用了C3P0连接池

缓存

EhCache是Hibernate的二级缓存技术之一,可以把查询出来的数据存储在内存或者磁盘,节省下次同样查询语句再次查询数据库,大幅减轻数据库压力

1.有关EhCache的配置可以在hibernat.cfg.xml中查看

2.在需要使用缓存的类添加注解

@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)

3.在数据库的查询操作中设置使用缓存

// 使用缓存
criteria.setCacheable(true);

3.当用Hibernate的方式修改表数据(save,update,delete等等),这时EhCache会自动把缓存中关于此表的所有缓存全部删除掉(这样能达到同步)。但对于数据经常修改的表来说,可能就失去缓存的意义了(不能减轻数据库压力);所以EhCache一般要使用在比较少执行write操作的表(包括update,insert,delete等)[Hibernate的二级缓存也都是这样];

注:本篇来自于数据库调试员:王飞先生

欢迎阅读我的开源项目《迷你微信》服务器《迷你微信》客户端

【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:5.技术简介之Hibernate的更多相关文章

  1. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:0.概述

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 序言 帖主和队友仿制了一个简单版的微信,其中,队友是用Unity3D做前段,帖主用Java的Mina.Hiberna ...

  2. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:7.项目介绍之架构(1)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 <迷你微信>服务器端是使用Java语言,Mina框架编写的,一个良好的架构关系到后期迭代的方便程度 ...

  3. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:9.观察者模式

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 在一个程序的迭代过程中,复杂度渐渐上升,可能会出现一些跨模块的调用的需求,若是直接得到引用来进行使用,会导致模 ...

  4. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:8.自定义传输协议

    欢迎阅读我的开源项目<迷你微信>服务器)与<迷你微信>客户端 前言 在上一篇中,我们讲到了<迷你微信>服务器)的主体架构,还讲到了如何在现有功能上进行拓展,但是拓展 ...

  5. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:6.技术简介之Protobuf

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 protocolbuffer(以下简称Protobuf)是google 的一种数据交换的格式,它独立于语言,独立于平 ...

  6. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统 :1.技术简介之Mina连接

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 Apache MINA(Multipurpose Infrastructure for Network Applic ...

  7. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:4.技术简介之Spring

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 Spring是一个轻量级的Java 开发框架,由Rod Johnson 在其著作Expert One-On-One ...

  8. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:3.技术简介之MinaFilter——LoggingFilter (转)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 LoggingFilter 接下来,使我们对Filter介绍的最后一个——LoggingFilter. 与Proto ...

  9. 【迷你微信】基于MINA、Hibernate、Spring、Protobuf的即时聊天系统:10.项目介绍之架构(2)

    欢迎阅读我的开源项目<迷你微信>服务器与<迷你微信>客户端 前言 前面我们讲到<迷你微信>服务器端的主架构,现在我们来描述一下它的模块详细信息. 网络模块 从上图我 ...

随机推荐

  1. <转>哥舒意:关于米奇的三个真相 (米奇·阿尔博姆)

    http://book.douban.com/review/6436827/   <时光守护者>的故事也不算复杂,虽然有三条线同时进行,但是三条线的情节都条理分明,而且这次他使用了类似于奇 ...

  2. LSI SAS 3008 Web配置操作

    配置 LSI SAS 3008 介绍LSISAS3008的配置操作. 4.1 登录CU界面 介绍登录LSISAS3008的CU配置界面的方法. 4.2 创建RAID 介绍在LSISAS3008扣卡上创 ...

  3. IIS 找不到.net framework 4.0/4.5程序池

    通常情况下是因为没注册造成的,也有可能跟操作系统有关系 以管理员身份运行cmd   打开我的电脑 C:\Windows\System32\cmd.exe,右键以管理员身份运行 然后:C:\WINDOW ...

  4. 定时器详解和应用、js加载阻塞、css加载阻塞

    1.setTimeout().setInterval()详解和应用 1.1 详解: setTimeout.setInterval执行时机 1.2 存在问题: setInterval重复定时器可能存在的 ...

  5. poj 2068 Nim

    Nim POJ - 2068 题目大意:多组数据,两人轮流操作,n轮一循环,给出总石子数和这n轮每次两人能取的石子上限(下限为1).取到最后一颗者输. /* f[i][j]表示在第i轮中一共有j个石子 ...

  6. 洛谷P1607 [USACO09FEB]庙会班车Fair Shuttle

    P1607 [USACO09FEB]庙会班车Fair Shuttle 题目描述 Although Farmer John has no problems walking around the fair ...

  7. java.lang.ClassCastException: java.util.ArrayList cannot be cast to com.github.pagehelper.Page

    出现这个错误,首先看配置mybatis-config.xml中的<plugins> <plugin interceptor="com.github.pagehelper.P ...

  8. CF987C Three displays 解题报告

    题目传送门 题目大意 n个位置,每个位置有两个属性s,c,要求选择3个位置i,j,k,使得s_i<s_j<s_k​,并使得c_i+c_j+c_k最小 方法1 n³枚举每一种情况(也许可以拿 ...

  9. 解决element-ui中el-menu组件作为vue-router模式在刷新页面后default-active属性与当前路由页面不一致问题的方法

    解决办法是给menu的default-active绑定route.path形如:<el-menu :default-active="$route.path" ...>每 ...

  10. @Import @bean,@Conditional @ConfigurationProperties @EnableConfigurationProperties 注解使用

    一分钟学会spring注解之@Import注解http://blog.51cto.com/4247649/2118354 @Autowired与@Resource 注解的使用 https://www. ...