Hibernate

Hibernate是一种ORM框架,全称为 Object_Relative DateBase-Mapping,在Java对象与关系数据库之间建立某种映射,以实现直接存取Java对象!

ORM思想 对象关系映射

 

Hibernate入门案例

 hibernate.cfg.xml配置

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- session对象 连接数据库 操作数据库-->
        <!--数据库方言-->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <!--驱动-->
        <property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
        <!--url-->
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/crm_hibernate</property>
        <!--用户名-->
        <property name="hibernate.connection.username">root</property>
        <!--密码-->
        <property name="hibernate.connection.password">lily</property>
        <!-- 显示执行的SQL语句 把你的SQL语句以一行的行输出到控制台 -->
        <property name="hibernate.show_sql">true</property>
        <!-- 格式化SQL语句 格式化后进行多行展示 -->
        <property name="hibernate.format_sql">true</property>
        <!--引入实体类的映射文件Customer.hbm.xml -->
        <mapping resource="com/minimax/code/entity/Customer.hbm.xml" />
    </session-factory>
</hibernate-configuration>

在idea中hibernate.cfg.xml的配置

<?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/crm_hibernate</property>
        <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
        <!-- <property name="connection.username"/> -->
        <!-- <property name="connection.password"/> -->
        <property name="connection.username">root</property>
        <property name="connection.password">lily</property>
        <!-- DB schema will be updated if needed -->
        <!-- <property name="hbm2ddl.auto">update</property> -->
        <mapping resource="com/minimax/code/entity/Customer.hbm.xml" />
    </session-factory>
</hibernate-configuration>

实体类Customer

package com.minimax.code.entity;

public class Customer {
    private Long id; // '客户编号(主键)',
    private String name; // '客户名称(公司名称)',
    private String source; // '客户信息来源',
    private String industry; // '客户所属行业',
    private String level; // '客户级别',
    private String phone; // '固定电话',
    private String mobile; // '移动电话',
  //有参构造,无参构造,get/set方法
}

实体类对应的映射文件Customer.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>
    <!--
		配置表与类的映射
	 	name 配置类的名称
	 	table 表名(数据库概念为了和程序概念加以区分数据库中的对象都要大写)
	 -->
    <class name="com.minimax.code.entity.Customer" table="CST_CUSTOMER" >
        <!-- 属性与字段的配置 -->
        <!-- 主键 -->
        <id name="id" column="cust_id">
            <!-- 主键自增策略 -->
            <!-- mysql 支持主键自增 -->
            <!-- hibernat让数据库自己决定主键的生成方法 因为mysql是自增的所以可以配置该属性 -->
            <generator class="native"/>
        </id>
        <!--
			普通字段
		 	type="java.lang.String"
		 	type="string"
		 	如果类型映射正确是可以不用指定的
		 -->
        <property name="name" column="cust_name" />
        <property name="source" column="cust_source" />
        <property name="industry" column="cust_industry" />
        <property name="level" column="cust_level" />
        <property name="phone" column="cust_phone" />
        <property name="mobile" column="cust_mobile" />
    </class>
</hibernate-mapping>

测试类Test.java

package com.minimax.code.test;


import com.minimax.code.entity.Customer;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;

public class Test {
    public static void main(String[] args) {
        // 获取数据库连接 session-->sessionFacotry-->hibernate-configuration
        // 创建configuration对象加载XML
        Configuration cfg = new Configuration();
        // 加载XML
        cfg.configure();
        // 创建session工厂类
        SessionFactory sf = cfg.buildSessionFactory();
        // 创建session对象  == conn + ps
        Session session = sf.openSession();
        // 添加操作 创建添加对象
        Customer cus = new Customer();
        cus.setIndustry("努力学习");
        cus.setLevel("紫色");
        cus.setMobile("1351245678");
        cus.setName("我是一个hibernate案例");
        cus.setPhone("010-12345678");
        cus.setSource("网络");
        // 开启事务
        Transaction transaction = session.beginTransaction();
        try {
            session.save(cus);
            transaction.commit();
            System.out.println("添加成功");
        } catch (Exception e) {
            transaction.rollback();
            e.printStackTrace();
        } finally {
            session.close();
        }

    }
}

