Hibernate学习笔记

Hibernate开发流程

  • 导入Maven依赖(还有数据库驱动)
<dependencies>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-core</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-entitymanager</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-osgi</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-c3p0</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-proxool</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-infinispan</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-ehcache</artifactId>
        <version>5.2.10.Final</version>
    </dependency>
</dependencies>
  • 创建核心配置文件和Mapper的xml文件里

    • 配置Xml头在核心包(core)里的dtd文件里找到,如下
    <!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd"><
    
    <!DOCTYPE hibernate-mapping PUBLIC 
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
    
    • 创建核心配置文件
    <!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>
            <!--配置数据源-->
            <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
            <property name="connection.url">jdbc:mysql://localhost:3306/money2?userSSL=true&amp;useUnicode=true&amp;characterEncoding=UTF8&amp;serverTimezone=GMT&amp;allowMultiQueries=true</property>
            <property name="connection.username">root</property>
            <property name="connection.password">root</property>
            <!--配置SQL方言-->
            <property name="hibernate.dialect">org.hibernate.dialect.MySQL57Dialect</property>
            <!--自动创建表(一般不需要)-->
            <property name="hbm2ddl.auto">update</property>
            <!--显示SQL-->
            <property name="show_sql">true</property>
            <property name="format_sql">true</property>
            <!--配置数据实体-->
    
            <!--注册mapper-->
            <mapping resource="mapping/AccUser.hbm.xml"/>
        </session-factory>
    </hibernate-configuration>
    
    • 创建实体类和映射文件
    <!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="com.libi.entity.AccUser" table="acc_user">
            <!--对象标识OID-->
            <id name="id" column="id">
                <generator class="identity"/>
            </id>
            <!--属性映射-->
            <property name="userName" column="user_name"/>
            <property name="password" column="password"/>
            <property name="createTime" column="create_time"/>
        </class>
    </hibernate-mapping>
    
    • 在核心配置文件的<session-factory>标签里注册mapping
    <!--注册mapper-->
    <mapping resource="mapping/AccUser.hbm.xml"/>
    
  • 添加主类进行测试

public class Application {
    public static void main(String[] args) {
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Transaction transaction = session.getTransaction();
        transaction.begin();
        AccUser user = new AccUser();
        user.setUserName("hibernate");
        user.setPassword("1233333");
        user.setCreateTime(System.currentTimeMillis());
        session.save(user);
        transaction.commit();
        session.close();
        sessionFactory.close();
    }
}

Hibernate主键生成策略

  • 配置位置:在Mapping配置文件里配置
<class name="com.libi.entity.AccUser" table="acc_user">
    <!--对象标识OID-->
    <id name="id" column="id">
        <generator class="具体策略"/>
    </id>
</class>
  • 生成策略
    • identity:采用数据库底层的自增长列(MySQL)
    • sequence:采用数据库底层的自增长列(Oracle)
    • native:根据数据库选择identity,sequence或hilo中的一个
    • increment:采用Hibernate自己维护的自增长(先查询max,再+1)
    • uuid:采用UUID作为唯一字符串(id字段必须是string类型)
    • assigned:需要明确赋值(开发者维护)

Hibernate的自动模式(生成映射文件和实体类)

  • 在IDEA里配置Database(右面maven上面的按钮)
  • 添加Hibernate插件的支持

HQL

  • HQL = Hibernate Query Language,主要用面向对象的思维来编写SQL。下面的示例就可以查询所有的User,并且实现分页
