Hibernate查询方式及关联

来源:互联网 发布:淘宝店铺最迟多久发货 编辑:程序博客网 时间:2024/06/10 03:37
Hibernate查询方式

hql:hibernate QUery Language :以字符串的形式进行数据查询。
-------------面向对象的字符串格式。
原生sql/本地查询:就是纯粹的sql语句。
Criteria查询:动态生成查询语句。

2.使用hql的步骤:
---获得session
a.创建Query对象,并且执行sql语句
b.接受返回值。
c.处理返回值。
---关闭session。
3.hql语句
【from 实体类的名字】 ===select * from 表名=====select 别名 from 表名 别名
from Users
from org.ecjtu.entity.Users
from Users u
添加查询条件
from 实体的名字 where 实体的属性=?and 实体的属性=?
例如:
1)
String hql="from Users where username=?";
Query query=session.createQuery(hql);
 query.setString(0, "小明");
2)
String hql="from Users where username=:a";  --a为代号名。
Query query=session.createQuery(hql);
 query.setString("a", "小明");
使用setxxx()   确定变量的类型。
使用setParameter(),可以不在乎属性是什么类型的。在不确定变量类型的时候,使用。
query.setParameter("b", 7);
 
query.list()和query.iterate()区别
1.返回值不一样
2.查询原理不一样。
list查询:select * from 表名
Iterate()查询:
select id from 表名
select * from 表名  where id=?
3.list()执行1条语句
iterate()----n+1条语句
4.list()直走1级缓存
 iterate()-走2级缓存
5.list()直接去数据库查询数据
 iterate()先去1级缓存查看,是否有满足条件的,再去2级缓存查看,若没有满足条件的,进入数据库查询。---减少访问数据库的次



例子1:
Iterator<Users> iter=query.iterate();
while(iter.hasNext()){//光标在上一行,判断下一行有没有。
Users user=iter.next();
System.out.println(user.toString());
}
例子2: ArrayList<Users> list=(ArrayList<Users>) query.list();//1.
ArrayList<Users> list=(ArrayList<Users>) session.createQuery("from Users").list();//2.
for(Users user:list){
System.out.println(user.toString());
}
【from 实体类名 where 属性=?order by id desc】
 
5.动态查询
--需求根据用户输入的查询条件个数,进行动态拼接查询
1.新建一个javaBean
2.
3.处理不确定条件个数是使用
query.setProperties(pv);
---两种方案,进行数据封装
map集合
javaBean工具类

6.query对象的特殊方法:针对某些功能,查询更方便。
uniqueResult():根据hql查询条件,进行查询,只返回单个对象。
---条件:必须保证查询后的结果只有一条数据,否则报错。
setMaxResults():控制查询的个数

----一起组合使用
Users user=(Users) query.setMaxResults(1).uniqueResult(); 

setFirstResult(i);//数据查询的起始位置,i表示从数据的第i+1条开始查询。(数据下标从0开始)
例子:
ArrayList<Users> list=(ArrayList<Users>) query.setMaxResults(3).setFirstResult(2).list();

分页查询
总条数
总页数
每页显示条数
当前页数
每页显示的信息集合
8.投影查询 select 列名1,列名 from 表
定义:
只查询实例对象一个或多个属性,这种查询叫投影查询。
--破坏类对象的完整性。
1种:object类型--查询一个属性的时。
例子:
1...
Session session=HibernateUtil.currentSession();
String hql="select u.username from Users u";
Query query=session.createQuery(hql);
Object obj=(Object) query.setMaxResults(1).uniqueResult();
System.out.println(obj);
2种:object[]类型---查询多个属性时。
例子:
2...
Session session=HibernateUtil.currentSession();
String hql="select u.username,u.id from Users u";
Query query=session.createQuery(hql);
Object[] obj=(Object[]) query.setMaxResults(1).uniqueResult();
System.out.println(obj[0]+":"+obj[1]);
3种:object类型--通过构造函数。
3...
Session session=HibernateUtil.currentSession();
String hql="select new Users(u.id,u.username,u.truename) from Users u";
Query query=session.createQuery(hql);
List<Users> list=(List<Users>)query.list();
for(Users user :list){
System.out.println(user.toString());
}
9.规定Dao层


延迟加载 load 
get是立即加载策略
类级别的查询策略
--在映射文件中设置:lazy="true" 延迟加载;false 为立即加载。

Query的返回值方法
1.查询语句返回多条数据时候,list()。Iterator();
--返回对应集合或者单个变量。
2.查询语句返回个数或者数据是单条数据uniqueResults();
---返回对应的单个对象或者单个变量
3.增,删,改,语句,executeQpdate();


