Hibernate

个人总结:

对数据库操作的半成品,封装基本的dml操作,增删改查都实现了很简单的方法,稍微复杂点的可以使用hql语句实现

使用框架步骤:

一、新建一个项目

——— 是不是web都无所谓,hibernate只是对数据库的操作

二、添加hibernate框架jar包

三、Hibernate.cfg.xml

<!DOCTYPE hibernate-configuration PUBLIC  "-//Hibernate/Hibernate Configuration DTD 3.0//EN"  "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">  <hibernate-configuration>  <session-factory >  <!-- 在控制台打印hibernate语句 --><property name="show_sql">true</property><!-- 格式化hibernate语句,没有这句话输出的hibernate语句是一整条 --><property name="format_sql">true</property><!-- 数据库名 --><property name="myeclipse.connection.profile">orcl</property><!-- oracle数据库驱动 -->  <property name="hibernate.connection.driver_class">oracle.jdbc.driver.OracleDriver</property>  <!-- oracle数据库url -->  <property name="hibernate.connection.url">jdbc:oracle:thin:@127.0.0.1:1521:orcl</property>  <!-- 数据库的登陆用户名 -->  <property name="hibernate.connection.username">scott</property>  <!-- 数据库的登陆密码 -->  <property name="hibernate.connection.password">scott</property>  <!-- 方言:为每一种数据库提供适配器,方便转换 -->  <property name="hibernate.dialect">org.hibernate.dialect.OracleDialect</property>  </session-factory>
</hibernate-configuration>  

四、实体类以及实体类对应的映射文件

实体类映射到数据表
有多个实体就直接把映射语句多写几句。。。

1、通过注解方式映射
在实体类上直接通过注解标明与其相关的数据表

  <!-- 注解方式加载实体类的映射 --><!-- <mapping class="entities.User"/> -->

2、通过xml文件映射
实体类User.java建好,建User.hbm.xml文件
在hibernate.cfg.xml中映射xml

<!-- xml方式把实体类的映射文件加载进来 --><mapping resource="entities/User.hbm.xml"/><mapping resource="entities/Group.hbm.xml"/><mapping resource="entities/Manager.hbm.xml"/><mapping resource="entities/Role.hbm.xml"/>

Xml映射文件:
(这里是单表的,只用写本表的属性即可 )

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC   "-//Hibernate/Hibernate Mapping DTD 3.0//EN"  "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">  <hibernate-mapping><class name="entities.Manager" table="tbl_manager"><id name="id"><column name="id" /><generator class="increment"></generator></id><property name="managername"></property></class></hibernate-mapping>

五、测试