以上是一个hibernage的入门案例

get()和load()

load() 延迟加载  懒加载

懒加载在加载一个实体的时候,不会马上从数据库中加载,即从数据库中加载到内存。而急加载在加载一个实体时,会立即从数据库中查询,与其关联的类也会被同时查询。

急加载就会很快,因为在第一次加载的时候,已经帮我们全部加载好了。而懒加载则会相对慢一些,因为在我门需要查询的时候,它才会执行sql操作。

所以懒加载的优点是占用内存小,执行速度慢;急加载是执行速度快,占用内存高

hibernate的get()和 load()方法在执行的时候又很大的区别,

执行get()方法会把所有的基本数据全部加载,

而load()方法在懒加载中只会加载ID属性,所有的ID属性,其他的非ID属性的操作都不会执行,当我们需要查询默写具体的数据是才会真的执行sql操作,因为懒加载的有效期是在一个session中,所以今天我们在关闭了session的情况下会报错,因为Hibernate尝试通过当前session发sql查询,但发现session已经关闭,这样就会发出no session的异常 。

我们可以吧加载方式变成急加载或者不关闭session。

 

 

Hibernate的持久化类和对象标示符
       持久化类 : 持久化 某个java的普通类与表建立映射关系之后
       规范

  • 持久化类需要无参的构造
  • 属性都是私有的 提供get set方法
  • 持久化类的属性都是包装类型 null int(0) Integer(null)
  • 持久化类中必须有一个属性与主键字段对应
  • implements Serializable

   对象标识符
        - OID 表的主键ID --> 程序里被标记成<id>标签里面的属性
            - 1) Hibernate用于区分两个对象的唯一途径
            - 2) 对象标示符可以帮助session完成查询性能的优化
Hibernate主键自增策略:

  • native : 让数据库自己决定主键如何生存适合于能主键自增的数据(mysql sqlserver)
  • sequence : 使用序列来生成主键,有的数据库不支持主键自增(Oracle)
  • identity : 采用数据库的主键自增来生成主键(mysql,sqlserver,DB2)

      uuid : 根据128位数据算法生成32为的一个字母+数字的字符串用来标识主键
      uuid : 当你一个程序使用两个数据库的时候必须使用UUID作为同名表的主键ID; 数据1 数据2 userinfo (1 2 3 4) (1 2 3 4)
          

Hibernate一级缓存

hibernate一级缓存(session缓存)

缓存 : 临时存储硬盘数据到内存中的一项技术;
程序运行在内存里 所以当读取数据的时候 内存读内存 内存读硬盘快
Hibernate为了提升查询性能也进行了缓存操作-->Session
Session的一级缓存 是Hibernate用于进行数据库与程序之间沟通的一个桥;
当程序完成持久化操作的时候Hibernate会通过Session把该对象与相对应的数据库中的数据关联到一起;

例如:当查询表中一条数据是,hibernate会先存在session中再返回,当再次查询的时候会先去缓存中查找,没有再去查询数据库

快照机制 :

说明了session不光可以缓存数据库中的数据,还可以管理数据库中的数据,但是要注意快照机制只能简化更新操作;
缓存与快照机制保证了数据库的简化及性能提升操作;

当session遇到commit是,会拿自己的缓存数据去和数据库对比,当发现不一样时,会更新数据库的数据(强制性的)

Hibernate管理java对象的三种状态

Hibernate管理Java对象的时候因为根据数据库数据对应于session管理不同分为三种状态

  • 持久化 : 数据库有数据对应     被session管理
  • 瞬时对象 : 数据库没有数据对应    session不管理
  • 游离状态 : 数据库有数据对应     但是session不管理 

