• 初识Hibernate


    1.问题

    这两天弄一个项目,连接了mysql。第一天访问数据库没问题,第二天就报错,异常如下:

    Caused by: com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure

    这里只摘取一段,很是头疼。去网上查,大多是说mysql的wait_timeout缺省为8小时,mysql数据库中是28800s。如果在wait_timeout秒期间内,数据库连接一直处于等待状态,那么mysql就将该连接关闭,这时你的java应用的连接池仍然合法的持有该连接的引用。所以你第二天操作数据时,会报错。

    2.解决

    一开始按照网上的思路是更改mysql数据库的wait_timeout字段,最大值是24天/365天(windows/linux)。或者改mysql的配置文件——my.ini/my.cnf(windows/linux)。可是后来想了想,这样过一段时间又会报错,该怎么解决呢。于是后决定试试看hibernate,看看通过这个框架还会导致问题出现吗

    3.Hibernate配置

    首先引入jar:image

    少一个基本会出现各种各样的问题,mysql-connector千万记得。

    接着在src目录下写配置文件:hibernate.cfg.xml

    image

    这里要注意url里面的值,useUnicode=true&

    它与jdbc的写法不同,他需要用& 代替;  不然会报错。

    接着我们建个包,在这个包里面写个pojo对应数据库字段。同时还要写个对应pojo的映射xml:

    image

    user类没什么好说的,跟自己数据库字段对应即可

    这个xml具体配置如下:

    image

    class标签下面name对应的是pojo,table是表名。

    id是映射的唯一标识,也就是表中的主键。要注意的是<generator>标签里的class属性。我这里写的assigned,意思是用户自定义id,即给定一个id

    还有其他6个属性,感兴趣的可以百度,这里就不做介绍了。

    4.写一个Util类获取Session

    package com.hibernate.DBUtil;
    
    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    public class HibernateUtil {
    
        private static final ThreadLocal<Session> threadLocal = new ThreadLocal<Session>();
        private static SessionFactory sessionFactory = null; // SessionFactory对象
    
        static {
            try {
                Configuration cfg = new Configuration().configure(); // 加载Hibernate配置文件
                  sessionFactory = cfg.buildSessionFactory();
            } catch (Exception e) {
                System.err.println("创建会话工厂失败");
                e.printStackTrace();
            }
        }
    
        // 获取Session
        public static Session getSession() throws HibernateException {
            Session session = (Session) threadLocal.get();
            if (session == null || !session.isOpen()) {
                if (sessionFactory == null) {
                    rebuildSessionFactory();
                }
                session = (sessionFactory != null) ? sessionFactory.openSession() : null;
                threadLocal.set(session);
            }
            return session;
        }
    
        /**
         * 重建会话工厂
         */
        public static void rebuildSessionFactory() {
            try {
                Configuration cfg = new Configuration().configure(); // 加载Hibernate配置文件
                  sessionFactory = cfg.buildSessionFactory();
            } catch (Exception e) {
                System.err.println("创建会话工厂失败");
                e.printStackTrace();
            }
        }
    
        // 获取SessionFactory对象
        public static SessionFactory getSessionFactory() {
            return sessionFactory;
        }
    
        // 关闭Session
        public static void closeSession() throws HibernateException {
            Session session = (Session) threadLocal.get();
            threadLocal.set(null);
            if (session != null) {
                session.close(); // 关闭Session
            }
        }
    }

    这里有必要说一下ThreadLocal。因为session是线程不安全的,为了解决并发的问题,防止数据污染,我们在创建session时把她放进ThreadLocal里,这是一个新思路。并不像之前的加synchronized,要程序员自己在各个不同的地方加,这样会显的很烦乱。具体ThreadLocal介绍这里贴一个博客,个人觉得理解的很到位:http://blog.csdn.net/lufeng20/article/details/24314381  ThreadLocal源码内的情况也确实如他所说。

    5.CRUD

    上面配置好了hibernate,下面来写一些方法来操作数据库

    具体方法如下:

    package com.hibernate.DBUtil;
    
    import org.hibernate.Session;
    
    import com.hibernate.Entity.User;
    
    public class HibernateORM {
        private HibernateUtil hibernateinit = null;
        private Session session = null;
    
        public void insert(Object obj) {
            // Hibernate的持久化操作
            try {
                session = hibernateinit.getSession(); // 获取session
                session.beginTransaction(); // 开启事务
                session.save(obj); // 执行数据库添加操作
                session.getTransaction().commit();// 事务提交
                System.out.println("数据添加成功");
            } catch (Exception e) {
                session.getTransaction().rollback();
                System.out.println("数据添加失败");
                e.printStackTrace();
            } finally {
                hibernateinit.closeSession();
            }
        }
    
        //get方法是在不确定数据库是否存在该信息的情况下获取detail
        public void getDetail() {
            try {
                session = hibernateinit.getSession();
                User user = (User) session.get(User.class, new Integer("4"));
                System.out.println("用户ID:" + user.getId() + ",用户姓名:" + user.getName());
                System.out.println("第一次装载对象");
                User user2 = (User) session.get(User.class, new Integer("4"));
                System.out.println("第二次装载对象");
            } catch (Exception e) {
                System.out.println("get()方法对象装载失败!");
                e.printStackTrace();
            } finally {
                hibernateinit.closeSession();
            }
        }
        
        //load方法是在给定ID的情况下获取detail
        public void loadDetail(){
            try {
                session = hibernateinit.getSession();
                User user = new User();
                session.load(user, new Integer("1"));   //装载对象
                System.out.println("用户ID:" + user.getId() + ",用户姓名:" + user.getName());
            } catch (Exception e) {
                System.out.println("load()方法对象装载失败!");
                e.printStackTrace();
            }finally {
                hibernateinit.closeSession();
            }
        }
        
        public void delete(){
            try {
                session = hibernateinit.getSession();
                session.beginTransaction();
                User user = (User)session.get(User.class, new Integer("3"));
                session.delete(user);
                session.flush();
                session.getTransaction().commit();
                System.out.println("对象删除成功!");
            } catch (Exception e) {
                session.getTransaction().rollback();
                System.out.println("对象删除失败!");
                e.printStackTrace();
            }finally {
                hibernateinit.closeSession();
            }
            
        }
        
        public void update(){
            try {
                session = hibernateinit.getSession();
                session.beginTransaction();
                User user = (User) session.get(User.class, new Integer("4"));
                user.setName("233");
                session.flush();
                session.getTransaction().commit();
                System.out.println("对象修改成功");
            } catch (Exception e) {
                session.getTransaction().rollback();
                System.out.println("对象修改失败");
                e.printStackTrace();
            }finally {
                hibernateinit.closeSession();
            }
        }
        
    }

    简单的写了一下,这里要注意,在增删改这些操作上,要加事务,不然会报一个Transaction的错误。

    最后写一个test测试一下:

    image

    自己试了里面一些方法,发现控制台输出了SQL语句和执行结果:

    image

    确实和数据库能对应起来,CRUD操作也都没有问题。

    6.昨天写好这些东西后,对数据库操作了一番发现没有问题,今天看看会不会出现通过JDBC操作mysql的wait_timeout问题。结果没有出现,这个方法应该可以不通过修改mysql数据库从而解决。下面还要进行长时间观察,看看有没有这个问题,这里先做一个记录。

  • 相关阅读:
    google的几道面试题
    轮盘赌算法
    基于packstack的openstack单节点安装
    攻克python3-字典(第四篇)
    攻克python3-列表与元组(第三篇)
    攻克python3-字符串(第二篇)
    攻克python3(第一篇)
    二维数组
    小白对c语言指针的基础总结
    小白对c语言数组的基础总结
  • 原文地址:https://www.cnblogs.com/JJDJJ/p/7258574.html
Copyright © 2020-2023  润新知