public List<AccUser> selectAllUser() {
    Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
    SessionFactory sessionFactory = configuration.buildSessionFactory();
    Session session = sessionFactory.openSession();
    Query<AccUser> query = session.createQuery("select au from AccUser au", AccUser.class);
    query.setFirstResult(0);
    query.setMaxResults(10);
    return query.getResultList();
}
  • 条件查询

    • 索引占位(下面的例子是查询Id是传入数字的AccUser)
    public AccUser selectUserById(Long uid) {
        Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
        SessionFactory sessionFactory = configuration.buildSessionFactory();
        Session session = sessionFactory.openSession();
        Query<AccUser> query = session.createQuery("select au from AccUser au where id = ?", AccUser.class);
        //传入占位的ID实现查询
        query.setParameter(0, uid);
        //获取单个结果
        return query.uniqueResult();
    }
    
    • 命名占位(只需要在上例的基础上修改hql语句和传入参数的语句)
    ...
    Query<AccUser> query = session.createQuery("select au from AccUser au where id = :id", AccUser.class);
    ...
    query.setParameter("id", uid);
    ...
    
  • 模糊查询

    • 使用百分号包起来做字符串部分匹配"%查询内容%"
  • HQL更新和删除(类似SQL更新和删除)

  • HQL查询部分字段

    • 只查询一个字段,在后面加上这个字段的类型
    Query userName = session.createQuery("select userName from AccUser where id = 1",String.class);
    
    • 不知道这是什么类型或者查询两个以上的字段,使用Object数组(Hibernate会用Object数组的方式返回给你)
    Query userName = session.createQuery("select userName, password from AccUser where id = 1");
    

解决传递当前Session问题

  • 保存到本地线程

    • 在核心配置xml里配置允许保存到本地线程
    <property name="hibernate.current_session_context_class">thread</property>
    
    • 在线程里获取session (使用这种session必须开启事务并且不用关闭session,现在这个session会和这个线程共存亡)
    Session currentSession = sessionFactory.getCurrentSession();
    

级联查询

  • Hibernate可以实现不通过写SQL或HQL语句拿到字段里外键约束对应的记录的映射对象(关联信息默认是懒加载的)
  • 具体做法可以在IDEA的逆向生成工具生成

延迟检索

  • 相当我使用这个对象时才会查询数据库
    • 使用session.get(class)是立即检索(先查session缓存再查数据库)
    • 使用session.load(calss)时延迟检索(先查session缓存再查二级缓存最后查数据库)
  • 关联表的延迟与立即(在<many-to-noe>默标签里添加lazy属性,认是延迟lazy = true

实体类的状态

  • 瞬时态:没有主键,没有被session管理(实体类刚刚被创建)
  • 持久态:有主键,被session管理(实体类被session做save、get等操作,现在实体类被session管理)
  • 游离态:有主键,但是没有被session管理(session被关闭)

缓存

  • 一级缓存:
    • 缓存在session中,如果修改了缓存内容(持久态的对象被修改)并且提交了事务之后,Hibernate会进行快照对比,如过不一致,会同步到数据库
    • 可以调用clear方法清空所有一级缓存
  • 二级缓存
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,324评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,303评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,192评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,555评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,569评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,566评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,927评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,583评论 0 257
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,827评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,590评论 2 320
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,669评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,365评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,941评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,928评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,159评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,880评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,399评论 2 342

推荐阅读更多精彩内容

  • 本节重点:1、hibernate映射文件2、hibernate核心配置文件3、hibernate核心类 1、hib...
    Vincilovfang阅读 605评论 0 2
  • layout: posttitle: hibernatesubtitle: 用法date: ...
    虫儿飞ZLEI阅读 324评论 0 1
  • 1.ORM(Object Relation Mapping):对象关系映射-主要解决对象-关系的不匹配 ORM的实...
    疏_桐阅读 354评论 0 0
  • 创建工程可以是java也可以是web 1、引入jar文件 2、设计表同时开发和表的字段名一致的javabean(持...
    蘋果_283e阅读 515评论 0 0
  • 不知是在那个落寞的深夜 人民广场上的玫瑰花 悄然绽放 路过花圃身旁 我想偷偷的摘一朵 把它送给你 可是 我又不忍心...
    来自青海的青稞酒阅读 264评论 1 1