论坛首页 Java企业应用论坛

“write less,do more” Hibernate下的JQuery --->HQuery

浏览 19606 次
该帖已经被评为良好帖
作者 正文
   发表时间:2009-04-07  
不错,能讲讲多线程是怎么处理的吗?
0 请登录后投票
   发表时间:2009-04-07   最后修改:2009-04-07
zhenjia 写道
pertghost 写道
QBC 一对多时,多方为EAGER加载,查询一方会有自动全连接的问题 不知道楼主是怎么解决这个问题的?

HQuery里没有用到FetchMode.EAGER 类似这样的代码

setFetchMode("orders",FetchMode.EAGER)   

关联的持久化类全部是
Criteria.createAlias()



关于这个问题,我举个例子:

@Entity
@Table(name = "EDUCATION")
public class Education implements Serializable {
private static final long serialVersionUID = -7255604367478847959L;

private String uuid;
private Employee employee;
private Date date;

/**
* @return the uuid
*/
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "UUID", length = 32)
public String getUuid() {
return uuid;
}
/**
* @param uuid the uuid to set
*/
public void setUuid(String uuid) {
this.uuid = uuid;
}
/**
* @return the employee
*/
@ManyToOne
@JoinColumn(name = "EMPLOYEE_UUID")
public Employee getEmployee() {
return employee;
}
/**
* @param employee the employee to set
*/
public void setEmployee(Employee employee) {
this.employee = employee;
}
/**
* @return the date
*/
@Column(name = "EDU_DATE")
@Temporal(TemporalType.DATE)
public Date getDate() {
return date;
}
/**
* @param date the date to set
*/
public void setDate(Date date) {
this.date = date;
}
}


@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable {
private static final long serialVersionUID = -2543903410221123484L;

private String uuid;
private String name;
private List<Education> educations = new ArrayList<Education>();

/**
* @return the uuid
*/
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "UUID", length = 32)
public String getUuid() {
return uuid;
}

/**
* @param uuid the uuid to set
*/
public void setUuid(String uuid) {
this.uuid = uuid;
}

/**
* @return the name
*/
@Column(name = "NAME")
public String getName() {
return name;
}

/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}

/**
* @return the educations
*/
@OneToMany(fetch=FetchType.EAGER,targetEntity=Education.class)
@JoinColumn(name = "EMPLOYEE_UUID")
public List<Education> getEducations() {
return educations;
}

/**
* @param educations the educations to set
*/
public void setEducations(List<Education> educations) {
this.educations = educations;
}
}

测试代码如下:

public class test {
public static void main(String[] arg) {
try {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();

Employee employee = new Employee();
employee.setName("simon");
session.save(employee);

Education edu1 = new Education();
edu1.setDate(new Date());
edu1.setEmployee(employee);
session.save(edu1);

Education edu2 = new Education();
edu2.setDate(new Date());
edu2.setEmployee(employee);
session.save(edu2);

                                     session.flush();
tx.commit();

Criteria crit = session.createCriteria(Employee.class);
crit.add(Restrictions.eq("name", "simon"));
List<Employee> list = crit.list();

} catch (Exception e) {
e.printStackTrace();
}
}
}

List<Employee> list = crit.list();   这个代码生成的SQL如下,ORACLE 10g的语句

select this_.UUID as UUID0_1_, this_.NAME as NAME0_1_, educations2_.EMPLOYEE_UUID as EMPLOYEE3_3_, educations2_.UUID as UUID3_, educations2_.UUID as UUID1_0_, educations2_.EDU_DATE as EDU2_1_0_, educations2_.EMPLOYEE_UUID as EMPLOYEE3_1_0_ from EMPLOYEE this_, EDUCATION educations2_ where this_.UUID=educations2_.EMPLOYEE_UUID(+) and this_.NAME=?

mySQL 下的语句:
select this_.UUID as UUID0_1_, this_.NAME as NAME0_1_, educations2_.EMPLOYEE_UUID as EMPLOYEE3_3_, educations2_.UUID as UUID3_, educations2_.UUID as UUID1_0_, educations2_.EDU_DATE as EDU2_1_0_, educations2_.EMPLOYEE_UUID as EMPLOYEE3_1_0_ from EMPLOYEE this_ left outer join EDUCATION educations2_ on this_.UUID=educations2_.EMPLOYEE_UUID where this_.NAME='simon'

LIST 结果集有两条记录,这个显然不是我们想要的结果,这个例子在业务层面可能不恰当,但感觉这是一个QBC的处理问题,想请教下,如果有这种EAGER加载的需求,如何用QBC得到正确的结果?
如果是Criteria.createAlias() 这样处理,是不是在查询时先得把所有有关联的对象都要起个别名?


0 请登录后投票
   发表时间:2009-04-07  
pertghost 写道
zhenjia 写道
pertghost 写道
QBC 一对多时,多方为EAGER加载,查询一方会有自动全连接的问题 不知道楼主是怎么解决这个问题的?

HQuery里没有用到FetchMode.EAGER 类似这样的代码

setFetchMode("orders",FetchMode.EAGER)   

关联的持久化类全部是
Criteria.createAlias()



关于这个问题,我举个例子:

@Entity
@Table(name = "EDUCATION")
public class Education implements Serializable {
private static final long serialVersionUID = -7255604367478847959L;

private String uuid;
private Employee employee;
private Date date;

/**
* @return the uuid
*/
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "UUID", length = 32)
public String getUuid() {
return uuid;
}
/**
* @param uuid the uuid to set
*/
public void setUuid(String uuid) {
this.uuid = uuid;
}
/**
* @return the employee
*/
@ManyToOne
@JoinColumn(name = "EMPLOYEE_UUID")
public Employee getEmployee() {
return employee;
}
/**
* @param employee the employee to set
*/
public void setEmployee(Employee employee) {
this.employee = employee;
}
/**
* @return the date
*/
@Column(name = "EDU_DATE")
@Temporal(TemporalType.DATE)
public Date getDate() {
return date;
}
/**
* @param date the date to set
*/
public void setDate(Date date) {
this.date = date;
}
}


