.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);

 

posted @ 2019-03-03 13:02  水痕灬  阅读(189)  评论(0编辑  收藏  举报