zoukankan      html  css  js  c++  java
  • Hibernate零散笔记

    加入mysql的驱动mysql-connector
    
    在数据库中建立相应的内容:
    create database hibernate;
    
    use hibernate;
    
    create table student(id int primary key, name varchar(20),age int);
    
    建立student类:
    
    
    建立hibernate配置文件,hibernate.cfg.xml:
    
    <?xml version='1.0' encoding='utf-8'?>
    <!DOCTYPE hibernate-configuration PUBLIC
            "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
    
    <hibernate-configuration>
    
        <session-factory>
    
            <!-- Database connection settings (hibernate自动帮你链接了数据库,填入相关信息) -->
            <property name="connection.driver_class">com.mysql.jdbc.Driver</property>
            <property name="connection.url">jdbc:mysql://localhost/hibernate</property>
            <property name="connection.username">root</property>
            <property name="connection.password">abc123</property>
    
            <!-- JDBC connection pool (use the built-in) (hibernate的连接池) -->
            <!-- <property name="connection.pool_size">1</property> -->
    
            <!-- SQL dialect (hibernate方言,hibernate统一了sql语言,将统一语言翻译成下面填写的相应的数据库语言) -->
            <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    
            <!-- Enable Hibernate's automatic session context management -->
            <property name="current_session_context_class">thread</property>
    
            <!-- Disable the second-level cache (将二级缓存disable掉)  -->
            <property name="cache.provider_class">org.hibernate.cache.NoCacheProvider</property>
    
            <!-- Echo all executed SQL to stdout (将生成的sql语句打印出来) -->
            <property name="show_sql">true</property>
    
            <!-- Drop and re-create the database schema on startup (是否让hibernate自动生成ddl(建表语句)) -->
            <!-- <property name="hbm2ddl.auto">update</property> -->
    
            <mapping resource="com/bjsxt/hibernate/model/Student.hbm.xml"/>
            
        </session-factory>
    
    </hibernate-configuration>
    
    还要指明object与表字段的对应关系。建立映射文件,Studnet.hbm.xml:
    
    <?xml version="1.0"?>
    <!DOCTYPE hibernate-mapping PUBLIC
            "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
            "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
    
    <hibernate-mapping package="com.bjsxt.hibernate.model">
        <class name="Student">    //找到对应的类
            <id name="id" column="id" />    //id表示为主键
            <property name="name" />    //property表示一般字段
            <property name="age" />
        </class>
    </hibernate-mapping>
    
    写测试类:
    
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    
    import com.bjsxt.hibernate.model.Student;
    
    
    
    public class StudentTest {
        public static void main(String args[]){
            Student s = new Student();
            s.setId(1);
            s.setName("s1");
            s.setAge(1);
            
            Configuration cfg = new Configuration();
            SessionFactory sf = cfg.configure().buildSessionFactory();    //SessionFactory产生connecyion的工厂
            Session session = sf.openSession();
            session.beginTransaction();
            session.save(s);    //将对象s插入数据库
            session.getTransaction().commit();
            session.close();
            sf.close();
        }
    }
    
    annotation(利用annotation注解就可以不用*.hbm.xml文件):
    建立新表:
    create table teacher (id int primary key,name varchar(10),title varchar(20));
    
    建立对象Teacher并加入注解annotation:
    
    package com.bjsxt.hibernate.model;
    
    import javax.persistence.Entity;
    import javax.persistence.Id;
    
    @Entity    //表示实体类,对应于数据库表中的一个表
    public class Teacher {    //利用annotation注解就可以不用*.hbm.xml文件
        private int id;
        private String name;
        private String title;
        
        @Id    //表示主键
        public int getId() {
            return id;
        }
        public void setId(int id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getTitle() {
            return title;
        }
        public void setTitle(String title) {
            this.title = title;
        }
    }
    
    JDBC操作数据库很繁琐
    sql语句是面向关系而不是面向对象
    可以再对象和关系表之间建立关系来简化变成
    o/r mapping跨越数据库平台
    
    表名与类名不同的时候,对表名进行配置
        Annotation:@Table
        xml:...
    
    字段名与属性相同的时候:默认为@Basic;xml中不写column
    
    字段名与属性名不同的时候:
        Annotation:@Column
        xml:...
    
    不需要psersitence(持久化,存入数据库)的字段:
        Annotation:@Transient
        xml:直接不写
    
    映射日期与时间类型,指定时间精度:
        Annotation:@Temporal
        xml:制定property标签的type属性
    
    枚举类型的映射:
        Annotation:@Enumerated
        xml:...
    
    注解的位置:
        可以放在field(成员变量)上面,
        也可以放在getxxx方法上面。
    
    Junit4有BUG:第19个视频
    
    ID生成策略:对应项目hibernate_0400_ID
    注意:
        我们观察hibernate生成表的结构并不是为了将来就用他生成(也可能还有自己的扩展,比如index),而是为了明白我们应该尽力什么样的表和实体类映射。
    
    xml生成id:
        使用generator
        常用的有四个:native identity sequence uuid
    annotation生成id:
        @GeneratedValue
        有四种取值方式:auto identity sequence(@SequenseGenrator) table(@TableGenerator)
    
    联合主键:
        xml:composite-id(要实现serializable和重写equals和hashcode)
        annotation:
            将类注解为@IdClass,并将该类实体中的所有属于主键的属性都注解为@Id
            将组件类注解为@Embeddable.并将组件的属性注解为@Id
            将组建的属性注解为@Embeddable
            
        
    Hibernate的核心开发接口:
        sessionFactory有两个方法得到Session:
        1.openSession:每次都打开一个新的Session,用完要关闭
        2.getCurrentSession:拿到当前上下文(可以在配置文件中设置current-context-class,主要有jta和thread)已有的Session或者打开一个新的Session(前一个Session被commit之后),用完不用关闭,commit()之后自动关闭。
        Session是个接口,这两种方法得到的具体类可能不一样,所以不能混用
        两种方法的区别很重要
    区别在第26集。
        JPA界定事物边界,例如数据存入和日志记录需要在同一个事物之内完成。
        还有一种事物JTA,分布式数据库。
    
    
    对象的三种状态:
        怎么区分:
        1.对象有没有ID
        2.ID在数据库中有没有
        3.在内存(session缓存)中有没有ID
    1.transient:内存中一个对象,没ID,缓存中也没有ID
    2.persistent:内存中有ID,缓存中有ID,数据库有ID
    3.detached:内存有ID,缓存没有ID,数据库有ID
    
    delete方法:
        只要有ID就可以调用delete方法
    
    get和load的区别:
        get会马上执行sql语句得到对象
        load会生成并返回一个代理对象,直到你取该对象的属性,这个代理才会执行sql语句得到对象
    不存在对应记录的时候有区别。
    
    update:
        用来跟新detached对象,更新完成后可以转化为persistent状态
        更新transient会报错
        跟新自己设定ID的transient对象可以(前提是数据库有对应记录)
    当一个persistent对象的字段被改变的时候,commit会检查修改,且更改全部字段。
    下面的方法只让他修改相应的修改了的字段:第32个视频。
    
    clear:
        无论是load还是get,都会先查找缓存,如果没有,才会去数据库查找,调用用clear方法可以强制清除Session缓冲。
    
    flush:
        可以强制进行从内存到数据库的同步,commit时就执行一次flush。
    
    
    关系映射:
    对象之间的关系:
    
    一对一:
        单向:
            每个Husband对应一个Wife,Wife中没有对应的Husbus,则此为单向关联
            在数据库有中用外键关联
            @OneToOne @JoinColumn(name="wifeId")
        双向:
            每个Husband对应一个Wife,Wife中也对应一个Husbus,则此为双向关联
            @OneToOne(mappedBy)
        联合主键:
            @JoinColums
    一对多(多对一):
        设局库表设计:在多的一方加外键。
    
    多对多:    
        单向关联:
            老师和学生的关系,老师需要知道自己教了哪些学生。
        双向关联:
            老师知道自己教了哪些学生,学生也知道教自己的有哪些老师。
    
    此外还可以根据单向还是双向可以非为7种。
    
    Ctrl+Alt+下    复制这一行到下一行
    Alt+下    移动这一行到下一行
    powerdesigner可以用于分析代码,生成表的关系图。
    
    关联关系中的CRUD:
        设定cascade可以设定在持久化时对于对象的操作。
        C--create
        R--retrieve(取出load get)
        U--update
        D--delete
    Cascade属性致命做什么操作的时候关联对象是绑在一起的
    Merge=save+update
    refresh=A里面需要读B改过之后的数据
    
    铁律:双向关系在程序中要设定双向关系,双向关系设定mappedBy(在一的那一方设置)
    
    fetch:
        双向不要两边设置Eager(会有多余的查询语句发出)
    对多的乙方设置fetch的时候要谨慎,结合具体情况,一帮使用Lazy不使用eager(特别情况:多方的数量不是很多的时候可以考虑,提高效率的时候可以考虑)。
    
    O/RMapping编程模型:
    1.映射模型
        jap annotation
        hibernate annotation extension
        hibernate xml
        jap xml
    2.编程接口
        jap
        hibernate
    3.数据查询:
        hql
        ejbql(jpql)
    
    要删除或者更新的时候,先load,除了精确知道ID号之外。
    
    如果要消除关联关系,先设定为NULL,在删除记录,如果不删除记录,该记录就会变成垃圾数据。第51集。
    
    如果指定@OneToOne的属性fetch为FetchType.LAZY,会延迟对于关联对象的加载,不论使用的是load还是get。
    
    关系映射总结:什么样的关系,设计什么样的表,进行什么样的映射。
    
    继承映射:
        1.一张表single_table
        2.每个类分别一张表table_pre_class
        3.每个子类一张表joined
    
    树状结构的设计(至关重要):
        在用一个类中使用one2many和many2one。
    
    Hibernate查询(query language)
    HQL&EJBQL
    1.NativeSQL
    2.HQL(Hibernate ql)
    3.EJBql(JPql 1.0)--可认为是hql的子集
    4.qbc
    5.qbe
    
    
    性能优化:
        注意session.clear()的使用,尤其在不断分页循环的时候,否则会造成内存泄漏。
    JAVA有内存泄露吗?
        在语法级别上没有,但是在实际上可能会间接造成,如果他调用用了C,在调用OS,而C需要手动控制内存。
    
    1+N问题(很重要):
        第64集
    解决方案:
        1.设置LAZY
        2.BatchSize
        3.join fetch
    用得最多的是1 3。
    
    list和Iterate的区别:
        1.list取所有
        2.iterate先去ID,等用到的时候再根据ID来去对象
        3.session中list第二次发出,仍会到数据库查询
        4.iterate第二次发出,则会先找session缓存
    
    hiberbate中有三种缓存:
        1.一级缓存(Session级)
    
        2.二级缓存(SessionFactory级)
            可以跨Session存在
        以下情况使用二级缓存:
            1.经常被访问
            2.不会经常改动
            3.数量有限
            如:用户权限、组织机构
    hibernate.cfg.xml设定:
        <property name="cache.use_second_level_cache">true</property>    //打开二级缓存
        <property name="cache.provider_class">org.hibernate.cache.EnCacheProvider</property>    //指明使用哪种二级缓存
    添加注解:
        @Cache
    load默认使用二级缓存,iterate默认使用二级缓存
    list默认往二级缓存加数据,但是查询的时候默认不使用
        3.查询缓存
    只有在查询语句完全一样才有效。查询缓存依赖于二级缓存,所以必须同时打开二级缓存。
    调用Query的setCachable(true)方法指明使用二级缓存。
    
    缓存算法:(当缓存满了之后怎么办)
        1.LRU:Least Recently Used(最近最少被使用的被清除)
        2.LFU:Least Frequently Used(使用频率最少的被清除)
        3.FIFO:First In First Out(先来的先被清除)
    可以在ehcache中设置使用哪一种:
        memoryStoreEvictionPolicy="LRU"
    
    事物并发处理:
    事物的特性:ACID
    Atomic(原子性) Consistency(独立性) Itegrity(一致性) Durability(持久性)
    事物经常出现的问题:
        脏读 不可重复读 幻读 
    数据库的事物的隔离机制:
    1:read-uncommitted
    2:read-committed
    4:repeatable read
    8:serilizable
    只要数据库支持事物,就不可能出现第一类丢失跟新。
    read-uncommitted会出现dirty read,phanton-read,non repeatable read问题。
    read-committed不会出现dirty read,因为只有另一个事物提交才会读出来结果,但仍然会出现phanton-read,non repeatable read.
    repeatable read。
    serial解决一切问题。
    设定hibernate的事物隔离级别:
        一般设定hibernate.connection.isolation=2    //考虑效率
        用悲观素解决repeatable read的问题(依赖于数据库的锁)
  • 相关阅读:
    本博客主题设置
    .NET开源类库Nini手册(INI、XML、注册表的配置应用)-中文翻译
    service层的@Autowired 与@Override
    ajax传值时各参数意义
    序列化+继承
    KMP
    SpringBoot启动过程:
    Web三层架构及MVC
    SpringBoot注解意义及作用
    Syntax error on token "{", { expected after this token相关的错误
  • 原文地址:https://www.cnblogs.com/mosquito-woo/p/3880737.html
Copyright © 2011-2022 走看看