zoukankan      html  css  js  c++  java
  • Hibernate 配置详解(11)

    hibernate.session_factory_name_is_jndi

    配置hibernate.cfg.xmlSessionFactoryname属性是否作为JNDI名称绑定。默认是true,即默认情况下,只要给SessionFactory配置了name属性,Hibernate就会把这个名字绑定到JNDI上。关于这个的配置,请看:

    http://blog.csdn.net/stefwu/article/details/10186077

    如果设置了

    Hibernate.session_factory_name_is_jndi false


    那么随便在什么地方为 SessionFactory 设置 name ,都不会做任何绑定了(也就不会再启动 hibernate 的时候报错了)。





    hibernate.jdbc.use_get_generated_keys

    配置hibernate是否通过PreparedStatementgetGeneratedKeys()方法得到数据库生成的ID值。在一般情况下,将该值设置为true可以提高一些性能,当然,数据库本身提供的驱动也得支持getGeneratedKeys()方法。默认情况下,hibernate通过数据库的DatabaseMetaDatasupportsGetGeneratedKeys()方法返回的值作为默认值。所以一般情况下该属性不用手动设置,hibernate会选择最好的方式。

    那么假如数据库驱动不支持getGeneratedKeys方法,Hibernate又会怎么处理这个生成的id呢?很有趣,简单做个实验,设置:

    hibernate.jdbc.use_get_generated_keys false


    再任意创建一个对象,设置其id生成策略为native。比如我现在用的数据库是MYSQL,驱动是mysql-connector-java-5.1.24-bin.jar(这个驱动本身是支持getGeneratedKeys的):

    @Test
    
    public void testSave() {
    Session session = HibernateUtil.getInstance().getSession();
    session.beginTransaction();
    session.save(new User());
    session.getTransaction().commit();
    session.close();
    }


    运行测试,控制台输出:

    315 [main] DEBUG org.hibernate.SQL  - insert into USER (name, age, borndate, married) values (?, ?, ?, ?)
    
    330 [main] DEBUG org.hibernate.SQL  - select last_insert_id()


    效果很明显, hibernate 只能使用 last_insert_id() 函数来得到最后插入的值,效率低,而且在高并发情况下易出错。

    所以,最好还是将该配置的值留给hibernate自己去选择。



    hibernate.hbm2ddl.auto

    这个配置项应该所有学习hibernate的人都应该用过吧,该属性可以配置hibernate是否根据映射文件自动生成数据库表的生成策略。一般是用在先有Java对象再生成表的项目中(也存在快速原型设计)中。该配置可选的值有:vaildateupdatecreatecreate-drop,除此之外填的任何值都没有实际意义,相当于不自动生成(none)

    下面分别简单总结一下几种选项的功能:

     1,create-drop:hibernate正常启动的时候创建表(等同于create

              1,什么是正常启动:buildSessionFactory()调用成功

              2,创建哪些表:创建hibernate这次管理的对象对应的表

              3,如果表已经存在:如果是hibernate要管理的对象对应的表,删除源表,重新创建表

     2,create:hibernate正常启动的时候创建表

              同上

     3,update:hibernate正常启动的时候修改表的结构:

              1,修改哪些表:hibernate这次管理的对象对应的表

              2,如果表已经存在:只修改表结构,不删除/重建表

              3,如果增加一列:直接增加一列

              4,如果删除一列:不管

              5,如果修改一列的类型:尝试修改该列的类型,如果修改失败,发出警告

     4,validate:hibernate正常启动的时候验证表的结构,如果不匹配直接报错,hibernate无法启动。

    其中要注意一点的就是在很早的版本的时候,hibernate已经把create-dropcreate都统一成了启动时先删除所有的表,再重新创建表这种策略了。在平时的开发中,个人一般习惯在白盒阶段设置为create(当然需要把系统拆成一个个小模块启动,要不对象多了,启动时间太长),黑盒阶段设置为update,在生产环境设置为validate。在生产环境不建议使用update,原因前面说了,update遇到属性类型修改,如果更新不了表中列的类型,不会报错,只会给一个警告,这确实挺危险的。

    另外,hibernate还提供了直接把映射文件导出为SQL文件的方式。要导出SQL,我们只需要用到两个类:SchemaExportSchemaUpdate。从名字上面就能很容易看出来,一个用于生成更新的任务,一个用于生成创建的任务。简单使用代码如下:

      /**
      	 * 将删除表/创建表的SQL完整导出
      	 */
      	@Test
      	public void testExport() {
      		// 要导出SQL,需要知道hibernate管理了哪些domain,所以需要读入配置
      		Configuration config = new Configuration().configure();
      		// 要导出SQL,需要知道数据库链接信息,方言等
      		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
      				.loadProperties("hibernate.properties").buildServiceRegistry();
      		// 根据Configuration和ServiceRegistry创建一个SchemaExport对象
      		// setFormat方法用于设置是否对生成的SQL进行格式化,格式化效果和hibernate.format_sql一样
      		// setOutputFile方法用于设置把生成的SQL输出到哪个文件中
      		// create方法用于创建SQL,第一个参数用于设置是否将SQL输出到控制台和文件中,
      		// 第二个参数用于设置是否将此次SQL在数据库上执行
      		new SchemaExport(serviceRegistry, config).setFormat(true)
      				.setOutputFile("create.sql").create(true, false);
      	}
      
      	/**
      	 * 将删除表的SQL完整导出
      	 */
      	@Test
      	public void testExportDrop() {
      		// 要导出SQL,需要知道hibernate管理了哪些domain,所以需要读入配置
      		Configuration config = new Configuration().configure();
      		// 要导出SQL,需要知道数据库链接信息,方言等
      		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
      				.loadProperties("hibernate.properties").buildServiceRegistry();
      		// drop方法用于创建删除表的SQL,第一个参数用于设置是否将SQL输出到控制台和文件中,
      		// 第二个参数用于设置是否将此次SQL在数据库上执行
      		new SchemaExport(serviceRegistry, config).setFormat(true)
      				.setOutputFile("drop.sql").drop(true, false);
      	}
      
      	/**
      	 * 将修改表结构的SQL完整导出
      	 */
      	@Test
      	public void testExportUpdate() {
      		// 要导出SQL,需要知道hibernate管理了哪些domain,所以需要读入配置
      		Configuration config = new Configuration().configure();
      		// 要导出SQL,需要知道数据库链接信息,方言等
      		ServiceRegistry serviceRegistry = new ServiceRegistryBuilder()
      				.loadProperties("hibernate.properties").buildServiceRegistry();
      		// 根据Configuration和ServiceRegistry创建一个SchemaUpdate对象
      		SchemaUpdate update=new SchemaUpdate(serviceRegistry, config);
      		// setFormat方法用于设置是否对生成的SQL进行格式化,格式化效果和hibernate.format_sql一样
      		update.setFormat(true);
      		// setOutputFile方法用于设置把生成的SQL输出到哪个文件中
      		update.setOutputFile("update.sql");
      		// execute方法用于创建修改表结构的SQL,第一个参数用于设置是否将SQL输出到控制台和文件中,
      		// 第二个参数用于设置是否将此次SQL在数据库上执行
      		update.execute(true, false);
      	}



  • 相关阅读:
    【Vue】 修饰符sync
    【VUE】vue路由跳转的方式
    【Element】elementui的Cascader 级联选择器,在懒加载的时候数据无法回显的解决方案
    【ES6】利用ES6 Set 将数组去重
    【.NETCORE】Refit 框架
    【.NETCORE】ASP.NET Core SignalR
    【Visual Studio Code】驼峰翻译助手
    VueX(Vue状态管理模式)
    hdmi 随笔
    ad 差分布线 等长布线
  • 原文地址:https://www.cnblogs.com/riskyer/p/3290242.html
Copyright © 2011-2022 走看看