//管理hibernate配置信息
Configuration cfg = new Configuration().configure();
//获得SessionFactory对象以创建session对象
sessionFactory = cfg.buildSessionFactory();
session = sessionFactory.openSession();
//开启事务
transaction = session.beginTransaction(); //dml操作
Role role = new Role();
role.setRolename("monkey");
session.save(role);//一个小例子//提交事务
transaction.commit();
//结束本次操作
if(session != null){  if(session.isOpen()){  //关闭session  session.close();  }
}  

Configuration是Hibernate的入口,在新建一个Configuration的实例时(构造),Hibernate会在CLASSPATH环境变量中查找hibernate.properties文件。
如果该文件存在,则将文件的内容加载到内容中,如果不存在,则抛出异常。
.configure() 方法默认会在CLASSPATH环境变量下面寻找hibernate.cfg.xml文件,

**hibernate的持久化操作:

增session.save(user)
删session.delete(user)
改session.update(user)
session.get(…) 均可正常使用,当查询对象不存在在数据库里时,get 返回null
session.load(…) load返回objectNotFoundException

异常信息:org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.geeksss.HibernateStudy.entity.Users#10]

当使用Session的get()方法时,如果加载的数据不存在,get()方法会返回一个null;但是使用load()方法,若加载的数据不存在,则会抛出异常。

load()方法有点麻烦的地方是会出很多异常,相比而言get()就简单多了

关联映射:

(开始有多表的了)

单向一对多—–》通过一端查所有多端

user 和 group 之间,一个group 有多个 user ,但是一个user 只能属于一个 group ,所以是 group 和 user 是 一对多 的关系:
实体类上:
一端group上包含 集合 set 属性 users
多端user上包含 int 类型的 groupid 外键

xml中
一端 group.hbm.xml

 <set name="users"  inverse="true" lazy="false"><!--指定“多”的一端的外键,与“一”端得主键相关联--> <key column="groupid" ></key> <!--指定了“多”端对应的类-->  <one-to-many class="entities.User"/></set> 

多端user.hbm.xml

<!-- 单向一对多关系,这里是多端的外键 --><property name="groupid" ></property>  

单向多对一——–》在多端上查所有,顺便查了一端的

一端 group 不做处理
多端 user 包含属性: private Group group;
user.hbm.xml 如下:

    <!-- 单向多对一关系,user里面的外键,对应group的主键 --><many-to-one name="group" class="entities.Group"><column name="groupid"></column>//多端的外键</many-to-one>

测试实例:

group = session.get(Group.class, new Integer("106"));
user = new User();
user.setUsername("data");
user.setUserpassword("data");
//user.setGroup(group);//单向一对多关系
user.setGroupid(group.getId());//单向多对一关系
session.save(user);

双向多对一/双向一对多
把上面那两个单向的合在一起
一端 group 上包含 集合 set 属性 users
多端 user 加上 private Group group;

xml
一端group

<set name="users"  inverse="true" lazy="false" cascade="all" outer-join="true"><!-- 指定“多”的一端的外键,与“一”端得主键相关联   --><key column="groupid" foreign-key="id"></key><!-- 指定了“多”端对应的类   --><one-to-many class="entities.User"/>
</set>

xml 多端

 <many-to-one name="group" class="entities.Group" outer-join="true"><column name="groupid"></column></many-to-one>

测试的时候要注意输出,因为两边都能用所以要格外注意是不是输出多了

测试group的时候
group类 toString 加上 this.getUsers() 输出 ,user类 去掉 this.getGroup().toString()
测试user的时候跟以上相反
user类加上 this.getGroup().toString() , group类 toString 去掉 this.getUsers() 输出

单向一对一
分主键关联和外键关联,我用外键关联

补充:这个是单向一对一关系,只能从manager端查找group
Group 和Manager 一对一关系,manager表中含有groupid 外键对应 group 表中的ID主键

Group类是正常属性
Manager类中含有group类型的对象

映射文件如下:
Group.hbm.xml——-普通映射文件
Manager.hbm.xml

<!-- 单向一对一关系,只能从manager端查找group -->
<!-- unique=true 指明这是一端 -->
<many-to-one name="group" unique="true" class="entities.Group"><column name="groupid"></column>
</many-to-one>以上这种方法只能用于从manager端查找group

双向一对一

Group 和Manager 一对一关系,manager表中含有groupid 外键对应 group 表中的ID主键

Group类 中含有manager类型的对象
Manager类中含有group类型的对象

可以从manager查group,也可以从group查manager
有外键的那一边 manager映射文件

<!-- 一对一关系,有外键的那边,不管单双向,这边都这么写 -->
<!-- unique=true 指明这是一端 -->
<many-to-one name="group" unique="true" class="entities.Group"><column name="groupid"></column>
</many-to-one>

外键映射的那一边 group映射文件

<!-- 双向一对一 -->
<one-to-one name="manager" property-ref="group" class="entities.Manager">
</one-to-one>

要注意property-ref这个属性,很重要,关键的地方就在这里。
property-ref:指定关联类的属性名,这个属性将会和本类的主键相对应。如果没有指定,会使用对方关联类的主键来跟本类的主键比较,这里要注意不是关联表中的外键字段名。如果不指定这个属性,那么一对一默认会使用主键去做对比。相当于原本我们是可以通过本类的主键去和关联类的外键比较,然后来找到对应记录的,但是这里一对一中没有column属性,所以该方法行不通,因此就想出了这种办法,不跟外键比,也不能跟主键比(因为不是主键关系),那么就跟关联表中的一个属性比,也就是我们这个manager类中的group属性,为什么找得到呢,因为从manager类能找到group属性,那么manager中的group中就会有对应的值,我们跟该值比,也就能找到对应的manager了。
**class:**manager所在的类,这个也可以不写,hibernate会自动帮我们找到
测试:

group = session.get(Group.class, new Integer("106"));Manager manager = new Manager();manager.setManagername("wanba");manager.setGroup(group); session.save(manager);

多对多

多端对多端配置基本相同 ,user和role 要有中间表 user_role
user类 private Set roles;
role类 private Set users;

xml 配置
user.hbm.xml

<!-- 多对多关系 -->
<set name="roles" table="user_role"><!-- 通过userid去user_role里面找role的ID --><key column="userid"></key><!-- column和class的意思是user_role.roleid=tbl_role.id--><many-to-many column="roleid" class="entities.Role">  </many-to-many>
</set>

role.hbm.xml

 <!-- 多对多关系 -->
<set name="users" table="user_role"><!-- 通过roleid去user_role里面找user的ID --><key column="roleid"></key><!-- 再通过user的ID找到 user 放到users里去 --><many-to-many column="userid" class="entities.User"></many-to-many>
</set>

插入:
user = session.get(User.class,new Integer(“3”));
role = session.get(Role.class, new Integer(“1”));
user.getRoles().add(role);
role = session.get(Role.class, new Integer(“2”));
user.getRoles().add(role);
role = session.get(Role.class, new Integer(“3”));
user.getRoles().add(role);

session.save(user);
酱紫user里面就有了role1、role2、role3这三个角色

Hql语句:

基本类似于SQL语句,用findAll(“from User”)就可以直接查出user表中所有数据
这里的User 是 跟表对应的 实体类名
Q.setString(0,”123”); 设置参数值

注解:

实体类的注解:
@Entity
@Table(name = "tbl_user")
public class User {@Id //主键  @GeneratedValue(strategy=GenerationType.AUTO)private int id;@Column(name="username")private String username;@Column(name="userpassword")private String userpassword;

异常错误信息整理:

1、序列不存在
Hibernate: select hibernate_sequence.nextval from dual
七月 25, 2017 9:00:31 上午 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 2289, SQLState: 42000
七月 25, 2017 9:00:31 上午 org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: ORA-02289: 序列不存在

org.hibernate.exception.SQLGrammarException: could not extract ResultSet

解决方案:
1.导致这个问题的一个原因是,没有用dba的身份连接数据库。在使用scott账户进行nextval操作的时候出现这个错误。
2.Sequence 是oracle 的 主键增长策略, 在设置这个表里面的ID 做主键的时候不用特别指定Sequence , 只用设置像这样就行了.

<id name="id" type="java.lang.Integer"><column name="id" /><generator class="increment"></generator></id>  

3.Hibernate: select hibernate_sequence.nextval from dual找不到序列解决办法
在hibernate.cfg.xml配置文件中增加
<property name="hbm2ddl.auto">update</property>
问题解决。
(这个没试过,网上找的)

2、jar包
org.hibernate.HibernateException: HHH000142: Javassist Enhancementfailed: com.s118.user.entity.User
原因: hibernate和struts2的包冲突
解决方案:
把struts2的javassist-3.11.0.GA.jar删除

3、反射获取实体类对象
org.hibernate.MappingException: Could not get constructor fororg.hibernate.persister.entity.SingleTableEntityPersister
只知道是反射获取实体类对象时出了错。
错误原因:

(1)实体类的属性对象没有设置setter或者getter。

http://stackoverflow.com/questions/18042247/could-not-get-constructor-for-org-hibernate-persister-entity-singletableentitype

(2) 没有导入javassist的jar文件 (javassist-3.15.0-GA.jar什么的)
http://blog.csdn.net/xiaochangwei789/article/details/7712725

(3)映射问题
我的实体类中的属性对象名和映射文件的property name不一致。

我这次出的错是先导包的时候导的是javassist-3.4.GA.jar报了第一个错,然后把javassist删了报第二个错,后面换成javassist-3.20.0-GA.jar就不报错了

4、java.lang.StackOverflowError

原因:多对多或者一对多的时候输出set集合那里冲突了,不能重复

5、主键约束
Caused by: org.hibernate.HibernateException: identifier of an instance of .[类名]. is alterde from [数字] to [数字]

原因:是由于在一个事务中更新了主键,而主键是不能被更新的

6、session创建出错
org.hibernate.HibernateException: No CurrentSessionContext configured!
原因:当前没有可用的session,换成seesionFactory.openSession()

暂时先这样,因为是以前做的,数据库里的表都没了,又懒得重新建,所以没有运行的结果和表内容。。。

hibernate 基本相关推荐

  1. java面试常见问题之Hibernate总结

    1  Hibernate的检索方式 Ø  导航对象图检索(根据已经加载的对象,导航到其他对象.) Ø  OID检索(按照对象的OID来检索对象.) Ø  HQL检索(使用面向对象的HQL查询语言.) ...

  2. Spring中启用Hibernate二级缓存步骤

    1.在applicationContext.xml配置文件中SessionFactory  bean中配置缓存 <!-- 配置会话工厂对象 --> <bean id="se ...

  3. ssh(Struts+spring+Hibernate)三大框架整合-简述

    ssh(Struts+spring+Hibernate)三大框架配合使用来开发项目,是目前javaee最流行的开发方式,必须掌握: 注意: 为了稳健起见,每加入一个框架,我们就需要测试一下,必须通过才 ...

  4. Hibernate框架第二天

    ### Hibernate的持久化类 ### ---------- **什么是持久化类** 1. 持久化类:就是一个Java类(咱们编写的JavaBean),这个Java类与表建立了映射关系就可以成为 ...

  5. Hibernate **关于hibernate4.3版本之后org.hibernate.service.ServiceRegistryBuilder被弃用**

    之前一直都是使用hibernate4.2.21的我,有一天突然没有使用本地的jar包而是让IDEA自动下载最新版本的hibernate5.2.2之后,发现有几个经常使用的方法报错了. //创建配置对象 ...

  6. 使用hibernate与mysql时数据不能插入的原因及解决办法

    1.背景 之前从没用过hibernate,因此在网上搜了一下hibernate快速入门方面的信息,最后我按照<Myeclipse Hibernate 快速入门 中文版>(CSDN,百度文库 ...

  7. IntelliJ IDEA下自动生成Hibernate映射文件以及实体类

    转自:https://blog.csdn.net/qq_34197553/article/details/77718925 1.构建项目并添加项目结构配置以及配置初始参数 1.1.如图将基本的架子搭建 ...

  8. Spring Hibernate JPA 联表查询 复杂查询

    (转自:http://www.cnblogs.com/jiangxiaoyaoblog/p/5635152.html) 今天刷网,才发现: 1)如果想用hibernate注解,是不是一定会用到jpa的 ...

  9. 5 -- Hibernate的基本用法 --2 1 Hibernate 下载和安装

    1. 下载Hibernate压缩包 2. 解压:文件结构 ⊙ documentation : 该路径下存放了Hibernate的相关文档,包括Hibernate的参考文档和API文档等. ⊙ lib ...

  10. Hibernate的一级缓存

    Hibernate的一级缓存 什么是缓存:缓存将数据库/硬盘上文件中数据,放入到缓存中(就是内存中一块空间).当再次使用的使用,可以直接从内存中获取 缓存的好处:提升程序运行的效率.缓存技术是Hibe ...

最新文章

  1. SpringMVC工作原理详解
  2. Science评论|只需加一种菌,番茄不仅抗盐胁迫还提高65%产量!
  3. python编写程序-Python 编程速成(推荐)
  4. 三层架构用户登录代码c语言,网站用户登录、注册和修改密码常用代码,采用三层架构...
  5. IDEA2021快捷键windows
  6. android工程创建,3.2.1 创建Android 项目(2)
  7. java document select_javasript 操作option select
  8. size_t strtok
  9. Android Theme
  10. 【Docker】练习-在容器中部署静态网站
  11. python数字图像处理(15):霍夫线变换
  12. 异贝,通过移动互联网技术,为中小微实体企业联盟、线上链接、线上线下自定义营销方案推送。案例14
  13. 国内三大云数据库测试对比
  14. springboot+Rabit实战一:(Rabbit MQ windows 环境搭建)
  15. 【源码共享】我花2小时写了微信官网的响应式布局HTML+CSS 换成旅行主题风格更炫酷了
  16. excel数据表转成insert语句插入数据库
  17. MSCOMM32控件注册的两种办法
  18. 所有计算机专业的学生应该认识到的
  19. 2022-2028年中国金融业OCR识别行业市场调查研究及前瞻分析报告
  20. 网页上facebook分享功能的具体实现

热门文章

  1. 合工大计算机有哪些好的老师,合肥工业大学计算机与信息学院导师教师师资介绍简介-☆郑利平...
  2. linux系统查看当前安装字库,Linux系统下安装和配置中文字库的方法
  3. C语言读取BMP格式图片
  4. 远程连接桌面到ubuntu登录闪退
  5. 我们的世界 文/江湖一劍客
  6. 新浪微博价值大幅贬值 将受腾讯致命冲击
  7. Hutool导出Excel,在一个单元格设置多个字体样式
  8. 必须记住的电源防反接电路,推荐后两种电路!
  9. 惠普HP DesignJet 500 Plus 打印机驱动
  10. [渝粤教育] 沈阳理工大学 复变函数与积分变换 参考 资料