一、Criteria查询方式
没有sql语了,因此更加面向对象一些。
Criteria是一种比HQL更面向对象的查询方式;Criteria的创建方式:
Criteria c = s.createCriteria(DomainClass.class);
简单属性条件如:c.add(Restrictions.eq(propertyName, name));
c.add(Restrictions.eqProperty(propertyName, otherpropertyName));
package cn.itcast.hibernate;
import java.util.Date;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Restrictions;
import cn.itcast.hibernate.domain.User;
public class Cri {
/**
* 使用Criteria根据name查询方法
* @param entity
*/
public static void Cri(String name){
Session s = null;
try {
s=HIbernateUtil.getSession();
//使用Criteria接口
Criteria c = s.createCriteria(User.class);
//对查询添加限制条件,相当于where子句。"name"必须是类中具有的属性
//Criteria相当于一个容器,约束可以一直加
c.add(Restrictions.eq("name", name)); //等于
// c.add(Restrictions.gt("birthday",new Date())); // 大于
c.add(Restrictions.lt("birthday",new Date())); // 小于
//以上条件之间是and的连接方式,当然也可以用一下的or连接方式
// c.add(Restrictions.or(lhs, rhs));or 两个条件
//Criteria实现分页,hql的方法名基本相同
c.setFirstResult(0);// 从哪条开始取
c.setMaxResults(10);// 共取多少条
List<User> list=c.list(); //executQuery();
for(User user:list){
System.out.print(user.getName());
}
//如果确定数据最多只有一条,可以使用一下的方法简化代码
User u= (User)c.uniqueResult();
System.out.print("只有一条数据"+u.getName());
} finally {
if(s!=null){
s.close();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
Cri("你妹");
}
}
二、小练习(一个各层的完整开发步骤)
1.完整开发步骤
2.实现功能(实现接口方法)
下面具体例子代码:
接口类:
package cn.itcast.dao;
import cn.itcast.domain.User;
public interface UserDao {
public void saveUser(User user);
public User findUserByName(String name);
public User findUserById(int id);
public void updateUser(User user);
public void remove(User user);
}
工具类:获取session
package cn.itcast.dao;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
*(1)不想让其他类继承工具类
*(2)不能让它创建对象,所以属性全部private,还得有个private的无参数构造
* @author Mars
*
*/
public final class HibernateUtil {
private static SessionFactory sessionFactory;
private HibernateUtil(){
}
/**
* 细节1:Configuration:是一个配置类
* Configuration的对象会找hibernate.cfg.xml,完成hibernate的初始化
*
* 细节2:hibernate的配置文件有两种hibernate.cfg.xml和hibernate.properties
* 两种存在一种即可,当然如果都存在的话,hibernate.cfg.xml中的配置信息会覆盖hibernate.properties的配置信息
*/
static{
//1。读取并解析配置文件
Configuration cfg = new Configuration();
//如果hibernate.cfg.xml不是放在类路径下,就需要此时指定路径
//cfg.configure("filename");
cfg.configure();
//可以使用代码来设置配置信息,但是不便于管理,不建议使用
//cfg.setProperty("hibernate.connection.driver_class", "oracle.jdbc.driver.OracleDriver");
//2。读取并解析映射信息,创建SessionFactory
//所有的配置信息都可以在SessionFactory中找到,映射文件的信息都能找到
sessionFactory = cfg.buildSessionFactory();
}
/**
* 获取session
* @return
*/
public static Session getSession(){
// 3。打开Session
return sessionFactory.openSession();
}
/**
* 获取SessionFactory对象
* @return
*/
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
}
接口的实现类:
package cn.itcast.dao.imp;
import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Restrictions;
import cn.itcast.dao.HibernateUtil;
import cn.itcast.dao.UserDao;
import cn.itcast.domain.User;
public class UserDaoHibernateImpl implements UserDao {
/**
* 根据id查询user
*/
public User findUserById(int id) {
//因为是查询所以可以不用开启事务
Session s = null;
try {
s = HibernateUtil.getSession();
//User.class不可随便放,必须靠这个指定来找相应的映射文件
//此处不能使用懒加载s.load(arg0, arg1),会报错,详见后续文章
User user = (User)s.get(User.class, id);
return user;
} finally {
if(s!=null){
s.close();
}
}
}
/**
* 根据姓名获取user
*/
public User findUserByName(String name) {
Session s = null;
try {
s=HibernateUtil.getSession();
Criteria c = s.createCriteria(User.class);
c.add(Restrictions.eq("name", name));
User user = (User)c.uniqueResult();
return user;
} finally{
if(s!=null){
s.close();
}
}
}
/**
* 通过hql根据姓名获取user
*/
public User findUserByNamehql(String name) {
Session s = null;
try {
s=HibernateUtil.getSession();
String hql = "from User as user where user.name=:n";
Query q = s.createQuery(hql);
q.setString("n",name);
User user = (User)q.uniqueResult();
return user;
} finally{
if(s!=null){
s.close();
}
}
}
/**
* 删除方法:必须开启事务
*/
public void remove(User user) {
Session s = null;
Transaction tx =null;
try {
s=HibernateUtil.getSession();
tx=s.beginTransaction();
s.delete(user);
tx.commit();
} finally{
if(s!=null){
s.close();
}
}
}
/**
* 删除方法测试:只穿id的话能否成功删除
*/
public void remove(int id) {
Session s = null;
Transaction tx =null;
User user = new User();
user.setId(id);
try {
s=HibernateUtil.getSession();
tx=s.beginTransaction();
s.delete(user);
tx.commit();
} finally{
if(s!=null){
s.close();
}
}
}
/**
* 保存对象
*/
public void saveUser(User user) {
Session s = null;
Transaction tx =null;
try {
s=HibernateUtil.getSession();
tx=s.beginTransaction();
s.save(user);
tx.commit();
} finally{
if(s!=null){
s.close();
}
}
}
/**
* 更新对象
*/
public void updateUser(User user) {
Session s = null;
Transaction tx =null;
try {
s=HibernateUtil.getSession();
tx=s.beginTransaction();
s.update(user);
tx.commit();
} finally{
if(s!=null){
s.close();
}
}
}
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
}
}
dimain:
package cn.itcast.domain;
import java.util.Date;
public class User {
private int id;
private String name;
private Date birthday;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
}
映射文件:
<?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 package="cn.itcast.domain">
<class name="User" table="tb_user">
<!-- 对象标示符,类型可以不写,hibernate自己识别 -->
<id name="id" column="id">
<!-- 指定主键生成方式。
native根据方言判定生成主键的方式
-->
<generator class="native"/>
</id>
<property name="name" column="name" unique="true" not-null="true"/><!--标示name唯一性,非空的限制 -->
<property name="birthday" />
</class>
</hibernate-mapping>
下面就是简单粗暴的测试类:
package cn.itcast;
import java.util.Date;
import cn.itcast.dao.UserDao;
import cn.itcast.dao.imp.UserDaoHibernateImpl;
import cn.itcast.domain.User;
public class DaoText {
/**
* 模拟业务逻辑层在使用数据访问层的东西
*/
public static void main(String[] args) {
UserDao dao = new UserDaoHibernateImpl();
UserDaoHibernateImpl daoimp = new UserDaoHibernateImpl();
User user = new User();
user.setName("nimei");
user.setBirthday(new Date());
System.out.println("1111");
dao.saveUser(user);
int id = dao.findUserByName("nimei").getId();
System.out.println("id: "+id);
user.setName("new name");
System.out.println("2222");
dao.updateUser(user);
//User u = dao.findUserByName(user.getName());
System.out.println("3333");
//dao.remove(user);
//封装的对象只封装如id和非空字段,实施删除测试
//daoimp.remove(id);
//封装的对象只封装如id和非空字段,实施更新测试
User user2 = new User();
user2.setId(id);
user2.setName("涅米");
dao.updateUser(user2);
}
}
备注:
备注1:对于方言可以不添加,hibernate在启动时会自行进行测试匹配,一般都能识别出相应的数据库,但是最好还是加上。
<property>节点中的name属性中不要有在结尾处有空格
备注2:hibernante:不再是更新单列,完全面对的是对象,更新就是更新对象状态,删除就删除对象。
所以对于删除来说删除是根据id,只要将id和映射文件中不为空的字段封装入user即可,之后就可以轻松的调用remove();
例如:不满足映射文件
<property name="name" column="name" unique="true" not-null="true"/><!--标示name唯一性 ,非空的限制-->
则运行时报错。
以上有关于删除的规则,更新同样适用
备注3.hibernate对domain Object限制
(1)默认构造方法(必须的)
(2)有无意义的标示符id(主键)(可选)
(3)非fianl的,对懒加载有影响(可选)