操作

  • 添加的一定是瞬时的
  • 更新和修改的一定是持久的

 

Hibernate

表与表之间   多对多   多对一  一对一

<mapping resource="com/minimax/entity/Customer.hbm.xml"/> 引入实体类配置文件

//多对多
<set name="roles" table="sys_user_role">
		<key column="user_id" />
		<many-to-many class="com.minimax.entity.RoleInfo" column="role_id" />
</set>
//多对一
<many-to-one lazy="false" name="cus" class="com.minimax.entity.Customer" column="lkm_cust_id"/>

<!-- 配置set集合 -->
		<!-- 
			cascade="all" 代表当添加一的一方的时候 级联添加多的一方 更新和删除走同样的操作
			一的一方 添加 或者 删除的时候 同步操作多的一方
			cascade="save"
			cascade="save-update"
			cascade="none" 不级联
			save-update 数据库如果村存在主外键还删除不了
			如果程序操作数据库那么数据库除主键约束外是不允许有其他约束的
			lazy="true" 默认延迟加载
		 -->
<set name="mans" inverse="true" cascade="all" lazy="extra">
			<!-- 一个外键因为实体的摆放位置不同所以才有的两种关系 说白了 多对一 和 一对多 都是主外键关系 -->
		<key column="lkm_cust_id" />
		<one-to-many class="com.itheima.entity.LinkMan"/>
</set>

 

Hibernate注解配置实体类

@Entity
@Table(name="cst_customer")//配置和数据库对应的表
public class Customer implements Serializable {
	@Id//主键Id
	@Column(name="cust_id")//配置和数据库表对应的字段
	@GeneratedValue(strategy=GenerationType.IDENTITY)
	private Long cid;// '客户编号(主键)',
	@Column(name="cust_name")
	private String cname; // '客户名称(公司名称)',
	
	@Transient //
	private String industry; // '客户所属行业',

@Entity 
    作用:指定当前类是实体类。写上此注解用于创建SessionFactory/EntityManager时,加载映射配置
@Table 
    作用:制定实体类与表之间的对应关系
    属性:name:制定数据库表的名称
@Id
    作用:指定当前字段是主键
@GeneratedValue
    作用:指定主键的生成方式
    属性:strategy:指定主键生成策略。
    JPA支持四种生成策略
        IDENTITY:主键由数据库自动生成(主要是自动增长型)
        SEQUENCE:根据底层数据库的序列来生成主键,条件是数据库支持数列

@GeneratedValue(strategy=GenerationType.SEQUENCE,generator="payablemoney_seq")
@SequenceGenerator(name="payablemoney_seq",sequenceName="seq_payment")
name:表示该表主键生成策略名称,它被引用在@GeneratedValue中设置对的generator值中。
sequenceName:属性表示生成策略用到的数据库序列名称

         AUTO:主键由程序控制
        TABLE:使用一个特定的数据库表格来保存主键(了解)
@Column
    作用:指定实体类属性和数据库表之间的对应关系
    属性:name:执行数据库的列名称
        unique:是否唯一
        nullable:是否可以为空
        inserttable:是否可以插入
        updateable:是否可以更新
        columnDefinition:定义建表时创建此列的DDL
        secondaryTable:从表名。如果此列不建在主标上(默认建在主表),改属性定义该列所在的从表的名字
    
一对多注解配置
@OneToMany
    作用:建立一对多的关系映射
    属性:
        targetEntityClass:指定多的多方的类的字节码
        mappedBy:指定从表实体类中引用主表对象的名称
        cascade:指定要使用的级联操作
        fetch:指定是否采用延迟加载
        orphanRemoval:是否使用孤儿删除
@ManyToOne
    作用:建立多对一的关系
    属性:
        targetEntityClass:指定一的一方的类的字节码
        cascade:指定要使用的级联操作
        fetch:指定是否采用延迟加载
        optional:关联是否可选。如果设置为false,则必须始终存在非空关系。
        orphanRemoval:是否使用孤儿删除
@JoinColumn
    作用:用于定义主键字段和外键字段的对应关系
    属性:
        name:指定外键字段名称
        referencedColumnName:指定引用主表的主键字段名称
        unique:是否唯一。默认值不唯一
        nullable:是否允许为空,默认值允许
        insertable:是否允许插入,默认值允许
        updatable:是否允许更新,默认值允许
        columnDefinition:列的定义信息