session执行增删改查
1.查询【只能根据主键id获得单个对象】 get(),load()
2.增加;save();
3.修改: update();
4.查询:


all 返回所有记录
any 返回任意一条
some 和any意义
in 与=any意思相同
exists 至少返回一条记录

命名查询语句是在映射文件中



Criteria 查询
原生sql查询:
Query,hql查询:依赖字符串实现查询。

查询全部:
Criteria criteria=session.createCriteria(Department.class);
List<Department> deps=criteria.list();
for(Department dep:deps){
System.out.println(dep.getDid()+" "+dep.getDname()+" "+dep.getLoc());
Iterator it=dep.getEmps().iterator();
while(it.hasNext()){
Employee emp=(Employee) it.next();
System.out.println(emp.getEname());
}
}
条件查询:
例子1:
Criteria criteria=session.createCriteria(Employee.class);
Criterion criterion=Restrictions.eq("ename", "木木");
criteria.add(criterion);
criteria.add(Restrictions.eq("eid",2));
List<Employee> emps=criteria.list();//criteria.setMaxResults(1).uniqueResult();返回单个对象。
for(Employee emp:emps){
System.out.println(emp.getEname()+" "+emp.getJob());
}
例子2:
Criteria criteria=session.createCriteria(Employee.class);
criteria.add(Restrictions.gt("eid", 2));//编号大于2的员工,eid为类的属性。
【空判断】
criteria.add(Restrictions.isNull("comm"));//comm为空的员工,空判断。
【范围运算】
criteria.add(Restrictions.between("sal", 2500f, 5000f));//范围判断。
List<Employee> emps=criteria.list();
for(Employee emp:emps){
System.out.println(emp.getEname()+" "+emp.getJob());
}
例子3:
List<String> objs=new ArrayList<String>();
objs.add("教授");
objs.add("普通员工");
List<Employee> emps=criteria.add(Restrictions.in("job", objs)).list();
for(Employee emp:emps){
System.out.println(emp.getEname()+" "+emp.getJob()+" "+emp.getSal());
}
例子4:

Criteria criteria=session.createCriteria(Employee.class);
// criteria.add(Restrictions.eq("job","emp").ignoreCase());//对于job属性值为emp,忽略大小写。
【字符串匹配】
// criteria.add(Restrictions.like("ename", "%张%"));//like 返回类型为 sestrictions
// criteria.add(Restrictions.ilike("ename", "%张%"));//ilke 返回类型为Criterion
// criteria.add(Restrictions.and(Restrictions.gt("eid",2), //逻辑运算 and
Restrictions.eq("job", "emp")));
criteria.add(Restrictions.or(Restrictions.gt("eid",2), //逻辑运算or
Restrictions.eq("job", "emp")));
List<Employee> emps=criteria.list();
for(Employee emp:emps){
System.out.println(emp.getEid()+" "+emp.getEname()+" "+emp.getJob()+" "+emp.getSal());
}

例子5:
public static Criteria t1(Employee emp){
Criteria criteria=session.createCriteria(Employee.class);
if(emp.getEid()>0){
criteria.add(Restrictions.eq("eid", emp.getEid()));
}
if(null!=emp.getEname()){
criteria.add(Restrictions.eq("ename", emp.getEname()));
}

return criteria;

}
---方法调用
Employee emp=new Employee();
emp.setEid(0);
emp.setEname("张三");
t1(emp);
List<Employee> emps=t1(emp).list();
for(Employee em:emps){
System.out.println(em.getEname()+","+em.getEid());
}
HibernateUtil.closeSession();

