hibernate学习笔记6--Criteria查询方式、完整小练习(开发步骤)

时间:2022-09-02 13:43:37

一、Criteria查询方式
没有sql语了,因此更加面向对象一些。
Criteria是一种比HQL更面向对象的查询方式;Criteria的创建方式:
 Criteria c = s.createCriteria(DomainClass.class);
 简单属性条件如:c.add(Restrictions.eq(propertyName, name));
 c.add(Restrictions.eqProperty(propertyName, otherpropertyName));

  1. package cn.itcast.hibernate;
  2. import java.util.Date;
  3. import java.util.List;
  4. import org.hibernate.Criteria;
  5. import org.hibernate.Session;
  6. import org.hibernate.criterion.Restrictions;
  7. import cn.itcast.hibernate.domain.User;
  8. public class Cri {
  9. /**
  10. * 使用Criteria根据name查询方法
  11. * @param entity
  12. */
  13. public static void Cri(String name){
  14. Session s = null;
  15. try {
  16. s=HIbernateUtil.getSession();
  17. //使用Criteria接口
  18. Criteria c = s.createCriteria(User.class);
  19. //对查询添加限制条件,相当于where子句。"name"必须是类中具有的属性
  20. //Criteria相当于一个容器,约束可以一直加
  21. c.add(Restrictions.eq("name", name)); //等于
  22. //          c.add(Restrictions.gt("birthday",new Date())); // 大于
  23. c.add(Restrictions.lt("birthday",new Date())); // 小于
  24. //以上条件之间是and的连接方式,当然也可以用一下的or连接方式
  25. //          c.add(Restrictions.or(lhs, rhs));or 两个条件
  26. //Criteria实现分页,hql的方法名基本相同
  27. c.setFirstResult(0);// 从哪条开始取
  28. c.setMaxResults(10);// 共取多少条
  29. List<User> list=c.list(); //executQuery();
  30. for(User user:list){
  31. System.out.print(user.getName());
  32. }
  33. //如果确定数据最多只有一条,可以使用一下的方法简化代码
  34. User u= (User)c.uniqueResult();
  35. System.out.print("只有一条数据"+u.getName());
  36. } finally {
  37. if(s!=null){
  38. s.close();
  39. }
  40. }
  41. }
  42. /**
  43. * @param args
  44. */
  45. public static void main(String[] args) {
  46. Cri("你妹");
  47. }
  48. }

二、小练习(一个各层的完整开发步骤)

1.完整开发步骤

hibernate学习笔记6--Criteria查询方式、完整小练习(开发步骤)

2.实现功能(实现接口方法)

hibernate学习笔记6--Criteria查询方式、完整小练习(开发步骤)

下面具体例子代码:

接口类:

  1. package cn.itcast.dao;
  2. import cn.itcast.domain.User;
  3. public interface UserDao {
  4. public void saveUser(User user);
  5. public User findUserByName(String name);
  6. public User findUserById(int id);
  7. public void updateUser(User user);
  8. public void remove(User user);
  9. }

工具类:获取session

  1. package cn.itcast.dao;
  2. import org.hibernate.Session;
  3. import org.hibernate.SessionFactory;
  4. import org.hibernate.cfg.Configuration;
  5. /**
  6. *(1)不想让其他类继承工具类
  7. *(2)不能让它创建对象,所以属性全部private,还得有个private的无参数构造
  8. * @author Mars
  9. *
  10. */
  11. public final class HibernateUtil {
  12. private static SessionFactory sessionFactory;
  13. private HibernateUtil(){
  14. }
  15. /**
  16. * 细节1:Configuration:是一个配置类
  17. * Configuration的对象会找hibernate.cfg.xml,完成hibernate的初始化
  18. *
  19. * 细节2:hibernate的配置文件有两种hibernate.cfg.xml和hibernate.properties
  20. * 两种存在一种即可,当然如果都存在的话,hibernate.cfg.xml中的配置信息会覆盖hibernate.properties的配置信息
  21. */
  22. static{
  23. //1。读取并解析配置文件
  24. Configuration cfg = new Configuration();
  25. //如果hibernate.cfg.xml不是放在类路径下,就需要此时指定路径
  26. //cfg.configure("filename");
  27. cfg.configure();
  28. //可以使用代码来设置配置信息,但是不便于管理,不建议使用
  29. //cfg.setProperty("hibernate.connection.driver_class", "oracle.jdbc.driver.OracleDriver");
  30. //2。读取并解析映射信息,创建SessionFactory
  31. //所有的配置信息都可以在SessionFactory中找到,映射文件的信息都能找到
  32. sessionFactory = cfg.buildSessionFactory();
  33. }
  34. /**
  35. * 获取session
  36. * @return
  37. */
  38. public static Session getSession(){
  39. //  3。打开Session
  40. return sessionFactory.openSession();
  41. }
  42. /**
  43. * 获取SessionFactory对象
  44. * @return
  45. */
  46. public static SessionFactory getSessionFactory(){
  47. return sessionFactory;
  48. }
  49. }

接口的实现类:

  1. package cn.itcast.dao.imp;
  2. import org.hibernate.Criteria;
  3. import org.hibernate.Query;
  4. import org.hibernate.Session;
  5. import org.hibernate.Transaction;
  6. import org.hibernate.criterion.Restrictions;
  7. import cn.itcast.dao.HibernateUtil;
  8. import cn.itcast.dao.UserDao;
  9. import cn.itcast.domain.User;
  10. public class UserDaoHibernateImpl implements UserDao {
  11. /**
  12. * 根据id查询user
  13. */
  14. public User findUserById(int id) {
  15. //因为是查询所以可以不用开启事务
  16. Session s = null;
  17. try {
  18. s = HibernateUtil.getSession();
  19. //User.class不可随便放,必须靠这个指定来找相应的映射文件
  20. //此处不能使用懒加载s.load(arg0, arg1),会报错,详见后续文章
  21. User user = (User)s.get(User.class, id);
  22. return user;
  23. } finally {
  24. if(s!=null){
  25. s.close();
  26. }
  27. }
  28. }
  29. /**
  30. * 根据姓名获取user
  31. */
  32. public User findUserByName(String name) {
  33. Session s = null;
  34. try {
  35. s=HibernateUtil.getSession();
  36. Criteria c =  s.createCriteria(User.class);
  37. c.add(Restrictions.eq("name", name));
  38. User user = (User)c.uniqueResult();
  39. return user;
  40. } finally{
  41. if(s!=null){
  42. s.close();
  43. }
  44. }
  45. }
  46. /**
  47. * 通过hql根据姓名获取user
  48. */
  49. public User findUserByNamehql(String name) {
  50. Session s = null;
  51. try {
  52. s=HibernateUtil.getSession();
  53. String hql = "from User as user where user.name=:n";
  54. Query q =  s.createQuery(hql);
  55. q.setString("n",name);
  56. User user = (User)q.uniqueResult();
  57. return user;
  58. } finally{
  59. if(s!=null){
  60. s.close();
  61. }
  62. }
  63. }
  64. /**
  65. * 删除方法:必须开启事务
  66. */
  67. public void remove(User user) {
  68. Session s = null;
  69. Transaction tx =null;
  70. try {
  71. s=HibernateUtil.getSession();
  72. tx=s.beginTransaction();
  73. s.delete(user);
  74. tx.commit();
  75. } finally{
  76. if(s!=null){
  77. s.close();
  78. }
  79. }
  80. }
  81. /**
  82. * 删除方法测试:只穿id的话能否成功删除
  83. */
  84. public void remove(int id) {
  85. Session s = null;
  86. Transaction tx =null;
  87. User user = new User();
  88. user.setId(id);
  89. try {
  90. s=HibernateUtil.getSession();
  91. tx=s.beginTransaction();
  92. s.delete(user);
  93. tx.commit();
  94. } finally{
  95. if(s!=null){
  96. s.close();
  97. }
  98. }
  99. }
  100. /**
  101. * 保存对象
  102. */
  103. public void saveUser(User user) {
  104. Session s = null;
  105. Transaction tx =null;
  106. try {
  107. s=HibernateUtil.getSession();
  108. tx=s.beginTransaction();
  109. s.save(user);
  110. tx.commit();
  111. } finally{
  112. if(s!=null){
  113. s.close();
  114. }
  115. }
  116. }
  117. /**
  118. * 更新对象
  119. */
  120. public void updateUser(User user) {
  121. Session s = null;
  122. Transaction tx =null;
  123. try {
  124. s=HibernateUtil.getSession();
  125. tx=s.beginTransaction();
  126. s.update(user);
  127. tx.commit();
  128. } finally{
  129. if(s!=null){
  130. s.close();
  131. }
  132. }
  133. }
  134. /**
  135. * @param args
  136. */
  137. public static void main(String[] args) {
  138. // TODO Auto-generated method stub
  139. }
  140. }

dimain:

  1. package cn.itcast.domain;
  2. import java.util.Date;
  3. public class User {
  4. private int id;
  5. private String name;
  6. private Date birthday;
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public String getName() {
  14. return name;
  15. }
  16. public void setName(String name) {
  17. this.name = name;
  18. }
  19. public Date getBirthday() {
  20. return birthday;
  21. }
  22. public void setBirthday(Date birthday) {
  23. this.birthday = birthday;
  24. }
  25. }

映射文件:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE hibernate-mapping PUBLIC
  3. "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
  4. "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
  5. <hibernate-mapping package="cn.itcast.domain">
  6. <class name="User" table="tb_user">
  7. <!-- 对象标示符,类型可以不写,hibernate自己识别 -->
  8. <id name="id" column="id">
  9. <!-- 指定主键生成方式。
  10. native根据方言判定生成主键的方式
  11. -->
  12. <generator class="native"/>
  13. </id>
  14. <property name="name" column="name" unique="true" not-null="true"/><!--标示name唯一性,非空的限制 -->
  15. <property name="birthday"  />
  16. </class>
  17. </hibernate-mapping>

下面就是简单粗暴的测试类:

  1. package cn.itcast;
  2. import java.util.Date;
  3. import cn.itcast.dao.UserDao;
  4. import cn.itcast.dao.imp.UserDaoHibernateImpl;
  5. import cn.itcast.domain.User;
  6. public class DaoText {
  7. /**
  8. * 模拟业务逻辑层在使用数据访问层的东西
  9. */
  10. public static void main(String[] args) {
  11. UserDao dao = new UserDaoHibernateImpl();
  12. UserDaoHibernateImpl daoimp = new UserDaoHibernateImpl();
  13. User user = new User();
  14. user.setName("nimei");
  15. user.setBirthday(new Date());
  16. System.out.println("1111");
  17. dao.saveUser(user);
  18. int id = dao.findUserByName("nimei").getId();
  19. System.out.println("id: "+id);
  20. user.setName("new name");
  21. System.out.println("2222");
  22. dao.updateUser(user);
  23. //User u = dao.findUserByName(user.getName());
  24. System.out.println("3333");
  25. //dao.remove(user);
  26. //封装的对象只封装如id和非空字段,实施删除测试
  27. //daoimp.remove(id);
  28. //封装的对象只封装如id和非空字段,实施更新测试
  29. User user2 = new User();
  30. user2.setId(id);
  31. user2.setName("涅米");
  32. dao.updateUser(user2);
  33. }
  34. }

备注:

备注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的,对懒加载有影响(可选)