zoukankan      html  css  js  c++  java
  • .Net转Java自学之路—Hibernate框架篇二(实体类、API、映射关系)

    实体类编写规则:

      1、实体类中属性私有化。
      2、私有属性使用公开的set()和get()。
      3、要求实体类中有属性作为唯一值。
      4、实体类中属性建议不使用基本数据类型,而使用基本数据类型对应的包装类。
        》八个基本数据类型对应的包装类:
          int>>Integer、char>>Character、其他的都是首字符大写。

    Hibernate主键生成策略:

      1、hibernate要求实体类中有属性作为唯一值,对应表主键,主键可以不同生成策略。
      2、hibernate主键生成策略有很多的值:<generator class="native"></tenerator>
        》native:生成表id值就是主键自动增长。根据使用的数据库选择那个值。
        》uuid:生成长度为32位的十六进制字符串。使用uuid时,实体类对应的uid必须是字符串类型。
        》increment:每次增量为1依次增长。
        》identity:条件是数据库支持自动增长数据类型。
        》sequence:序列。条件是数据库支持序列。如:Oracle

    //查询操作
    SessionFactory factory=HibernateUtils.getSessionFactory();
    Session session=factory.openSession();
    Transaction tx=session.beginTransaction();
    //get()方法:根据id查询
    //第一个参数:实体类的class。第二个参数:id值
    User user = session.get(User.class,1);
    tx.commit();
    session.close();
    factory.close();
    
    
    //修改操作
    SessionFactory factory=HibernateUtils.getSessionFactory();
    Session session=factory.openSession();
    Transaction tx=session.beginTransaction();
    
    User user=session.get(User.class,1);
    user.setUsername("李四");//设置修改的值
    session.update(user);或session.save(user);
    
    tx.commit();
    session.close();
    factory.close();
    
    
    //删除操作
    SessionFactory factory=HibernateUtils.getSessionFactory();
    Session session=factory.openSession();
    Transaction tx=session.beginTransaction();
    
    //第一种方式:
    User user=session.get(User.class,1);
    session.delete(user);
    //第二种方式:
    User user=new User();
    user.setUid(1);
    Session.delete(user);
    
    tx.commit();
    session.close();
    factory.close();
    实例crud

    实体类的三种状态:

      1、瞬时态:对象中没有id值,对象与Session没有关联。
      2、持久态:对象中有id值,对象与Session关联。
      3、托管态:对象中有id值,对象与Session没有关联。

      saveOrUpdate():添加或修改操作。
        当实体类对象状态是瞬时态时,做添加操作。
        当实体类对象状态是托管态时,做修改操作。
        当实体类对象状态是持久态时,做修改操作。

    Hibernate缓存:

      1、Hibernate框架中提供了很多优化的方式。Hibernate的缓存就是一个优化的方式。
      2、Hibernate缓存特点:

        》hibernate的一级缓存:
          > hibernate的一级缓存默认时打开的。
          > hibernate的一级缓存使用范围,是Session的范围。从Session创建到Session关闭的范围。
          > hibernate的一级缓存中,存储数据必须是持久态数据。

        》hibernate的二级缓存:
          > 目前已经不使用了,替代技术redis。
          > 二级缓存默认没有打开,需要配置开启。
          > 二级缓存使用范围,是SessionFactory的范围。

      一级缓存特性:持久态会自动更新数据库。

    Hibernate绑定Session:

      多人开发项目时,为了保证Session的单线程对象的特性。将Session与本地线程绑定即可。

      1、Session类似于jdbc的Connection连接。

      2、与本地线程绑定Session。其实底层就是与ThreadLocal绑定。

      3、获取与本地线程Session:
        》在Hibernate核心配置文件中配置。在第二部分配置<property name="hibernate.current_session_context_class">thread</property>
        》调用SessionFactory中的方法得到。SessionFactory.getCurrentSession();

      4、获取与本地线程绑定Session时,关闭Session会报错,所以不需要手动来关闭Session。

    public class HibernateUtils{
        private static final Configuration cfg=null;
        private static final SessionFactory factory=null;
        static{
            cfg=new Configuration();
            cfg.configure();
            factory=cfg.buildSessionFactory();
        }
        //提供方法返回SessionFactory
        publc static SessionFactory getSessionFactory(){
            return factory;
        }
        //提供返回与本地线程绑定的Session的方法
        public static Session getSessionThread(){
            return factory.getCurrentSession();
        }
    }
    在HibernateUtils中添加得到绑定Session的方法

    Hibernate查询的API使用:

      Query:

        1、使用Query对象,不需要写sql语句,但要写hql语句。
          》hql:hibernate query language。Hibernate提供的查询语言。hql语句与普通sql语句很相似。
          》hql和sql语句区别:使用sql操作表和表字段。使用hql操作实体类和属性。

        2、查询所有hql语句。from 实体类名称

        3、Query对象使用:
          》创建Query对象:Query query = session.createQuery("from User");
          》调用Query对象中的方法得到结果:List<User> list = query.list();

      Criteria:

        1、使用该对象查询操作,但hi使用该对象时,不需要写语句,直接调用方法即可。

        2、实现过程:
          》创建Criteria对象:Criteria criteria = session.createCriteria(User.class);
          》调用对象中的方法得到结果:List<User> list=criteria.list();

      SQLQuery:

        1、使用hibernate时,调用底层SQL实现。

        2、实现过程:
          》创建对象:SQLQuery query = session.createSQLQuery("sql语句");
          》调用对象的方法得到结果:
            > List<Object[]> list = query.list();返回list集合,默认里面的每部分是数组结构。

            > query.addEntity(User.class);设置将数据放到实体类中。
             
    List<User> list=query.list();返回list集合,每部分是对象的形式。

    Hibernate的一对多映射:

      一对多映射配置:

        1、创建一和多的实体类。(暂用OnlyClass和MoreClass表示)

        2、让俩个实体类之间相互表示。
          》在Hibernate中要求使用set集合表示多的数据。
          》在OnlyClass中定义自身属性后,还需要定义一个set集合来表示MoreClass的属性。
          》在MoreClass中定义自身属性后,还需要定义一个表示OnlyClass的属性。

        3、配置映射关系:
          》一般一个实体类对应一个映射文件。
          》完成映射最基本的配置。
          》在映射文件中,配置一对多关系。配置OnlyClass.hbm.xml的一对多关系使用set标签表示。
            set标签中的name属性:属性值写在OnlyClass实体类中表示MoreClass的set集合名称。

    <class>
      <set name="setMoreClass">
          <!--一对多的建表,需要使用外键来建立关系
              Hibernate机制:双向维护外键,
            在一和多的双方都配置外键
               column的属性值:外键名称-->
          <key column="mcid"></key>
          <!--在一的一方需要使用one-to-many标签:
              class属性值:MoreClass实体类全路径-->
          <one-to-many class="cn.test.xx.MoreClass"/>
      </set>
    </class>

            配置MoreClass.hbm.cml 表示所属的OnlyClass。name属性:在MoreClass实体类中的OnlyClass名称。class属性:OnlyClass全路路径。column属性:外键名称(和OnlyClass中配置的外键名称保持一致)。

    <class>
      <many-to-one name="onlyClass"  class="cn.test.xx.OnlyClass" column="mcid"></many-to-one>
    </class>

        4、创建核心配置文件,把映射文件引入到核心配置文件中。

    SessionFactory factory = HibernateUtils.getSessionFactory();
    Session session=factory.openSession();
    Transaction tx=session.beginTransaction();
    //创建对象。
    OnlyClass onlyClass=new OnlyClass();
    onlyClass.setXXX("xxx");
    onlyClass.setXXX("xxx");
    ......
    
    MoreClass moreClass=new MoreClass();
    moreClass.setXXX("xxx");
    moreClass.setXXX("xxx");
    ......
    //建立OnlyClass与MoreClass关系。
    //把MoreClass对象放到OnlyClass对象的set集合中。
    onlyClass.getSetMoreClass().add(moreClass);
    //把OnlyClass对象放到MoreClass对象的set集合中。
    moreClass.setOnlyClass(onlyClass);
    
    //保存到数据库
    session.save(onlyClass);
    session.save(moreClass);
    
    tx.commit();
    session.close();
    factory.close();
    一对多级联操作:级联保存

      简化写法:

        1、在一OnlyClass的映射文件OnlyClass.hbm.xml中进行配置。在set标签中添加属性cascade="save-update"

    <set name="setMoreClass" cascade="save-update">

        2、常见一和多的对象,只需要把多的对象放到一中。最终只需要保存一即可。

    SessionFactory factory = HibernateUtils.getSessionFactory();
    Session session=factory.openSession();
    Transaction tx=session.beginTransaction();
    //创建对象。
    OnlyClass onlyClass=new OnlyClass();
    onlyClass.setXXX("xxx");
    onlyClass.setXXX("xxx");
    ......
    
    MoreClass moreClass=new MoreClass();
    moreClass.setXXX("xxx");
    moreClass.setXXX("xxx");
    ......
    //把MoreClass对象放到OnlyClass对象中。
    onlyClass.getSetMoreClass().add(moreClass);
    
    //保存到数据库
    session.save(onlyClass);
    
    tx.commit();
    session.close();
    factory.close();
    一对多级联操作:级联保存

    级联删除:

      在删除一中的数据时,需要先删除多里面的数据。

      1、先在OnlyClass映射文件set标签,进行配置。使用属性cascade="delete"

    <set name="setMoreClass" cascade="save-update,delete">

      2、执行过程:根据id查询OnlyClass的内容;再根据外键查询MoreClass的内容;将MoreClass的外键设置为null值;删除MoreClass的数据;删除OnlyClass的数据。

      3、代码实现:

    SessionFactory factory = HibernateUtils.getSessionFactory();
    Session session=factory.openSession();
    Transaction tx=session.beginTransaction();
    
    OnlyClass only=session.get(OnlyClass.class,11);
    session.delete(only);
    
    tx.commit();
    session.close();
    factory.close();
    SessionFactory factory = HibernateUtils.getSessionFactory();
    Session session=factory.openSession();
    Transaction tx=session.beginTransaction();
    
    //根据id查询MoreClass的一条数据
    MoreClass more=session.get(MoreClass.class,2)
    //根据id查询OnlyClass的一条数据
    OnlyClass only=session.get(OnlyClass.class,5);
    //设置持久态对象值:把MoreClass放到OnlyClass中
    only.getSetMoreClass().add(more);
    //把OnlyClass放到MoreClass中。即可完成修改
    more.setOnlyClass(only);
    
    tx.commit();
    session.close();
    factory.close();
    一对多级联操作:修改

      inverse属性:因为Hibernate是双向维护外键,所以会修改俩次外键,从而性能不是很高,造成了效率问题。
        解决方式:让其中的一方不维护外键。一对多中,让一OnlyClass放弃。
        实现:在放弃关系维护的映射文件中,进行配置,在set标签上使用inverse属性。inverse的默认值为false(不放弃关系维护)。而true表示放弃关系维护。

    <set name="setMoreClass" cascade="save-update,delete" inverse="true">

    Hibernate多对多映射:

      多对多映射配置:以用户(User)和角色(Role)为例。

      1、创建实体类。

      2、让俩个实体相互表示。
        一个用户中表示所有角色,使用set集合。

    private Set<Role> role=new HashSet<Role>();
    
    public Set<Role> getRole() {
        return role;
    }
    
    public void setRole(Set<Role> role) {
        this.role = role;
    }

        一个角色有多个用户,使用set集合。

    private Set<User> user=new HashSet<User>();
    
    public Set<User> getUser() {
        return user;
    }
    
    public void setUser(Set<User> user) {
        this.user = user;
    }

      3、配置映射关系:基本配置和配置多对多关系<set>标签。

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="cn.test.entity.User" table="t_user">
            <id name="u_id" column="u_id">
                <generator class="native"></generator>
            </id>
            <property name="u_uname" column="u_uname"></property>
            <property name="u_pwd" column="u_pwd"></property>
            <property name="u_email" column="u_email"></property>
            <property name="u_address" column="u_address"></property>
            <!--t_user_role是t_user和t_role的关系表-->
            <set name="role" table="t_user_role" cascade="save-update,delete">
                <!--key标签中配置当前映射文件第三张表外键名称-->
                <key column="uid"></key>
                <!--class:实体类全路径。column:角色在第三张表外键名称-->
                <many-to-many class="cn.test.entity.Role" column="rid"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>
    User.hbm.xml的配置
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    <hibernate-mapping>
        <class name="cn.test.entity.Role" table="t_role">
            <id name="r_id" column="r_id">
                <generator class="native"></generator>
            </id>
            <property name="r_rname" column="r_rname"></property>
            <property name="r_memo" column="r_memo"></property>
            <!--t_user_role是t_user和t_role的关系表-->
            <set name="user" table="t_user_role">
                <!--key标签中配置当前映射文件第三张表外键名称-->
                <key column="rid"></key>
                <!--class:实体类全路径。column:角色在第三张表外键名称-->
                <many-to-many class="cn.test.entity.User" column="uid"></many-to-many>
            </set>
        </class>
    </hibernate-mapping>
    Role.hbm.xml的配置

      4、在核心配置文件中引入映射文件。

    <?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD//EN"
            "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
    <hibernate-configuration>
        <session-factory>
            <property name="connection.url">jdbc:mysql://localhost:3306/Test</property>
            <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="connection.username">root</property>
            <property name="connection.password">root123456</property>
    
            <property name="hibernate.show_sql">true</property>
            <property name="hibernate.format_sql">true</property>
            <property name="hibernate.hbm2ddl.auto">update</property>
            <!-- <property name="hbm2ddl.auto">update</property> -->
            <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
            <mapping resource="cn/test/entity/User.hbm.xml"/>
            <mapping resource="cn/test/entity/Role.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>
    核心配置文件

      级联保存:

        1、再User配置文件中set标签进行配置,cascade值save-update

        2、实现:创建User、Role对象,把角色放到用户中,最终保存用户即可。

    SessionFactory factory=HibernateUtils.getSessionFactory();
    Session session=factory.openSession();
    Transaction tx=session.beginTransaction();
    
    User user1=new User();
    user1.setUsername("zhangsan");
    .....
    User user2=new User();
    user3.setUsername("lisi");
    .....
    Role role1=new Role();
    role1.setR_rname("管理员");
    .....
    Role role2=new Role();
    role2.setR_rname("普通用户");
    .....
    
    User1.getRole().add(role1);
    User1.getRole().add(role2);
    User2.getRole().add(role2);
    
    session.save(user1);
    session.save(user2);
    
    tx.commit;
    View Code

      级联删除:

    User user=session.get(User.class,1);
    session.delete(user);

      维护第三张表:

        1、通过第三张表t_user_role来维护用户和角色多对多的关系。

        2、让某用户有某角色:
          》根据id查询用户和角色

    User user=session.get(User.class,2);
    Role role=session.get(Role.class,1);

          》把角色放到用户的set集合中:

    user.getRole().add(role);

        3、让某用户没有某角色:

    User user=session.get(User.class,2);
    Role role=session.get(Role.class,1);
    user.getRole().remove(role);
  • 相关阅读:
    命令窗口
    文件压缩,文件夹压缩
    objectarx之工具
    Quick Search Articles in My Blog
    Draw graph(network) with nx_pydot in networkx
    How to Share Wired Internet Via Wi-Fi and Vice Versa on Linux
    Deluge: Enables BT download on your Raspberry Pi
    你还在想用 nextCloud 自建NAS? 何不试试P2P Sync?
    screen 命令使用 keep session running after ssh logout
    Zotero: add a history feature for paper viewing
  • 原文地址:https://www.cnblogs.com/zltao/p/10464853.html
Copyright © 2011-2022 走看看