我正在开发第一个webapp,我将使用hibernate。
我有:
我想要做的是,在我的webapp中有一个表单,用户将输入他们的凭据,然后我会将它们与我在数据库中的内容相匹配。
第一步是通过JSF获取信息==>工作良好。 下一步是查询数据库以检查我有这个用户并且密码是否正确。
对于第二步,我遇到了问题。
这是我正在调用的代码:
public String checkUser() {
/** 1° Query the database for active users with specified name. */
session = helper.getSessionFactory().openSession();
PAC_USERS queryUsr = new PAC_USERS();
session.load(PAC_USERS.class, queryUsr);
session.beginTransaction();
queryUsr.setName(this.name);
this.user = (PAC_USERS) session.get(PAC_USERS.class, queryUsr);
session.close();
return null;
/** 2° verify password against the one stored in the DB. */
}
这是hibernate映射文件:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class catalog="pac" name="com.a3c.pac.jsf.beans.PAC_USERS" table="pac_users">
<id column="id" name="id" type="integer">
<generator class="identity"/>
</id>
<property column="name" name="name" type="string"/>
<property column="password" name="password" type="string"/>
</class>
</hibernate-mapping>
这是我的表的SQL语句:
CREATE TABLE `pac_users` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(45) NOT NULL,
`password` varchar(45) NOT NULL,
`active` int(11) NOT NULL DEFAULT '1',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=latin1$$
我想要的是在PAC_USERS表中查询通过网页提供名称的记录。
PAC_USERS.java类也可以提供帮助,这里是:
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package com.a3c.pac.jsf.beans;
import java.io.Serializable;
/**
*
* @author Utilisateurs
*/
public class PAC_USERS implements Serializable {
private Integer id;
private String name;
private String password;
private Boolean active = false;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Boolean getActive() {
return active;
}
public void setActive(Boolean active) {
this.active = active;
}
}
非常感谢任何建议。
先谢谢。
保重, 马可。
答案 0 :(得分:2)
完全没有理解session.load和session.get的目的。如果你想按名称加载PAC_USERS对象(我甚至不会进入那个命名)那么你就是这样做(假设名称是唯一的):
session = helper.getSessionFactory().openSession();
this.user = (PAC_USERS) session.createQuery( "select u from PAC_USERS u where u.name = :username" )
.setParameter( "username", this.name )
.uniqueResult();
session.close();
但是,这里有很多事情可以做得更好。首先,这似乎是我们称之为每次操作会话的反模式的主要示例,特别是为数据库的每个请求打开和关闭会话。也许它只是这个特定用例的本质,请注意......
接下来,这是@NaturalId(或<natural-id/>
)映射的一个很好的候选者。从4.1开始,Hibernate通过natural-id提供加载实体作为头等公民,与id加载相同。假设您已将名称映射为自然ID,您可以改为:
session = helper.getSessionFactory().openSession();
this.user = (PAC_USERS) session.bySimpleNaturalId( PAC_USERS.class ).load( this.name );
session.close();
最后,如果您对此返回用户所做的只是验证其身份验证凭据,那么最好不要返回实体。或者,直接选择密码并验证:
session = helper.getSessionFactory().openSession();
final String password = (String) session.createQuery( "select u.password from PAC_USERS where u.name = :username" )
.setParameter( "username", this.name )
.uniqueResult();
session.close();
或者只是在查询中执行验证:
session = helper.getSessionFactory().openSession();
final Long matches = (Long) session.createQuery( "select count(*) from PAC_USERS where u.name = :username and u.password = :pswd" )
.setParameter( "username", this.name )
.setParameter( "pswd", this.password )
.uniqueResult();
// count should == 1...
session.close();