zoukankan      html  css  js  c++  java
  • Hibernate过程小计

    1. 对实体 "XXX" 的引用必须以 ';' 分隔符结尾(需要对分号进行编码)

      <property name="connection.url">jdbc:mysql://localhost:3306/test2?useUnicode=true;characterEncoding=gbk</property>

      <property name="connection.url">jdbc:mysql://localhost:3306/test2?useUnicode=true&amp;characterEncoding=gbk</property> 

    2. F3之后,跳到了"需要附加jar或者zip文件"的黑白页面去了,需要做的就是将从官网上面下载的zip文件"attache"即可;记得当年MINA也有同样问题,处理方式也一样,其实查看解压文件,其实文件结构是基本一样的:
    3. 在开始使用配置文件配置Hibernate的映射关系,后来改为声明式的;但是运行时发现了"org.hibernate.MappingException: Unknown entity XXX",后来确定是因为在cfg.xmlmapping节点需要做调整:
      <mapping resource="com/historycreator/hibernate/Event.hbm.xml" />修改为
      <mapping class="com.historycreator.hibernate.Event"/>
    4. Hibernate的查询有两种方式,一种通过指定Id的方式直接获得(session.byId(Test.class).load(16), byId的参数是声明类,load的参数是Id值);还有一种方式是通过SQL方式,SQL方式又分为两种:一种是通过HSQL的方式
      Query query = session.createQuery("from Test where t1=:t1");
      query.setParameter("t1", 16);
      Test entity = (Test)query.uniqueResult();
      需要注意的是:HQL的方式from后面跟着的是实体的名称(推测Hibernate将会根据实体声明的信息找到对应的映射表名形成最终的SQL文);HQL中的t1=:t1是指定t1字段参数名为"t1",参数值是通过"query.setParameter来进行指定;
      第二种方式是使用原生的SQL
      SQLQuery sqlQuery = session.createSQLQuery("select * from test1 where t1=:t1")
      sqlQuery.setParameter("t1", 16);
      sq1Query.addEntity(Test1.class);
      Test entity2 = (Test)sqlQuery.uniqueResult();
      使用原生的SQL,创建的方法不同(createSQLQuery方法),而且还需要添加一步:sqlQuery.addEntity,来告诉session来如何将返回值进行类型转换;
    5. 如果是需要对返回的Query/SQLQuery对象进行操作,需要使用list()方法获得元素列表:
      for(Object item: sqlQuery.list()){
          Test t = (Test)item; ...
      }
    6. 下午使用Hibernate进行构建SFS的数据库操作,但是发现了一个异常"Unknown table 'system_sequences' in information_schema",说是数据库方言错误;后来把*.cfg.xml里面的"dialect"Property注释掉,问题解决;所谓方言其实就是你的数据库种类以及具体类型,比如当时我是用的是Mysql里面的InnoDB模式,于是方言应该设置为:org.hibernate.dialect.MySQLInnoDBDialect(之前设置为H2Dialect);
    7. Hibernate里面配置表级别(数据库连接级别在*.cfg.xml中进行配置)映射有两种方式,一种是*.hbm.xml定义方式,还有一种就是声明的方式;这两种方式采用实在*.cfg.xml中的mapping节点中声明的,但是注意,如果是xml文件配置方式,mapping节点使用的属性是resource,但是声明方式属性使用的是class
      <mapping resource="com/alibaba/conf/event.xml"/>
      <mapping class="com.alibaba.entity.event"/>
      还有一种貌似更加牛逼的方式就是声明一个包体名称,下面的类无条件的将会被认为是采用声明/配置方式:<mapping package="com.alibaba.entity"/>,但是经过验证毛用没有,非常简单,hibernate本身并没有探测功能(比如你新添加了一个类,自动探测到),如果想要自动探测,只能是和Spring结合在一起了;
    8. akka组件貌似很牛逼的样子 http://akka.io/ 
    9. Hibernate拥有"正向工程"的功能,cfg.xmlhbm2ddlProperty,如果设置为create,那么当检测到不同,将会删掉表(schema),重新创建;validate,将会在运行时报错(在初始化sessionFactory的节点上面);update则是更新表结构(如果数据库字段比Entity多,将什么也不做,这样处理可能是因为数据库字段多不会报错,大不了值为空,但是如果Entity字段多,声明的字段值将没有地方保存);如果你不想使用此功能,就注释掉这个节点;正向工程其实和Entity FrameworkCode-First很像;
    10. 读代码的时候看到动物快跑Hibernatesession事务处理机制是通过getTransaction()获得Transaction信息,然后try...catch中对trans对象进行rollback()操作,在finally中调用HibernateUtilcloseSession();这样处理感觉会更加完整;
    11. HibernateUtil中的创建session是放置在localThread上面的,为什么要这么做呢?closeSession的时候,读取的也是从当前线程读取;难道说如果HibernateUtil是设计被多线程访问(屁话,伦家都是static好不好),通过这种方式保证session在各个线程间是独立的;看到了一个死贴上面讲述都是:如果不适用localThread,土的掉渣的方式就是创建一个HashMap,以当前线程做Keyvalue放置响应对象;另外如果想要在一个LocalThread里面放置多个东东,可以向里面放置一个Hashtable/Map即可;
    12. 今天上午尝试使用多线程进行测试HibernateUtil类的时候,发现了对于取最大+1获得主键值的方式还是有很大并发问题,获得了一样的主键值,插入的时候报错了;看来还是应该扔给系统来做这个自增长,自己来维护就不可以简单地取最大+1,而是要提供一个static的资源库,对于一个加锁变量进行+1取最大;
    13. 刚才尝试了一下使用AtomicInteger来进行控制,static块中从数据库中读取最大值,之后查处都是通过这个原子整型的incrementAndGet()方法进行获取+1值,完美的避免的并发问题;
  • 相关阅读:
    试试中文时间
    一道极限题目,难道不识别align*环境?
    一道求三元函数在空间区域上平均值的题目
    一道用单调有界证明的数列极限题目
    ORA-00119和ORA-00132报错
    安装mysql时提示This application requires .NET framework 4.5.2的解决办法
    Linux防火墙的开启关闭
    ORA-12541:TNS:无监听程序问题 解决办法
    卸载oracle11g
    Linux笔记
  • 原文地址:https://www.cnblogs.com/xiashiwendao/p/4691113.html
Copyright © 2011-2022 走看看