 Customer类    
        @OneToMany(targetEntity=LinkMan.class,mappedBy="customer")
        private Set<LinkMan> linkmans = new HashSet<LinkMan>();
 LinkMan类       
        @ManyToOne(targetEntity=Customer.class)
        @JoinColumn(name="lkm_cust_id",referencedColumnName="cust_id")


多对多关系映射
@ManyToMany
    作用:
        用于映射多对多关系
    属性:
        cascade:配置级联操作
        fetch:配置是否采用延迟加载
        targetEntity:配置目标实体类,映射多对多的时候不用写
@JoinTable
    作用:
        针对中间表的配置
    属性:
        name:配置中间表的名称
        joinColumns:中间表的外键字段关联当前实体类所对应表的主键字段
        inverseJoinColumn:中间表的外键字段关联对方标的主键字段


SysUser类 
    @ManyToMany(mappedBy="users")
    private Set<SysRole> roles = new HashSet<SysRole>();
SysRole类
    @ManyToMany
    @JoinTable(name="user_role_rel",//中间表的名称
    //中间表user_role_rel字段关联sys_role表的主键字段role_id
    joinColumns={@JoinColumn(name="role_id",referencedColumnName="role_id")},
    //中间表user_role_rel字段关联sys_user表的主键user_id
    inverseJoinColumn={@JoinColumn(name="user_id",referencedColumnName="user_id")}
    )
    private Set<SysUser> users = new HashSet<SysUser>();    
        
        
        

 

 

HIbernate一级缓存、懒加载、二级缓存查看网址

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
校园悬赏任务平台对字典管理、论坛管理、任务资讯任务资讯公告管理、接取用户管理、任务管理、任务咨询管理、任务收藏管理、任务评价管理、任务订单管理、发布用户管理、管理员管理等进行集中化处理。经过前面自己查阅的网络知识,加上自己在学校课堂上学习的知识,决定开发系统选择小程序模式这种高效率的模式完成系统功能开发。这种模式让操作员基于浏览器的方式进行网站访问,采用的主流的Java语言这种面向对象的语言进行校园悬赏任务平台程序的开发,在数据库的选择上面,选择功能强大的Mysql数据库进行数据的存放操作。校园悬赏任务平台的开发让用户查看任务信息变得容易,让管理员高效管理任务信息。 校园悬赏任务平台具有管理员角色,用户角色,这几个操作权限。 校园悬赏任务平台针对管理员设置的功能有:添加并管理各种类型信息,管理用户账户信息,管理任务信息,管理任务资讯公告信息等内容。 校园悬赏任务平台针对用户设置的功能有:查看并修改个人信息,查看任务信息,查看任务资讯公告信息等内容。 系统登录功能是程序必不可少的功能,在登录页面必填的数据有两项,一项就是账号,另一项数据就是密码,当管理员正确填写并提交这二者数据之后,管理员就可以进入系统后台功能操作区。项目管理页面提供的功能操作有:查看任务,删除任务操作,新增任务操作,修改任务操作。任务资讯公告信息管理页面提供的功能操作有:新增任务资讯公告,修改任务资讯公告,删除任务资讯公告操作。任务资讯公告类型管理页面显示所有任务资讯公告类型,在此页面既可以让管理员添加新的任务资讯公告信息类型,也能对已有的任务资讯公告类型信息执行编辑更新,失效的任务资讯公告类型信息也能让管理员快速删除。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值