hibernate----懒加载,原生 sql查询及多种hql查询,表连接查询
来源:互联网 发布:history.js下载 编辑:程序博客网 时间:2024/06/07 01:03
创建实体类:
package com.xiangshuai.hibernate;
import java.util.HashSet;
import java.util.Set;
/**
* 顾客类
* */
public class Customer {
privateInteger id;
privateString cname;
privateSet<Order> orders=new HashSet<Order>();
publicInteger getId() {
returnid;
}
publicvoid setId(Integer id) {
this.id= id;
}
publicString getCname() {
returncname;
}
publicvoid setCname(String cname) {
this.cname= cname;
}
publicSet<Order> getOrders() {
returnorders;
}
publicvoid setOrders(Set<Order> orders) {
this.orders= orders;
}
@Override
publicString toString() {
return"Customer [id=" + id + ", cname=" + cname + ",orders=" + orders + "]";
}
}
package com.xiangshuai.hibernate;
/**
* 订单类
* */
public classOrder {
private Integerid;
privateStringoname;
privateCustomercustomer;
public Integer getId() {
returnid;
}
public void setId(Integer id) {
this.id =id;
}
public String getOname() {
returnoname;
}
public void setOname(String oname) {
this.oname =oname;
}
public Customer getCustomer(){
returncustomer;
}
public void setCustomer(Customer customer) {
this.customer =customer;
}
@Override
public String toString() {
return"Order [id="+ id +", oname="+ oname+"]";
}
}
package com.xiangshuai.hibernate;
/**
* //投影查询查出的数据映射的POJO类,将查询出来的记录直接封装成对象,如果new的这个POJO非本身要映射的Customer类那么必须写全类名
POJO pojo = (POJO)session.createQuery("select newcom.xiangshuai.hibernate.POJO(c.id,c.cname) from Customer c wherec.id=?").setInteger(0, 8).uniqueResult();
* */
public classPOJO {
privateStringpname;
privateIntegerpid;
public POJO() {
super();
// TODO Auto-generated constructor stub
}
public POJO( Integerpid,String pname) {
super();
this.pname =pname;
this.pid =pid;
}
public String getPname() {
returnpname;
}
public void setPname(String pname) {
this.pname =pname;
}
public Integer getPid() {
returnpid;
}
public void setPid(Integer pid) {
this.pid =pid;
}
@Override
public String toString() {
return"POJO [pname="+ pname+", pid="+ pid+"]";
}
}
实体类对应的xml文件
Customer.hbm.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEhibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- ORM元数据 表对象关系映射文件
package : 配置该配置文件中类所在的包. -->
<hibernate-mappingpackage="com.xiangshuai.hibernate">
<classname="Customer"table="t_customer" >
<!-- 如果类属性 name和表列column一致可以只定name -->
<idname="id"column="id"length="255">
<generatorclass="native"></generator>
</id>
<propertyname="cname"></property>
<!-- 一对多关系用 set配置在set标签中将inverse设为ture则此xml对应的类放弃维护外键,
即Customer放弃维护外键,实际开发也一般是一的一方放弃维护外键关系
默认是flase,如果一的一方经常要维护cid外键,那么这里就不要设置,默认就好
<keycolumn="cid"> column类名这里表示在Order对应的表中的列名(表外键字段cid)cid
<one-to-manyclass="Order"/>即cid表对应的类
如果inverse设为true也就是一的一方不负责维护外键cid的创建等等,那么在用session.sava(customer)时
虽然因为设置了cascade="save-update,delete"但也只会保存order对象中已有属性,而不会保存order对象中
没有的属性cid,因此在执行session.sava(customer)前必须执行 order1.set(customer),order1.set(customer),
让order这个多的一方维护外键,先将customer保存到对象中以生成cid这样 session.sava(customer)执行后t_order给的
cid值才不会为null
而 delete却可以直接 session.delete(customer)在删除customer的同时删除customer所拥有的所有订单-->
<!-- set 里面有个属性默认 lazy="true"默认是lazy 也就是查询customer对象时暂时不发sql查Set<Order>
只有在用到order时才查,注意此时session不能关闭的,要不会报错-->
<setname="orders"inverse="true"cascade="save-update,delete"lazy="false">
<keycolumn="cid"></key>
<one-to-manyclass="Order"/>
</set>
</class>
</hibernate-mapping>
Order.hbm.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEhibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<!-- ORM元数据 表对象关系映射文件
package : 配置该配置文件中类所在的包. -->
<hibernate-mappingpackage="com.xiangshuai.hibernate">
<classname="Order"table="t_order" >
<idname="id"column="id"length="255">
<generatorclass="native"></generator>
</id>
<propertyname="oname"></property>
<!-- 多的一方直接用<many-to-one标签配置与一的一方的关系即可
nameOrder的属性名customet,class="Customer" 这个name"customer"对应的类 ,column对应的外键名即多
的一方的外键名和一一方set中的<key column="cid"></key>一致-->
<many-to-onename="customer"class="Customer"column="cid"></many-to-one>
</class>
</hibernate-mapping>
将实体类对应的XML文件mapper到hibernate.cfg.xml中去
hibernate.cfg.xml
<?xmlversion="1.0"encoding="UTF-8"?>
<!DOCTYPEhibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<!-- property 元素用于配置Hibernate中的属性
键:值
-->
<!--hibernate.connection.driver_class :连接数据库的驱动 -->
<propertyname="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<!--hibernate.connection.username :连接数据库的用户名 -->
<propertyname="hibernate.connection.username">root</property>
<!--hibernate.connection.password :连接数据库的密码 -->
<propertyname="hibernate.connection.password">root</property>
<!--hibernate.connection.url :连接数据库的地址,路径 -->
<propertyname="hibernate.connection.url">jdbc:mysql://localhost:3306/demo</property>
<!-- show_sql: 操作数据库时,会向控制台打印sql语句 -->
<propertyname="show_sql">true</property>
<!-- format_sql: 打印sql语句前,会将sql语句先格式化 -->
<propertyname="format_sql">true</property>
<!-- hbm2ddl.auto: 生成表结构的策略配置
update(最常用的取值):如果当前数据库中不存在表结构,那么自动创建表结构.
如果存在表结构,并且表结构与实体一致,那么不做修改
如果存在表结构,并且表结构与实体不一致,那么会修改表结构.会保留原有列.
create(很少):无论是否存在表结构.每次启动Hibernate都会重新创建表结构.(数据会丢失)
create-drop(极少):无论是否存在表结构.每次启动Hibernate都会重新创建表结构.每次Hibernate运行结束时,删除表结构.
validate(很少):不会自动创建表结构.也不会自动维护表结构.Hibernate只校验表结构.如果表结构不一致将会抛出异常.
-->
<propertyname="hbm2ddl.auto">update</property>
<!-- 数据库方言配置
org.hibernate.dialect.MySQLDialect (选择最短的)
-->
<propertyname="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<!-- hibernate.connection.autocommit:事务自动提交 -->
<propertyname="hibernate.connection.autocommit">true</property>
<!-- 将Session与线程绑定=>只有配置了该配置,才能使用getCurrentSession-->
<propertyname="hibernate.current_session_context_class">thread</property>
<!-- 引入ORM映射文件
填写src之后的路径
-->
<mappingresource="com/xiangshuai/hibernate/Customer.hbm.xml"/>
<mappingresource="com/xiangshuai/hibernate/Order.hbm.xml"/>
</session-factory>
</hibernate-configuration>
测试test
package com.xiangshuai.hibernate;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;
import org.junit.Test;
public class Demo1 {
privateConfiguration conf = null;
SessionFactorysessionFactory = null;
Sessionsession = null;
/*
* 在lazy="true"的情况下,如果用 get方法会直接从数据库中查出数据放入快照和session
* 中,而load只会由hibernate生成代理对象, 只有当用到其它 属性时才会去数据 库select出来
* ,并快照和更新session中存在的数据
*/
@Test
publicvoid lazytrue1() {
/*lazy="ture"的情况 get 会马上从数据库中将id为5的customer记录查出并封装但不会马上查
* customer的属性即关联的order
* 如下执行session.get(Customer.class,5)发的sql如下:
* Hibernate:
select customer0_.id asid0_0_,customer0_.cname as cname0_0_
from t_customer customer0_ where customer0_.id=?
* 而只有执行了customer.getOrders()才会发查询orders的sql如下:
* Hibernate:
select orders0_.cid as cid0_1_,orders0_.id as id1_,orders0_.id as id1_0_,orders0_.oname as oname1_0_,
orders0_.cid as cid1_0_ from t_order orders0_ where
orders0_.cid=?
syso执行结果-- [Order [id=10, oname=订单1], Order [id=9, oname=订单2]]
* */
session=getSession();
Customer customer = (Customer) session.get(Customer.class, 5);
System.out.println(customer.getOrders());
closeStream(sessionFactory, session);
}
//原生 sql查询及多种hql查询
@Test
public void testR(){
session=getSession();
//hql条件查询1 --setInteger(0, 5):0表示占位符的位置,从0开始,5表示此占位符set进的值
Customer c1 = (Customer)session.createQuery("from Customer where id=?").setInteger(0,5).uniqueResult();
//hql条件查询2--加select 则必须使用类别名并且slect c(别名)这种格式
Customer c2 = (Customer)session.createQuery("select c from Customer c whereid=?").setInteger(0, 6).uniqueResult();
//hql条件查询2
Customer c3 = (Customer)session.createQuery("select c from Customer c where c.id=?").setInteger(0,7).uniqueResult();
//投影查询(部分),将查询出来的记录直接封装成对象,如果new 的这个POJO非本身要映射的Customer类那么必须 写全类名
POJO pojo = (POJO) session.createQuery("select newcom.xiangshuai.hibernate.POJO(c.id,c.cname) from Customer c wherec.id=?").setInteger(0, 8).uniqueResult();
//投影查询查询出的customer对象记录封装成List<POJO>集合
List<POJO> list = session.createQuery("select newcom.xiangshuai.hibernate.POJO(c.id,c.cname) from Customer c").list();
System.out.println(list);
//排序查询出 按id倒序的两条customer记录,先按id查询反序再分页即可
List<Customer> list2 = session.createQuery("from Customerorder by id desc").setFirstResult(0).setMaxResults(2).list();
//mysql 聚合函数的使用如查询 t_customer共有几条记录,注意uniqueResult() 返回的只能先强转为long值
Long sum = (Long) session.createQuery("select sum(c.id) fromCustomer c").uniqueResult();
closeStream(sessionFactory, session);
}
@Test
public void ljdemo(){
/*
* 表连接查询 -- 内连接 迫切内连接 左外连接 迫切左外内连接 右连接 迫切右连接
* 区别 普通连接与迫切连接的区别在于,普通是将连接查出的一条记录封装成表对象的对象
* 再将所有的对象 放入Object[]中(其中像orders单独再封装成一个对象放入此数组中),
* 而迫切是将一条记录直接封装到Customer看(其中像orders单独再封装成一个对象放入此数组中)
* 左,右连接和mysql一样,左连接左边的会全查出的,而右边的只有满足条件才查出来
* 普通内连接查询出来的结果 如list1为:
* Customer.hbm.xml中set lazy="false"的情况 下 sql为:
*
list1.get(0)获得的object[]为 [Customer [id=5,cname=小明, orders=[Order [id=10, oname=订单1], Order [id=9,oname=订单2]]], Order [id=9, oname=订单2]]
即 object[]中放的是查出的封装成customer,和 order两个对象
list1.get(1)获得的object[]为
[Customer [id=5, cname=小明, orders=[Order [id=10, oname=订单1], Order [id=9,oname=订单2]]], Order [id=10, oname=订单1]]
普通内连接查询出来的结果 如list2为:
Customer.hbm.xml中setlazy="false"的情况下 sql为:
Hibernate:
select customer0_.id as id0_0_, orders1_.id as id1_1_, customer0_.cname as cname0_0_, orders1_.oname as oname1_1_,
orders1_.cid as cid1_1_,orders1_.cid as cid0_0__,orders1_.id as id0__
from t_customer customer0_ inner join t_order orders1_ on customer0_.id=orders1_.cid
object[0]即为 Customer [id=5, cname=小明, orders=[Order[id=10, oname=订单1], Order [id=9, oname=订单2]]]即
Customer一个对象,此对象customer的属性,其中set<Order>单独封装成一个数组。
迫切与非迫切就是看 join 后有没有加 fetch,那么生成的 Oject[] 迫切一个只放一个对象,非迫切放两个对象
[Customer [id=5, cname=小明, orders=[Order [id=10, oname=订单1], Order [id=9,oname=订单2]]],
Customer [id=5, cname=小明, orders=[Order [id=10, oname=订单1], Order [id=9,oname=订单2]]],
Customer [id=6, cname=小明,orders=[Order [id=11, oname=订单1], Order [id=12, oname=订单2]]],
Customer [id=6, cname=小明,orders=[Order [id=11, oname=订单1], Order [id=12, oname=订单2]]],
Customer [id=7, cname=小明,orders=[Order [id=13, oname=订单1], Order [id=14, oname=订单2]]],
Customer [id=7, cname=小明,orders=[Order [id=13, oname=订单1], Order [id=14, oname=订单2]]],
Customer [id=8, cname=小明,orders=[Order [id=15, oname=订单8], Order [id=16, oname=订单9]]],
Customer [id=8, cname=小明,orders=[Order [id=15, oname=订单8], Order [id=16, oname=订单9]]],
Customer [id=9, cname=小明,orders=[Order [id=17, oname=订单10], Order [id=18, oname=订单11]]],
Customer [id=9, cname=小明, orders=[Order[id=17, oname=订单10], Order [id=18, oname=订单11]]]]
* */
//内连接操作(部分)
//普通内连接放入Object[]中(其中像orders单独再封装成一个对象放入此数组中)
session=getSession();
// List<Object[]> list1 =session.createQuery("from Customer c,Order o where o.customer=c").list();
//方法2List<Object[]> list1 = session.createQuery("from Customer c join c.orders").list();
//迫切内连接加 fetch关键字- 不会像普通 内连接一样 放入Object[]中(其中像orders单独再封装成一个对象放入此数组中),而是是直接将记录封装成一个Customer对象(其中像orders单独再封装成一个对象放入此数组中)
// List<Object[]> list2 =session.createQuery("from Customer c join fetch c.orders").list();
//左外连接
List<Object[]> llist =session.createQuery("from Customer c join c.orders").list();
//左迫切外连接
List lflist = session.createQuery("fromCustomer c join fetch c.orders").list();
closeStream(sessionFactory, session);
}
publicSession getSession() {
//1 读取配置文件
conf= new Configuration().configure();
//2 根据配置 创建Factory
sessionFactory= conf.buildSessionFactory();
//3 通过获得操作数据库的session对象
session= sessionFactory.openSession();
returnsession;
}
publicvoid closeStream(SessionFactory sessionFactory, Session session) {
if(session != null) {
session.close();
}
if(sessionFactory != null) {
sessionFactory.close();
}
}
}
- hibernate----懒加载,原生 sql查询及多种hql查询,表连接查询
- Hibernate的HQL查询及原生sql查询语句写法
- Hibernate中的查询:HQL、Criteria、原生SQl
- Hibernate(一)HQL查询、原生sql查询
- Hibernate(一)HQL查询、原生sql查询
- hibernate原生sql查询和hql查询的注意点
- Hibernate 查询HQL,QBC 及命名HQL,SQL查询
- 89-----hibernate的hql查询,原生SQL查询,命名查询,投影查询
- HQL中的原生SQL查询
- HQL条件查询和原生SQL查询
- Hibernate原生SQL查询
- hibernate 原生sql查询
- Hibernate原生SQL查询
- Hibernate原生SQL查询
- Hibernate原生SQL查询
- Hibernate原生SQL查询
- Hibernate原生SQL查询
- Hibernate原生SQL查询
- 线性表简述
- [leetcode]#112. Path Sum
- 习题 4.3
- 习题7
- LaTeX的简单使用
- hibernate----懒加载,原生 sql查询及多种hql查询,表连接查询
- NOIp2017游记
- C语言---多进程
- hiho 第177周
- Super Jumping! Jumping! Jumping! --简单dp
- HQL详解三
- hibernate原生sql查询和hql查询的注意点
- 局部图像处理
- 量子计算机编程原理简介 和 机器学习