IntelliJ IDEA Hibernate 从入门到填坑

背景:本文所涉及的IDE如标题所示:IntelliJ IDEA. Java编译器史上最强大的IDE,对,你没有看错,没有之一。没试过的赶紧放下手中的Eclipse去尝试下他吧。我们常见的Android Studio就是基于他定制而来(他本身也可以开发Android)

一. 项目添加Hibernate框架

这里没什么好说的,对于新建项目时要勾选Hibernate框架。如果项目已经建好了就在项目上右击Add Framework.
算了,展开说下吧。也当是个笔记。

1.新建Hibernate项目

IntelliJ IDEA Hibernate 从入门到填坑_第1张图片
Paste_Image.png

下面红框里的文件就是生成的Hibernate配置文件,后期很多配置都需要他。


IntelliJ IDEA Hibernate 从入门到填坑_第2张图片
Paste_Image.png

2.在现有项目上添加Hibernate框架

右击项目,点击 Add Framework Support


IntelliJ IDEA Hibernate 从入门到填坑_第3张图片
Paste_Image.png

看下图,记得勾选创建默认Hibernate 配置文件


IntelliJ IDEA Hibernate 从入门到填坑_第4张图片
Paste_Image.png

点击OK 下载Hibernate依赖库文件

Paste_Image.png

下载依赖库时可能会失败,因为在天朝,原因你我懂的。嗯,相信你已经知道该怎么做了:给IDE设置proxy
下图是我的项目在下载依赖库时的网络流量情况,很显然需要爬城墙。


IntelliJ IDEA Hibernate 从入门到填坑_第5张图片
Paste_Image.png

二. 项目配置

你以为把Hibernate框架加入就可以用ORM了嘛。 年轻人,naive. 还要加入从maven中获取你所对应的数据库的依赖库,例如我这里的MySQL,那就需要依赖MySQL Connector.其他数据库类似

选中项目,点击菜单 File ~ Project Structure ~ Libraries ~

IntelliJ IDEA Hibernate 从入门到填坑_第6张图片
Paste_Image.png
IntelliJ IDEA Hibernate 从入门到填坑_第7张图片
Paste_Image.png

三.hibernate.cfg.xml 配置

默认生成的hibernate.cfg.xml 内容如下:



 
        
              
       
     
       
        
      
 

关于Hibernate的配置及其详尽用法,可以自行Google之。

下面介绍MySql常用的hibernate.cfg.xml配置




    
        
        jdbc:mysql://127.0.0.1:3306/workdiary?useUnicode=true&characterEncoding=UTF-8&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
        com.mysql.jdbc.Driver
        root
        123456


        
        4

        
        org.hibernate.dialect.MySQLDialect

        
        thread

        
        org.hibernate.cache.internal.NoCacheProvider
        
        true
        
        true

        
        update

        
        
        

    

注意上面的


 

这个在你的项目中是需要删除的,不然会报错的(因为你数据库可能没有这两个表)。而且这个也是hibernate自动生成的。下一节我将介绍怎么自动生成。

还有一点需要注意:那就是每次自动生成实体类后,hibernate.cfg.xml中关于数据库连接那一块总是被替换重置,建议还是改回

             
      
     
     

这种形式,否则你就会遇到 HHH-000319 HHH-000231 Could not get database metadata 等等奇奇怪怪的报错信息。

四. hibernate生成数据库实体类

重点来了,在这一节,我将介绍怎么使用hibernate生成实体类。

  1. 首先将上一节生成的Main.java 重命名一下。

    IntelliJ IDEA Hibernate 从入门到填坑_第8张图片
    Paste_Image.png


    将它命名成** HibernateSessionFactory**
    其实这一步可做可不做,只是Main.java 我个人觉得不适合我的项目命名,而且这个Main.java的主要功能就是提供Hibernate的Session的。

  2. 建个entities包,存放数据库的实体类。

IntelliJ IDEA Hibernate 从入门到填坑_第9张图片
Paste_Image.png
  1. 添加Database连接
    在IDE右侧找到Database标签页。点开


    Paste_Image.png

    IntelliJ IDEA Hibernate 从入门到填坑_第10张图片
    Paste_Image.png

    IntelliJ IDEA Hibernate 从入门到填坑_第11张图片
    Paste_Image.png

连接成功:


Paste_Image.png

点击OK即可。

现在我们到IDE左下角找到 Persistence 标签页,并点开它。

Paste_Image.png

右击菜单:


IntelliJ IDEA Hibernate 从入门到填坑_第12张图片
Paste_Image.png

点击 Generate Persistence Mapping ~ By Database Schema.

IntelliJ IDEA Hibernate 从入门到填坑_第13张图片
Paste_Image.png

然后我们再操作一次。注意图中的红框和字。


IntelliJ IDEA Hibernate 从入门到填坑_第14张图片
Paste_Image.png

生成成功


IntelliJ IDEA Hibernate 从入门到填坑_第15张图片
Paste_Image.png

记得把连接字符串改回来。

  1. 修改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  map = (Map) 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简单使用示例

IntelliJ IDEA Hibernate 从入门到填坑_第16张图片
Paste_Image.png

泛泛而谈一点吧,以上图为例,dao 就是对数据库表操作的封装类的包。
先创建接口,再在dao.impl包中创建实现类。

IntelliJ IDEA Hibernate 从入门到填坑_第17张图片
Paste_Image.png

就是这么简单。Easy.

还有个小坑在这里一笔带过一下吧:Hibernate在save(新增插入)数据时,如果这个Entity有自增长主键,那么请不要对这个新建的Entity的主键字段做任何更改,比如题主我就画蛇添足将Entity主键字段设成-1,心想数据库会自增长的嘛,但是Hibernate不这么想,你如果对主键字段设置了值,他就将这个值一并代入并插入数据库,而往往我们不需要这样。

还有对于更新数据,请先用Session从数据库将这个Entity查出来,再将更改的字段应用到这个查出来的Entity里,最后再调用Hibernate去update这个Entity.千万不要new Entity然后去更新,否则你没更新的字段都会被Hibernate置为null了,这显然和我们想要的不同。

有时间再开辟新的文章详细叙述吧。

五. 排错/debug

  1. 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服务器目录中。

IntelliJ IDEA Hibernate 从入门到填坑_第18张图片
Paste_Image.png

就是拷贝替换到这个目录中。

  1. Debug都能查询到数据,但是偏偏Jersey返回json格式数据时就报错。
    还是Glassfish的问题,Glassfish4.1.1有个bug,在返回json数据的时候就报错了,返回TEXT_PLAIN和XML都是没问题的,这个bug官方已经知道了,会在下个版本修复,目前可以使用Glassfish4.1.0版本的。

IntelliJ IDEA Hibernate 从入门到填坑_第19张图片
关注我的公众号.jpg

你可能感兴趣的