Hibernate常用方法详解
- 格式:doc
- 大小:130.50 KB
- 文档页数:5
Hibernate使⽤详解(⼀)⼀、前⾔ 这些天都在为公司框架重构做准备,浏览了⼀下代码,挑了⼏个不熟或者没接触过的知识点进⾏攻坚,hibernate是其中之⼀。
其实接触hibernate是在⼤学期间,应该是在2012年,已经2017-2012=5年时间了,当初给我的印象就是hibernate难学(特别是关联关系的配置这块内容),没学好,很多概念当时理解不了,于是我经⼿的项⽬基本都是使⽤mybatis,不再去碰这个“⿇烦”(所以,给⼈的第⼀印象很重要,平时要注意⼀下形象了)。
但是呢,我发现,编程的世界就是这么⼩,兜兜转转最后还是需要照⾯,于是乎,我决定,啃下这块⾻头~我翻出了2012年的⼤学课件,也在⽹上搜索了⼀⼤堆的博⽂,算是理清了hibernate关联关系配置这块内容,果真是“会当凌绝顶,⼀览众⼭⼩”,现在回头想想,hibernate并没有第⼀印象那么难,只是有些细节需要注意~ 本篇博⽂持续更新,主要是记录⼀些hibernate使⽤细节、难点,知识点顺序不分难易,想到哪记到哪⼉,有需要⾃⾏全⽂搜索,如有错误之处,还望斧正~ 本⽂运⾏环境: jdk1.8.0_131 Eclipse Mars.2 Release (4.5.2) Hibernate-release-5.2.11.final Mysql 5.6.14⼆、正⽂ 写这篇博⽂的起因是研究hibernate的关联关系配置过程中,发现很多细节问题,对于新⼿或者⼀知半解的⼈来说,理解起来很困难,作为“过来⼈”,我希望能⽤通俗⼀点的描述加上⾃⼰写的实例代码解决同⾏的疑惑,所以这边就先记录⼀下“关联关系”配置过程中的问题~ 数据库中表与表之间的关系分为三种:⼀对⼀,⼀对多,多对多。
数据表是如何体现这种关系的呢?对于⼀对⼀和⼀对多,会在其中⼀张表增加⼀个外键字段(有可能和这张表的主键同⼀字段),关联另外⼀张表的主键,多对多则会建⽴⼀张中间表,存储了两张关系表的主键,hibernate中的关联关系是建⽴在数据库中表的这层关系之上。
hibernatetemplate常用方法HibernateTemplate是Hibernate提供的一个简单而方便的模板类,封装了Hibernate的常用操作方法,可以大大简化Hibernate的使用。
以下是HibernateTemplate的常用方法:1. save方法:用于保存对象到数据库。
示例代码如下:```public void save(Object obj)```2. update方法:用于更新数据库中的对象。
示例代码如下:```public void update(Object obj)```3. delete方法:用于删除数据库中的对象。
示例代码如下:```public void delete(Object obj)```4. get方法:根据主键获取单个对象。
示例代码如下:```public Object get(Class<?> cls, Serializable id)return hibernateTemplate.get(cls, id);```5. load方法:根据主键加载单个对象。
示例代码如下:```public Object load(Class<?> cls, Serializable id)return hibernateTemplate.load(cls, id);```6. find方法:根据HQL查询语句查询对象列表。
示例代码如下:```public List<?> find(String hql)return hibernateTemplate.find(hql);```7. findByExample方法:根据对象的属性值查询对象列表。
示例代码如下:```public List<?> findByExample(Object obj)return hibernateTemplate.findByExample(obj);```8. execute方法:执行Hibernate回调函数。
Hibernate查询首先介绍get()和load()方法的区别:get()方法和load()方法的区别主要在于对二级缓存的使用上。
load()方法会使用二级缓存,而get()方法在一级缓存没有找到会直接查询数据库,不会去二级缓存中查找。
get():如果在数据库中没有记录会返回空,get()无论如何都会返回数据.load():如果数据库中没有记录会抛出异常,如果有数据返回的是一个代理对象。
list和iterator()方法之间的区别:(N+1?)list()方法在执行时,直接运行查询结果所需要的查询语句。
iterator()方法则是先执行得到对象ID的查询,然后在根据每个ID值去取得所要查询的对象。
因此:对于list()方式的查询通常只会执行一个SQL语句,而对于iterator()方法的查询则可能需要执行N+1条SQL语句(N为结果集中的记录数).结果集的处理方法不同:list()方法会一次活的所有的结果集对象,而且他会依据查询的结果初始化所有的结果集对象。
如果在结果集非常庞大的时候会占据非常多的内存,甚至会造成内存溢出的情况发生。
iterator()方法在执行时不会一次初始化所有的对象,而是根据对结果集的访问情况来初始化对象。
一次在访问中可以控制缓存中对象的数量,以避免占用过多的缓存,导致内存溢出情况的发生。
HQL:HQL是一种面向对象的查询语言,HQL的操作对象是类、实例和属性等。
SQL:sql的操作对象是数据表和列等数据对象。
Hql是完全面向对象的查询语言,因此可以支持继承和多条等特征。
HQL查询依赖于Query类,每个Query实例对应一个查询对象。
定参数的功能,Query 接口才是真正的HQL查询接口。
//创建一个Query 对象Java代码1Query query = session.createQuery ("from Customer as c where=:customerName and c.age=:customerAge");//动态绑定参数Java代码2query.setString("customerName","Tom");3query.setInteger("customerAge",21);//执行查询语句,返回结果Java代码4List result = query.list();HQL查询步骤:1:获取Hibernate Session对象。
hibernate saveorupdate举例使用Hibernate是一个用于Java语言的对象关系映射框架,它提供了一种将对象模型与关系数据库进行映射的方式,使开发人员可以通过面向对象的方式进行数据库操作。
其中,saveOrUpdate()是Hibernate中一个常用的方法,用于保存或更新实体对象。
在本文中,我将详细介绍saveOrUpdate()方法的使用,并以示例代码来演示其具体的操作步骤。
首先,我们需要配置Hibernate的相关环境和依赖。
在项目的pom.xml 文件中,添加如下的Hibernate依赖:xml<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-core</artifactId><version>5.4.0.Final</version></dependency>同时,我们需要在项目中配置Hibernate的相关配置文件,如hibernate.cfg.xml。
在该文件中,我们需要配置数据库的连接信息、实体类与数据库表的映射关系等。
接下来,我们创建一个实体类,假设为User,用于映射到数据库中的一张用户表。
javaEntityTable(name = "user")public class User {IdGeneratedValue(strategy = GenerationType.IDENTITY)private Long id;Columnprivate String username;Columnprivate String password;getters and setters}在上述代码中,我们使用Entity注解将User类与数据库表进行映射,并使用Table注解指定了数据库表的名称。
Hibernate查询数据库的三种方式一、Hibernate的HQL与SQL查询1.Hql(Hibernate Query Language)是面向对象的查询查询方式,HQL查询提供了更加丰富的和灵活的查询特性,因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,提供了类似标准SQL语句的查询方式,同时也提供了面向对象的封装。
HQL查询语句from关键字后面跟的类名+类对象,where后用对象的属性做条件;示例代码:(User是映射数据库的一个类)public boolean checkUser(UserForm userForm){//TODO Auto-generated method stub//String HQLString="from User u whereername='"+userForm.getUsername()+"'";String HQLString="from User u where ername=:uname";Session session=HibernateSessionFactory.currentSession();//获取事务session.beginTransaction();Query query=session.createQuery(HQLString);query.setParameter("uname",userForm.getUsername());//绑定参数Object list=query.list().get(0);//list获取数据集,get获取数据集的某条记录//提交事务session.getTransaction().commit();//关闭SessionHibernateSessionFactory.closeSession();User user=(User)list;if(user.getPassword().equals(userForm.getPassword())){return true;}else{return false;}}2.sql是面向数据库表查询,from后面跟的是表名,where后用表中字段做条件;示例代码:([xxdb].[dbo].[student]就是要查询的数据库表)public boolean checkUser(UserForm userForm){//TODO Auto-generated method stub//String SQLString="select*from[xxdb].[dbo].[student]u whereerName='"+userForm.getUsername()+"'";String SQLString=”select*from[xxdb].[dbo].[student]u whereerName=:uname”;Session session=HibernateSessionFactory.currentSession();session.beginTransaction();//Query query=session.createSQLQuery(SQLString).addEntity(User.class);//实体查询Query query=session.createSQLQuery(SQLString).addScalar("userid",StandardBasicTypes.INTEGER).addScalar("username",StandardBasicTypes.STRING).addScalar("password",StandardBasicTypes.STRING).addScalar("gender",StandardBasicTypes.INTEGER);//标量查询query.setParameter("uname",userForm.getUsername());//绑定参数Object list=query.list().get(0);//list获取数据集,get获取数据集的某条记录session.getTransaction().commit();HibernateSessionFactory.closeSession();User user=(User)list;if(user.getPassword().equals(userForm.getPassword())){return true;}else{return false;}}3.对比hql和sql查询方式我们可以发现他们之间的不同:a.首先是查询语句的不同,hql语句from后面跟的类名+类对象,where后用对象的属性做条件,而sql语句from后面跟的是表名,where后用表中字段做条件,这也就是面向对象和面向数据库的一个区别。
hibernate createnativequery 使用【最新版】目录1.Hibernate 简介2.CreateQuery 和 CreateNativeQuery 的区别3.CreateNativeQuery 的使用方法4.实际应用示例正文一、Hibernate 简介Hibernate 是一款流行的 Java ORM(对象关系映射)框架,它可以将 Java 对象与数据库表中的记录相映射,使得 Java 程序员可以更方便地处理数据库操作。
在 Hibernate 中,我们可以通过创建查询(CreateQuery)和本地查询(CreateNativeQuery)等方式来实现对数据库的查询。
二、CreateQuery 和 CreateNativeQuery 的区别1.CreateQuery:它是 Hibernate 中的一种查询方式,可以创建基于Hibernate 的查询语句。
这种查询方式可以实现较为复杂的查询需求,例如:HQL(Hibernate Query Language)查询、Criteria 查询等。
2.CreateNativeQuery:它是另一种查询方式,可以创建基于数据库本地的查询语句。
这种查询方式的性能通常优于 CreateQuery,因为它可以直接生成 SQL 语句,而不需要经过 Hibernate 的转换。
三、CreateNativeQuery 的使用方法1.首先,创建一个 SessionFactory 实例,用于管理数据库连接和会话。
2.获取一个 Session 实例,用于执行数据库操作。
3.使用 Session 实例的 createQuery() 方法,创建一个CreateNativeQuery 实例。
4.通过 Set、Get 等方法设置查询参数。
5.使用 List、Iterate 等方法执行查询并获取结果。
四、实际应用示例以下是一个使用 CreateNativeQuery 的简单示例:```javaimport Hibernate.SessionFactory;import Hibernate.Session;import Hibernate.CreateNativeQuery;import Hibernate.Query;import Hibernate.SessionFactoryBuilder;public class CreateNativeQueryExample {public static void main(String[] args) {// 1.创建一个 SessionFactory 实例SessionFactory sessionFactory = new SessionFactoryBuilder().build();// 2.获取一个 Session 实例Session session = sessionFactory.openSession();// 3.创建一个 CreateNativeQuery 实例CreateNativeQuery createNativeQuery =session.createNativeQuery();// 4.设置查询参数createNativeQuery.setResultMap(newjava.util.HashMap());createNativeQuery.setResultMapProperty("id", "id");createNativeQuery.setResultMapProperty("name", "name");// 5.执行查询并获取结果List list = createNativeQuery.list();// 6.处理查询结果for (Object obj : list) {System.out.println("id: " + obj.get("id") + ", name: " + obj.get("name"));}// 7.关闭 Sessionsession.close();}}```通过以上示例,我们可以看到如何使用 CreateNativeQuery 来执行简单的数据库查询操作。
1.from子句from Person表明从Person持久化类中选出全部的实例。
推荐:from Person as p2.select子句select from Person as pselect .firstName from Person as pselect new list(, p.address) from Person as pselect new ClassTest(, p.address) from Person as p (有前提)select as personName from Person as pselect new map( as personName) from Person as p (与new map()结合更普遍) 3.统计函数查询:1: count() 统计记录的条数2: min() 求最小值3: max() 求最大值4: sum() 求和4: avg() 求平均值//取得Student的数量Query query=session.createQuery("select count(*) from Student")//avg()取得Student平均年龄Query query=session.createQuery("select avg(s.age) from Student as s")//upper()方法将字符串转为大写Query query=session.createQuery("select upper() from Student as s")//去除重复行distinctQuery query=session.createQuery("select distinct s.age from Student as s") select count(*) from Personselect max(p.age) from Person as pselect || "" || p.address from Person as p4.多态查询from Person as pfrom ng.Object ofrom Named as n5.where子句from Person where name like "tom%"from Person as p where like "tom%"from Cat cat where like "kit%"select * from cat_table as table1 cat_table as table2 where table1.mate = table2.id and like "kit%"from Foo foo where foo.bar.baz.customer.address.city like "fuzhou%" from Cat cat, Cat rival where cat.mate = rival.mateselect cat, matefrom Cat cat, Cat matewhere cat.mate = matefrom Cat as cat where cat.id = 123from Cat as cat where cat.mate.id = 69from Person as personwhere person.id.country = 'AU'and person.id.medicareNumber = 123456from Account as accountwhere account.owner.id.country = 'AU'and account.owner.id.medicareNumber = 123456from Cat cat where cat.class = DomesticCatfrom Account as a where .firstName like "dd%" // 正确from Account as a where like "dd%" // 错误6.表达式=, <>, >, <, >=, <=, between, not between, in, not in, is, like等。
hibernate.initialize
Hibernate.initialize方法是 Hibernate 框架中的一个重要方法,用于在Hibernate 初始化会话期间加载和初始化一个实体类的关联对象。
这个方法通常用于延迟加载关联对象,即在需要的时候才加载关联对象,以提高应用程序的性能。
在 Hibernate 中,关联对象的加载方式有两种:立即加载和延迟加载。
立即加载会在加载实体对象时就加载关联对象,而延迟加载则会将关联对象的加载延迟到需要使用时才进行。
Hibernate.initialize方法可以用于将一个关联对象设置为延迟加载。
当调用该方法时,Hibernate 会立即加载关联对象,并将其初始化。
这对于需要在多个地方使用关联对象的场景非常有用,因为它可以避免重复执行相同的加载和初始化操作。
使用 Hibernate.initialize方法时,需要传递一个实体类的实例作为参数。
该方法会返回一个实体类的实例,该实例包含关联对象的初始化数据。
如果关联对象尚未加载,则该方法将触发加载和初始化操作。
需要注意的是,Hibernate.initialize方法只适用于延迟加载的关联对象。
如果关联对象已经被立即加载,则该方法不会执行任何操作。
总之,Hibernate.initialize方法是 Hibernate 框架中用于初始化关联对象的重要方法,它可以帮助提高应用程序的性能,避免重复执行加载和初始化
操作。
在使用该方法时,需要确保关联对象是延迟加载的,并且传递正确的实体类实例作为参数。
Hibernate基础知识详解<hibernate-mapping><class name="*.*.*" table="t_customer" catalog="***"><id name="id" column="c_id"><generator class="identity"/></id><property name="name" column="c_name" length="20"/><set name="orders" inverse="false" cascade="save-update"><key column="c_customer_id"/></set></class></hibernate-mapping>(1)统⼀声明包名,这样在<class>中就不需要写类的全名。
(2)关于<class>标签配置name 属性:类的全名称table 表的名称,可以省略,这时表的名称就与类名⼀致catalog 属性:数据库名称可以省略.如果省略,参考核⼼配置⽂件中 url 路径中的库名称(3)关于<id>标签,<id>是⽤于建⽴类中的属性与表中的主键映射。
name 类中的属性名称column 表中的主键名称 column 它也可以省略,这时列名就与类中属性名称⼀致length 字段长度type 属性指定类型<generator>它主要是描述主键⽣成策略。
详解Hibernatecascade级联属性的CascadeType的⽤法详解Hibernate cascade级联属性的CascadeType的⽤法cascade(级联)级联在编写触发器时经常⽤到,触发器的作⽤是当主控表信息改变时,⽤来保证其关联表中数据同步更新。
若对触发器来修改或删除关联表相记录,必须要删除对应的关联表信息,否则,会存有脏数据。
所以,适当的做法是,删除主表的同时,关联表的信息也要同时删除,在hibernate中,只需设置cascade属性值即可。
cascade表⽰级联操作,在hibernate配置注解@OneToOne,@OneToMany,@ManyToMany,@ManyToOne中的属性。
例如:@ManyToOne(cascade = CascadeType.REFRESH, optional = true)@JoinColumn(name = "user_id", unique = false)private UserBaseInfo userBaseInfo;配置多种级联,例如:@OneToOne(cascade = {CascadeType.REFRESH,CascadeType.PERSIST,CascadeType.MERGE}, optional = true)@JoinColumn(name = "user_id", unique = false)private UserBaseInfo userBaseInfo;CascadeType.PERSIST:级联新增(⼜称级联保存):对order对象保存时也对items⾥的对象也会保存。
对应EntityManager 的presist⽅法。
CascadeType.MERGE:级联合并(级联更新):若items属性修改了那么order对象保存时同时修改items⾥的对象。
对应EntityManager的merge⽅法。
状态 方法 说 明
get 根据给定标识和实体类(实体命名)返回持久化对象的实例,如果没有
符合条件的持久化对象实例则返回null。get是每次都会从数据库取数据以保证数据的可靠。 load 在符合条件的实例存在的情况下,根据给定的实体类(实体命名)和标
识返回持久化状态的实例。load 则会返回一个proxy,相当于一个存根,访问的时候从当前session或者hibernate二级缓存中查找,如果找不到则从数据库中Lazy Load一下。因此load可以更好的利用Hibernate中缓存。 save 首先为给定的自由状态(Transient)的对象(根据配置)生成一个
标识并赋值,然后将其持久化。 update 根据给定的detached(游离状态)对象实例的标识更新对应的持久
化实例。 saveOrUpdate 根据给定的实例的标识属性的值(注:可以指定unsaved-value。
一般默认null。)来决定执行 save() 或update()操作。 persist 将一个自由状态(transient)的实例持久化。
merge 将给定的对象的状态复制到具有相同标识的持久化对象上。
replicate 使用当前的标识值持久化给定的游离状态(Transient)的实体。
evict 将当前对象实例从session缓存中清除。
对象的状态转换图: Customer对象的状态转换过程: HQL查询 关联查询: 多对一关联:从多的一方去查找相关联的一方(多的一方可导航到一的一方,而一的一方不能导航至多的一方),可以采用属性查询的方式。 class TblFwxx{ private TblJd jd; //一的一方 …… } class="com.aptech.jb.entity.TblJd" fetch="select"> HQL:select fw.jd from TblFwxx fw where fw.lxr='伊先生'
一对多关联:从一的一方关联查询多的一方(多方做为一方的集合属性),此时可采用迫切左外连接查询。
隐式联接:隐式联接始终采用多对一或者一对一关联,从来不通过集合值的联(无法编写item.bids.amount)。例如: 1. From User u where u.homeAddress.city = ‘Bangkok’ 2. Select distinct u.homeAddress.city from User u 3. //Bid与itm是多对一 From Bid bid where bid.itm.description like ‘%Foo%’ 4. From Bid bid where bid.item.category.name like ‘%Laptop%’ 5. From Bid bid where bid.item.category.name like ‘%Laptop%’ And bid.item.sccessfulBid.amount > 100
内联接:一对多关联(join, inner join) 使用原因:你可能想要以应该应用到货品Bid的一些条件为基础,来限制通过查询返回的货品。例如,你可能想要出价超过¥100的所有Item;因而这需要一个内部联结。 From Item i join i.bids b where i.description like ‘%Foo%’ and b.amount >100 投影查询: select i from Item i join i.bids b where i.description like ‘%Foo%’ and b.amount >100 类似的 select i from Item i in(i.bids) b where i.description like ‘%Foo%’ and b.amount >100
外联接:一对多关联,多对一或一对一(left join fetch); 抓取集合: From Item i Left join fetch i.bids where i.description like ‘%Foo%’ 也可以利用相同的语法遇抓取多对一或者一对一关联: From Bid bid Left join fetch bid.item Left join fetch bid.bidder Where bid.amount > 100
高级查询 1. 条件查询 创建比较表达式 Criterion restriction = Restrictions.between(“amount”, new BigDecimal(100), new BigDecimal(200)); session.createCriteria(Bid.class).add(restriction);
String emails = {“foo@hibernate.org”,”bar@hibernate.org”}; session.createCriteria(User.class) .add(Restrictions.in(“email”,emails)); 也可以用isEmpty()、isNotEmpty()或者它的实际大小测试集合: session.createCriteria(Item.class) .add(Restrictions.isEmpty(“bids”)); session.createCriteria(Item.class) .add(Restrictions.sizeGt(“bids”,3)); 组合表达式和逻辑操作符 Session.createCriteria(User.class) .add(Restrictions.like(“firstname”,”g%”)) .add(Restrictions.like(“lastnames”,”k%”)); 如果需要分开(or),有两种方法。第一种是把Restriction.or()和Restriction.and()一起使用。 Session.createCriteria(User.class) .add( Restrictions.or( Restrictions.and(Restrictions.like(“firstname”,”g%”, Restrictions.like(“lastname”,”k%”) ), Restrictions.in(“emails”,emails) ) ); 第二种方法是把Restriction.disjunction()和Restrictions.conjunction()一起使用: Session.createCriteria(User.class) .add(Restrictions.conjunction() .add(Restrictions.disjunction() .add(Restrictions.like(“firstname”,”g%”)) .add(Restrictions.like(“lastname”,”k%”)) ) .add(Restrictions.in(“email”,emails)) ); 联结和动态抓取 1.给限制联贯关联 List result = session.createCriteria(Item.class) .add(Restrictions.like(“description”, ”Foo”, MatchMode.ANYWHERE) ) .createCriteria(“bids”) .add(Restrictions.gt(“amount”,new BigDecimal(99))) .list();
session.createCriteria(Item.class) .createAlias(“bids”,”b”) .add(Restrictions.like(“this.decription”,”%Foo%”)) .add(Restrictions.gt(“b.amount”,new BigDecimal(99))); 通过条件查询动态抓取 用join fetch操作即时填入一个集合,或者初始化一个被映射为延迟否则将被代理的对象。可以用Criteria API完成同样的事: session.createCriteria(Item.class) .setFetchMode(“bids”,FetchMode.JOIN) .add(Restrictions.like(“description”,”%foo%”)); 如果想要使用内部联结(很少用,因为它不返回没有出众蝗货品),可以强制它: session.createCriteria(Item.class) .createAlias(“bids”,”b”,CriteriaSpecification.INNER_JOIN) .setFetchMode(“b”, FetchMod.JOIN) .add(Restrictions.like(“decription”,”%Foo%”)); 也可以预抓取多对一和一对一关联: session.createCriteria(Item.class) .setFetchMode(“bids”,FetchMode.JOIN) .setFetchMode(“seller”,FetchMode.JOIN) .add(Restrictions.like(“decription”,”%Foo%”)); 应用结果转换器 默认情况下,所有的条件查询都只返回根实体的实例: List result = session.createCriteria(Item.class) .setFetchMode(“bids”,FetchMode.JOIN) .setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY) .list(); Set distinctResult = new LinkedHashSet(result);
Criteria crit = session.createCriteria(Item.class) .createAlias(“bids”,”b”) .createAlias(“seller”,”s”) . setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP); List result = crit.list(); for(Object aResult : result){ Map map = (Map)aResult; Item item = map.get(Criteria.ROOT_ALIAS); Bid bid = (Bid)map.get(“b”); User seller = (User)map.get(“s”); ... } 2. 3.