分页查询:
public static EmployeeDaoimpl empimpl=new EmployeeDaoimpl();
public static void main(String[] args) {
// TODO Auto-generated method stub
ParamValues pv=new ParamValues();
pv.setInfo_count(empimpl.sel_info_count());
pv.setShow_count(3);
int page_count=pv.getPage_count();
for(int i=1;i<=page_count;i++){
System.out.println("总共"+page_count+"页");
System.out.println("当前第"+i+"页");
pv.setShow_index(i);
pv.setList(empimpl.sel_info_List(pv, pv.getShow_count(), (pv.getShow_index()-1)*pv.getShow_count()));
for(Employee emp :pv.getList()){
System.out.println(emp.getEname()+","+emp.getJob()+","+emp.getSal());
}
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
排序查询
Session session=HibernateUtil.currentSession();
Criteria criteria=session.createCriteria(Employee.class);
criteria.addOrder(Order.desc("eid"));//降序。
List<Employee> emps=criteria.list();
for(Employee emp :emps){
System.out.println(emp.getEname()+emp.getEid());
}


例子6:
Criteria criteria=session.createCriteria(Employee.class);
criteria.createAlias("dep", "d")
.add(Restrictions.eq("d.dname", "弑神部门"));
// criteria.createCriteria("dep");
criteria.addOrder(Order.desc("eid"));
List<Employee> emps=criteria.list();
for(Employee emp :emps){
System.out.println(emp.getEname()+","+emp.getEid()+","+emp.getDep().getDname());
}

query查询       Criteria查询
list()       支持支持
Iterator()   支持 不支持


投影查询:
例子7:
【单个属性查询】
Session session=HibernateUtil.currentSession();
Criteria criteria=session.createCriteria(Employee.class);
criteria.setProjection(Property.forName("ename"));
List<String> list=criteria.list();
for(String emp:list){
System.out.println(emp);
}
返回List<String/Object>
【多个属性查询】
Criteria criteria=session.createCriteria(Employee.class);
criteria.setProjection(Projections.projectionList()
.add(Property.forName("ename"))
.add(Property.forName("job"))
.add(Property.forName("d.dname"))
);
criteria.createAlias("dep", "d");//要查询部门名称,需要这一句。
List<Object[]> list=criteria.list();
for(Object[] obj:list){
System.out.println(obj[0]+","+obj[1]+","+obj[2]);
}
返回List<Object[]>

使用注解的步骤:
1.添加项目的hibernate环境支持
2.添加工具包。
configuration = new Configuration().configure();
修改为:
configuration=new AnnotationConfiguration().configure();
3.新建实体类
配置注解:
Department.java
@Entity
@Table(name="department")
public class Department implements java.io.Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)//--主键,自增。
@Column(name="did")//-----对应表中的列
private int did;
@Column(name="dname")
private String dname;
@Column(name="loc")
private String loc;
@OneToMany (mappedBy="dep" ,cascade={CascadeType.ALL})//关系,mappedBy的dep为属性。
private Set<Employee> emps=new HashSet<Employee>();
others ....此处省略
}
Employee.java
@Entity
@Table(name="employee")
public class Employee implements java.io.Serializable{
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="eid")
private int eid;
@Column(name="ename")
private String ename;
@Column(name="job")
private String job;
@ManyToOne
@JoinColumn(name="did")
private Department dep;
others.....此处省略
}
4.在核心配置文件hibernate.cfg.xml。添加映射文件。
<mapping class="org.ecjtu.entity.Department"/>
<mapping class="org.ecjtu.entity.Employee"/>

类和类之间的关联关系
:建立类关联关系的两个类,从当前对象可以导航另一个对象的属性或集合
单向:只配置一个类
双向:配置双方的类


多对一
一对一
多对多


表和表之间:就只有多对一


2.配置《单向 多对一关联关系》
1).对员工实体类进行修改
去掉外键属性,改为部门。-----让部门对象成为员工的属性
//private Integer did;
private department dep;
2).修改员工的映射文件
3).使用‘单向’
3.配置《双向 多对一关联关系》
1.一的一方实体类改动
添加set集合(元素不能重复)
private set<Employee> emp;
2.
<set name="employees" inverse="false">
            <key>
                <column name="did" />
            </key>
            <one-to-many class="org.ecjtu.entity.Employee" />
        </set>
3.使用
4.<set>标签的几个特殊属性:
cascade:配置要不要级联。
none: 默认,忽略关联关系对象
save-update:级联保存修改
all: 级联所有(save_update,delete)
delete: 级联删除
A:
Department dep=new Department();
dep.setDname("市场部4");
dep.setEmployees(new HashSet<Employee>());
session.save(dep);
B:
针对部门的删除
cascade="none"
当删除部门时,不会删除相关联的员工。
cascade="delete"
当删除部门时,相关联的员工也会删除。外键设为null。


inverse:默认为false
false表示需要维护外键,当修改的时候会同步修改。进行update语句。
true,表示维护。
----表示在双向多对一关联关系中,一得一方是否负责维护关联关系。
----维护什么?维护子表中的外键/多的一方中的外键属性。
----怎么维护?当一的一方的主键发生添加/删除时,要通知多的一方进行更改。
----不建议一得一方进行维护,inverse属性为假。
1.产生类sql冗余,会多执行很多没有意义的update操作。
2.当字表中的外键不为空时,会抛出异常。
order-by:对set标签集合中的结果进行排序

5.配置《双向 多对多关联关系》
---注意:需要第三张表。

更改两个实体类。



















 
 
 
 
 
 
  
0 0
原创粉丝点击