@Entity
@Table(name = "EMPLOYEE")
public class Employee implements Serializable {
private static final long serialVersionUID = -2543903410221123484L;

private String uuid;
private String name;
private List<Education> educations = new ArrayList<Education>();

/**
* @return the uuid
*/
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid")
@Column(name = "UUID", length = 32)
public String getUuid() {
return uuid;
}

/**
* @param uuid the uuid to set
*/
public void setUuid(String uuid) {
this.uuid = uuid;
}

/**
* @return the name
*/
@Column(name = "NAME")
public String getName() {
return name;
}

/**
* @param name the name to set
*/
public void setName(String name) {
this.name = name;
}

/**
* @return the educations
*/
@OneToMany(fetch=FetchType.EAGER,targetEntity=Education.class)
@JoinColumn(name = "EMPLOYEE_UUID")
public List<Education> getEducations() {
return educations;
}

/**
* @param educations the educations to set
*/
public void setEducations(List<Education> educations) {
this.educations = educations;
}
}

测试代码如下:

public class test {
public static void main(String[] arg) {
try {
Session session = HibernateUtil.getSession();
Transaction tx = session.beginTransaction();

Employee employee = new Employee();
employee.setName("simon");
session.save(employee);

Education edu1 = new Education();
edu1.setDate(new Date());
edu1.setEmployee(employee);
session.save(edu1);

Education edu2 = new Education();
edu2.setDate(new Date());
edu2.setEmployee(employee);
session.save(edu2);

                                     session.flush();
tx.commit();

Criteria crit = session.createCriteria(Employee.class);
crit.add(Restrictions.eq("name", "simon"));
List<Employee> list = crit.list();

} catch (Exception e) {
e.printStackTrace();
}
}
}

List<Employee> list = crit.list();   这个代码生成的SQL如下,ORACLE 10g的语句

select this_.UUID as UUID0_1_, this_.NAME as NAME0_1_, educations2_.EMPLOYEE_UUID as EMPLOYEE3_3_, educations2_.UUID as UUID3_, educations2_.UUID as UUID1_0_, educations2_.EDU_DATE as EDU2_1_0_, educations2_.EMPLOYEE_UUID as EMPLOYEE3_1_0_ from EMPLOYEE this_, EDUCATION educations2_ where this_.UUID=educations2_.EMPLOYEE_UUID(+) and this_.NAME=?

mySQL 下的语句:
select this_.UUID as UUID0_1_, this_.NAME as NAME0_1_, educations2_.EMPLOYEE_UUID as EMPLOYEE3_3_, educations2_.UUID as UUID3_, educations2_.UUID as UUID1_0_, educations2_.EDU_DATE as EDU2_1_0_, educations2_.EMPLOYEE_UUID as EMPLOYEE3_1_0_ from EMPLOYEE this_ left outer join EDUCATION educations2_ on this_.UUID=educations2_.EMPLOYEE_UUID where this_.NAME='simon'

LIST 结果集有两条记录,这个显然不是我们想要的结果,这个例子在业务层面可能不恰当,但感觉这是一个QBC的处理问题,想请教下,如果有这种EAGER加载的需求,如何用QBC得到正确的结果?
如果是Criteria.createAlias() 这样处理,是不是在查询时先得把所有有关联的对象都要起个别名?



Criteria.createAlias("column","asName",joinType) ;有这样一个方法
你试试。一般 set的我都延迟加载的
0 请登录后投票
   发表时间:2009-04-07  
femto 写道
不错,能讲讲多线程是怎么处理的吗?

保证每个$()操作的是一个属于自己的对象(也就是新的对象) 就好了。
0 请登录后投票
   发表时间:2009-04-08  
减少代码量,偷懒还是真理
0 请登录后投票
   发表时间:2009-04-09  
想法挺有意思的,抽空看看。
0 请登录后投票
   发表时间:2009-04-13   最后修改:2009-04-13
可以简单地认为楼主的所做的工作是jQuery化的通用DAO么?
我认为写两次代码来进行一项查询更新工作和一次写完分别不大,
与其写在一起,不如加入点代码冗余使得耦合更加松散.

另外,由于对数据库同样hit了两次,性能方面是没有改变的
0 请登录后投票
   发表时间:2009-04-14  
兄弟,我看着有点晕啊,不好意思,水平不够!

你的$()是方法吧,如果$是类名,那么构造函数也要用个new $()吧,否则写在java里面,不报错?

这个看不明白:)是不是要将类继承HQuery呢?
0 请登录后投票
   发表时间:2009-04-16  
linliangyi2007 写道
兄弟,我看着有点晕啊,不好意思,水平不够!

你的$()是方法吧,如果$是类名,那么构造函数也要用个new $()吧,否则写在java里面,不报错?

这个看不明白:)是不是要将类继承HQuery呢?

$()是HQuery的方法
是需要继承HQuery然后就会有一系列的支持
据我所知 $可以用做class name method name
0 请登录后投票
   发表时间:2009-04-22  
欣赏LZ的态度,想法不错,LZ加油。

Hibernate Criteria其实是从SQL到relation algebra的回归,把relation algebra实践化了,在思维方式上和结构化的SQL,HQL有所不同。我觉得LZ可以从relation algebra的角度上考虑一下,其实不用完全拘泥于Hibernate的模式。
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics