zoukankan      html  css  js  c++  java
  • hibernate基础(1)

    hibernate基础
    1.hibernate介绍与动手入门体验
      问题:模型不匹配(java对象模型与数据库关系模型不匹配)
      解决:
     1.使用JDBC手工转换
            2.使用ORM(Object Relation Mapping对象关系映射)框架,有Hibernate,TopLink,OJB
      下载地址http://www.hibernate.org  3.2.5版本
      安装配置:
        配置文件:hibernate.cfg.xml,hibernate.properties 这两个文件作用一样,可以用来指定数据库的URL、用户名、密码、JDBC驱动类、方言等,推荐用xml。
        映射文件:hbm.xml 是对象模型和关系模型的映射

    2.hibernate入门案例的细节分析
         1.由Domain object-->mapping-->db(官方推荐),  知道其中一个导出其余两个
         2.由 db 开始,用工具生成mapping和Domain object(使用较多)
         3.由映射文件开始
       Domain object的限制:
        Domain object不能自定义构造方法,必须使用默认构造方法;
            有序列号(无意义的标识符)id(主键) (可选);
            类是非final的,对懒加载有影响(可选),final类不能被继承。
      映射文件 .hbm.xml
        <? xml version="1.0"?>
        <hibernate-mapping package="xxx.xxx.domain">
          <class name="User" table="user">   //实体类,name 类名,table 表名
              <id name="id" column="id">     //name 是类的属性名,column 列名,id被定义为主键 generator 定义序列号
                  <generator class="native"/>
              </id>
              <property name="name" column="name">  
              <property name="birthday" column="birthday">  
          </class>
        </hibernate-mapping>

    3.hibernate入门案例的代码优化
       初始化hibernate的工具类 HibernateUtil.java 
    package cn.itcast.hibernate;
    import java.io.Serializable;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.Transaction;
    import org.hibernate.cfg.Configuration;

    public final class HibernateUtil {    //final类不允许被继承
     private static SessionFactory sessionFactory;  //私有静态属性
     private static ThreadLocal session = new ThreadLocal();

     private HibernateUtil() {      //私有的构造方法 禁止实例化
     }

     static {                       //static块只会在虚拟机进行加载时被执行一次
      Configuration cfg = new Configuration();
      cfg.configure();       //读取配置文件信息,默认配置文件是"hibernate.cfg.xml"
      sessionFactory = cfg.buildSessionFactory();
     }

     public static Session getThreadLocalSession() {
      Session s = (Session) session.get();
      if (s == null) {
       s = getSession();
       session.set(s);
      }
      return s;
     }

     public static void closeSession() {
      Session s = (Session) session.get();
      if (s != null) {
       s.close();
       session.set(null);
      }
     }

     public static SessionFactory getSessionFactory() {
      return sessionFactory;
     }

     public static Session getSession() {
      return sessionFactory.openSession();
     }
            //数据库操作:增
     public static void add(Object entity) {
      Session s = null;
      Transaction tx = null;
      try {
       s = HibernateUtil.getSession();
       tx = s.beginTransaction();
       s.save(entity);
       tx.commit();
      } finally {                  //确保Session被关闭
       if (s != null)
        s.close();
      }
     }
            //数据库操作:改
     public static void update(Object entity) {
      Session s = null;
      Transaction tx = null;
      try {
       s = HibernateUtil.getSession();
       tx = s.beginTransaction();
       s.update(entity);
       tx.commit();
      } finally {
       if (s != null)
        s.close();
      }
     }
            //数据库操作:删
     public static void delete(Object entity) {
      Session s = null;
      Transaction tx = null;
      try {
       s = HibernateUtil.getSession();
       tx = s.beginTransaction();
       s.delete(entity);
       tx.commit();
      } finally {
       if (s != null)
        s.close();
      }
     }
            //数据库操作:查询    通过主键id查询数据库中一个表的一行信息。Class 对应数据库表 或者 domain中的实体对象类,Serializable 序列号
     public static Object get(Class clazz, Serializable id) {
      Session s = null;
      try {
       s = HibernateUtil.getSession();
       Object obj = s.get(clazz, id);
       return obj;
      } finally {
       if (s != null)
        s.close();
      }
     }
    }

    4.Session接口及get-load-persist方法
      get(),load()都是通过主键查询一个实体对象(数据库中的一行记录),区别在于get()立即执行(加载),load()当只有查询结果被使用时才被执行(称为懒加载)
      save(),persist()都用来保存,区别在于在没开启事务时,save()先插入数据再回滚,persist()不插入数据。

    5.实体对象的三种状态与saveOrUpdate方法
      saveOrUpdate与merge 根据id和version的值来确定是save或update,merge的对象处于脱管状态。
      对象的三种状态:
          瞬时状态(transient):数据库中没有数据与之对应,超出作用域会被jvm垃圾回收器回收,一般是new出来且与session没有关联的对象。
          持久状态(persistent):数据库中有数据与之对应,当前与session有关联,并且相关联的session没有关闭,事务没有提交;持久对象状态发生改变,在事务提交时会影响到数据库(hibernate能够检测到)。
          脱管/游离状态(detached):数据库中有数据与之对应,但当前没有session与之有关联,脱管对象状态发生改变,hibernate不能检测到。
        瞬时状态 通过save()转为 持久状态;脱管/游离状态 通过update()转为 持久状态;如果不清楚对象的状态 通过saveOrUpdate() 由hibernate自动判断更新 并转为持久状态;merge()可以更新,但更新后对象仍是脱管状态。
        unsaved-value="" 通过该属性设置 瞬时状态对象的主键属性值。

    6.完善HibernateUtil类及hql查询入门
      HibernateUtil类代码见上文(3)
      HQL(Hibernate Query Language) 面向对象的查询语言,HQL中查的是对象而不是表,且支持多态,HQL中的对象名是区分大小写的(除了Java类名及其属性名,其余部分不区分大小写)
         Query q=session.createQuery(hql);
            from User    //from Object  将查询数据库中所有的表,因为HQL支持多台,Object是数据库中表对应实体类的父类
            from User user where user.name=?
            from User user where user.name=:name and user.birthday < :birthday
         exp: 
            public static void query(String name) {
      Session s = null;
      try {
       s = HibernateUtil.getSession();
              String hql="from User as user were user.name=?";
                            Query query = s.createQuery(hql);
                            query.setString(0,name);//传入条件参数
                            List<User> list = query.list();//executeQuery()  执行动作
                            for (User user:list) {
                                System.out.println(user.getName());
                             }
      } finally {
       if (s != null)
        s.close();
      }
     }

    7.实体类或属性名与数据库关键字冲突问题
      可以通过调整数据库中的表名及列名进行处理,然后在映射文件 xxx.hbm.xml 增加table="xxx",column="XXX"属性即可
        <? xml version="1.0"?>
        <hibernate-mapping package="xxx.xxx.domain">
          <class name="User" table="user">   //实体类,name 类名,table 表名
              <id name="id" column="id">     //name 是类的属性名,column 列名,id被定义为主键 generator 定义序列号
                  <generator class="native"/>
              </id>
              <property name="name" column="name">  
              <property name="birthday" column="birthday">  
          </class>
        </hibernate-mapping>

    8.hql的命名参数与Query接口的分页查询
            String hql="from User user where user.name=:name and user.birthday < :birthday";
            Query query = s.createQuery(hql);
            query.setString("name",nameuser);//传入命名参数值,优点在于与参数位置无关,调整String hql="...."后参数传入不受影响
            query.setString("birthday",2000-10-01);
            query.setFirstResult(200);//分页方法:起始记录位置
            query.setMaxResults(10);//分页方法:页的最大记录数量,各种数据库用于分页的伪列都相同,通过定义方言来制定使用的是哪个数据库 
         
    9.Criteria查询方式(条件查询)        
      Criteria 是一种比HQL更面向对象的查询方式(官方推荐使用HQL)
         Criteria crit=session.createCriteria(DomainClass.class);
         exp:
             static void cri(String name) {
      Session s = null;
      try {
       s = HibernateUtil.getSession();
                            Criteria c = s.createCriteria(User.class);//传入一个类
                            c.add(Restrictions.eq("name",name));//加入相等关系判断条件,并引入参数
                            c.add(Restrictions.lt("birthday",new Date()));//加入小于关系判断条件,并引入参数
              c.setFirstResult(0);//分页方法:起始记录位置
              c.setMaxResults(10);//分页方法:页的最大记录数量,各种数据库用于分页的伪列都相同,通过定义方言来制定使用的是哪个数据库 
                            List<User> list = c.list();//executeQuery()  执行动作
                            User u = (User) c.uniqueResult();  //执行查询动作,返回结果是一个对象(一行记录)
                            for (User user:list) {
                                System.out.println(user.getName());
                             }
      } finally {
       if (s != null)
        s.close();
      }
             }

    10.使用Hibernate完成CRUD实验的步骤说明
       作业实现UserDao接口(待处理)
           public interface UserDao {
               public void saveUser(User user);//
               public User findUserById(int id);//
               public User findUserByName(String name);//
               public void updateUser(User user);//
        public void remove(User user);//
           }
       步骤:
       1.设计domian对象User
       2.设计UserDao接口
       3.加入hibernate.jar和其依赖的包
       4.编写User.hbm.xml映射文件,可以基于hibernate/eg目录下的org/hibernate/auction/User.hbm.xml修改
       5.编写hibernate.cfg.xml配置文件,可以基于hibernate/ect/hibernate.cfg.xml修改,必须提供的参数有:
         connection.driver_class、connection.url、connection.username、connection.password、dialect、hbm2ddl.auto
       6.编写HibernateUtils类,主要用来完成Hibernate初始化和提供一个获得Session的方法(这步可选)
       7.实现UserDao接口

    11.完成CRUD实验并回顾和补充细节知识(上)
       ctrl+1  import功能
       ctrl+s  保存功能
       com.hoperun.domain.Ouser  类

  • 相关阅读:
    推荐谷歌浏览器12款常用的扩展
    推荐谷歌浏览器12款常用的扩展
    推荐VSCode12个比较实用的插件
    推荐VSCode12个比较实用的插件
    Linux中Shell循环结构for用法笔记
    django之上传图片
    django之中间件设置
    django之admin站点
    django之管理静态文件
    django之设置分页
  • 原文地址:https://www.cnblogs.com/tian830937/p/4420526.html
Copyright © 2011-2022 走看看