hibernate

作者: 帅哥_刷哥 | 来源:发表于2017-10-10 23:45 被阅读39次

    AQ#说明

    1.基础的jar包
        required + jpa + mysql数据库连接
        
    1.下载地址
        http://hibernate.org/orm/downloads/
        https://sourceforge.net/projects/hibernate/files/hibernate-orm/
        https://sourceforge.net/projects/hibernate/files/
        
    2.ORM概念
        O  Object 对象 
            Java对象
        R  Relation 关系
            数据库表
        M  Mapping 映射
            dao中的增删改查操作  方式:1.xx.hbm.xml  2.注解
            
        ORM是规则是概念
        ORM的实现
            hibernate框架
            mybatis框架
            自己代码实现(反射)
            
    3.对dao操作,有哪些选择,优缺点
        1.jdbc
        2.DbUtils组件
        3.自己封装jdbc工具类,简化jdbc操作
        4.hibernate框架
        5.mybatis框架
        
        对比
            执行效率最高:纯jdbc操作
            开发效率最高:hibernate
            兼容性好:hibernate,可以跨数据库平台
            
    4.使用步骤:
        1.建库、建表
        2.写实体类
        3.写映射文件
        4.写数据库配置文件
        5.测试api
            
        
    基本映射 base
    
    主键映射 
        基本主键映射
        复合主键映射
    
    复合属性  compattr
          修改列名2种方式
          
    集合映射 collection
        基本数据类型/自定义类型
        List
        Set
        Map 
        
    关联映射 oneway/bothway
        单向关联(一边配置关联):oneway
            一对一(1--1):
            一对多(1--N):
            多对一(N--1):
            多对多(N--N):
        双向关联(两边配置关联):两边都可以查询 bothway
            一对一(1--1):@OneToOne 加了mappedBy的表时主表,另外一张是从表
            一对多(1--N):
            多对多(N--1):@ManyToMany
                
        从表中生成外键,配置@JoinCloumn的是从表 先保存主表,再保存从表
        
    继承映射 extend
        所有的持久化都会生成表(子类表会引用父类表的主键列)
        单个表(只生成一张表)
        所有的持久化都会生成表(子类会把父类中的属性继承过来生成在自己的表中)
    

    代码

    onfiguration cf = new Configuration();
    cf.configure("com/shuai/hibernate/bothway/onetomany/hibernate.cfg.xml");
    ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() 
    .applySettings(cf.getProperties()).build();
    SessionFactory sessionFactory = cf.buildSessionFactory(serviceRegistry);
    Session session = sessionFactory.getCurrentSession();
    Transaction transaction = session.beginTransaction();
    //数据库操作
    transaction.commit();
    

    基础

    //1.注解方式
    @Entity //把pojo转化成持久化类
    @Table(name="user") // 指定表名
    public class User {
    
        @Id //主键列
        @GeneratedValue(strategy=GenerationType.AUTO) //自增长
        @Column(name="u_id") //指定数据库列名 如果不写就跟属性名一致 (映射列名  )
        private int id;
        
        @Column(name="u_name", //列名
                length=50, //长度
                nullable=true, //非空约束
                unique=true)// 唯一约束
        private String name;
        
        @Column(name="u_age", //列名
                columnDefinition="int(10) NOT NULL default 20") //规定长度 和 初始化值
        private int age;
        
        @Column(name="u_address",
                insertable=false, // 不允许插入
                updatable=false)// 不允许修改
        private String address;
        
        @Column(name="u_salary", precision=6, // 总位数
                scale=2) // 小数点后面位数
        private BigDecimal salary;
        
        @Lob // 映射大的二进制或大的文本
        private byte[] pictrue;
        
        /*
         * TemporalType.DATE : yyyy-MM-dd
         * TemporalType.TIME : HH:mm:ss
         * TemporalType.TIMESTAMP : yyyy-MM-dd HH:mm:ss
         * */
        @Temporal(TemporalType.TIMESTAMP) //日期格式
        private Date birthday;
        
        @Transient // @Transient|transient 指定不是持久化的属性(不会生成表中列) 
        private String remark;
    }
    
    
    //2.配置文件方式
    public class User { 
        private int id;
        private String name;
        private String password;
    }
    
    //配置User.hbm.xml
    <class name="com.shuai.hibernate.domain.User" table="t_user">
        <id name="id" column="u_id">
            <generator class="native"></generator>
        </id>
        <property name="name" column="u_name"></property>
        <property name="password" column="u_password"></property>
    </class>
    <!-- 
        class 是映射一个对象  
            name 是Java类
            table 是表
    
        property 映射属性
            name 是类的属性名
            column 是表中的属性名
            length 是指定表中字段的长度  默认是255
            type 是表中字段的类型
            not-null 是否能为空 非空约束
            unique 是否唯一  唯一约束
            
        id 是主键映射  在hibernate中表中必须要有主键
            generator 主键生成策略
                native 主键自增长
                identity MySQL中的自增长方式
                sequence Oracle中的序列增长方式
                increment 自增长但是不支持并发
                assigned 手动指定主键的值
                uuid 使用uuid做为主键   主键是String类型
                foreign 外键策略  一对一映射时用到
    -->
    

    主键/联合主键

    //主键
    @Entity
    @Table(name="user")
    public class User {
    
        /*
         * GenerationType.IDENTITY: 适宜MySQL、SqlServer有自增长列的数据库
         * GenerationType.SEQUENCE:适宜Oracle这种没有自增长有sequence的数据库
         * GenerationType.AUTO:让Hibernate根据数据库方言自动选择主键生成策略
         * GenerationType.TABLE: 适宜所有的数据库,因为它会单独生成一张表来维护主键生成
         * */
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private int id;
    }
    
    
    //联合主键
    public class PersonKey implements Serializable{
        private String firstName;
        private String lastName;
    }
    @Entity
    @Table(name="Person")
    public class Person {
        @Embedded
        private PersonKey key;
    }
    
    
    //修改联合主键表中名字-第一种方式
    public class PersonKey implements Serializable{
        private String firstName;
        private String lastName;
    }
    @Entity
    @Table(name="Person")
    public class Person {
        @Embedded
        @AttributeOverrides({@AttributeOverride(name="firstName", column=@Column(name="F_NAME")),
                             @AttributeOverride(name="lastName", column=@Column(name="L_NAME"))})
        private PersonKey key;
    }
    
    //修改联合主键表中名字-第二种方式
    public class PersonKey implements Serializable{
        @Column(name="FIRST_NAME")
        private String firstName;
        @Column(name="LAST_NAME")
        private String lastName;
    }
    @Entity
    @Table(name="Person")
    public class Person {
        @Embedded
        private PersonKey key;
    }
    
    
    
    //配置文件
    public class PersonKeys implements Serializable{
        private String username;
        private int password;
    }
    public class Person {
        private PersonKeys keys;
        private int age;
    }
    //Person.hbm.xml配置
    <class name="com.shuai.hibernate.domain.Person" table="t_person">
        <composite-id name="keys">
            <key-property name="username"></key-property>
            <key-property name="password"></key-property>
        </composite-id>
        <property name="age" column="u_age"></property>
    </class>
    
    

    继承体系中生成表的情况 InheritanceType.JOINED

    @Entity
    @Table(name="person") //生成person表
    @Inheritance(strategy=InheritanceType.JOINED) //所有的持久化都会生成表(子类表会引用父类表的主键列)
    public class Person{
        @Id
        @GeneratedValue(strategy=GenerationType.AUTO)
        private int id;
        private String name;
    }
    
    @Entity
    public class Student extends Person{
        private String subject;
    }
    
    注意:
        @Inheritance(strategy=InheritanceType.JOINED)
            所有的持久化都会生成表(子类表会引用父类表的主键列)
    

    继承体系中生成表的情况 InheritanceType.SINGLE_TABLE

    @Entity
    @Table(name="person") //生成person表
    @Inheritance(strategy=InheritanceType.SINGLE_TABLE)// 单个表
    @DiscriminatorColumn(name="per_stu",discriminatorType=DiscriminatorType.INTEGER)// 辨别者列
    @DiscriminatorValue("1")// 辨别者列值
    public class Person {}
    
    @Entity
    @DiscriminatorValue("2") //辨别者列值
    public class Student{}
    
    注意:
        @DiscriminatorColumn(name="per_stu",discriminatorType=DiscriminatorType.INTEGER)// 辨别者列
            person表中会生成一个per_stu列。
            当存入Person对象时,per_stu列的值是1
            当存入Student对象时,per_stu列的值是2
    

    继承体系中生成表的情况

    @Entity
    @Table(name="person")
    @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)// 所有的持久化都会生成表(子类会把父类中的属性继承过来生成在自己的表中)
    public class Person{}
    
    @Entity
    public class Student{}
    
    注意:
        所有的持久化都会生成表(子类会把父类中的属性继承过来生成在自己的表中)
        这种策略主键不能用自增长
        查询时会出现union运算
    

    总结保存List/Set/Map

    List
        @ElementCollection
        @CollectionTable
        @OrderColumn
        @Embeddable - 注解集合中的类
    Set
        @ElementCollection
        @CollectionTable
        @Embeddable - 注解集合中的类
    Map
        @ElementCollection
        @CollectionTable
        @MapKeyColumn
        @Embeddable - 注解集合中的类
    

    保存List

    Person.java
        @ElementCollection(fetch=FetchType.LAZY,targetClass=String.class)
        @CollectionTable(name="address")
        @OrderColumn(name="a_id")
        private List<String> address = new ArrayList<String>();
        
    注意:
        @OrderColumn(name="a_id") 
            a_id是自增长id
        @CollectionTable(name="address")
            address是表名
            生成的address表中会有一个Person_id 是Person的主键id
            
    
    @Embeddable     
    Address.java
        里面就是一些属性,可以没有主键
        此类不会生成表
    User.java
        @ElementCollection(fetch=FetchType.LAZY,targetClass=Address.class)
        @CollectionTable(name="user_address")
        @OrderColumn(name="u_a_id")
        private List<Address> address = new ArrayList<Address>();
        
    注意:
        @OrderColumn(name="u_a_id")
            u_a_id 是自增长的id
        @CollectionTable(name="user_address")
            user_address是表名
            生成的user_address表中会有一个User_id是user表的主键id
    

    保存Set

    Person.java
        @ElementCollection(fetch=FetchType.LAZY,targetClass=String.class)
        @CollectionTable(name="p_address")
        private Set<String> address = new HashSet<String>();
    
    注意:
        @CollectionTable(name="p_address")
            p_address 是表名
            在表中会有一个Person_id是person表中的主键
            
    
    @Embeddable
    Address.java
        里面就是一些属性,可以没有主键
        此类不会生成表
    User.java
        @ElementCollection(fetch=FetchType.LAZY,targetClass=Address.class)
        @CollectionTable(name="user_address")
        private Set<Address> address = new HashSet<Address>();
        
    注意:
        @CollectionTable(name="user_address")
            user_address 是表名
            在表中会有一个User_id是user表中的主键
    

    保存Map

    Person.java
        @ElementCollection(fetch=FetchType.LAZY,targetClass=String.class)   
        @CollectionTable(name="p_address")
        @MapKeyColumn(name="m_key")
        private Map<String,String> address = new HashMap<String,String>();
    
    注意:
        @MapKeyColumn(name="m_key")
            是Map的键
        @CollectionTable(name="p_address")
            是表名 
            在生成的表中会有一个Person_id对应person表中的id
            
    
    @Embeddable
    Address.java
        里面就是一些属性,可以没有主键
        此类不会生成表
    User.java
        @ElementCollection(fetch=FetchType.LAZY,targetClass=Address.class)
        @CollectionTable(name="user_address")
        @MapKeyColumn(name="map_key")
        private Map<String,Address> address = new HashMap<String,Address>();
            
    注意: 
        @MapKeyColumn(name="map_key")
            是Map的键
        @CollectionTable(name="user_address")
            是表名
            在生成的表中会有一个User_id对应user表中的id
    

    总结

    双向关联
        多对多
        多对一
        一对多
        一对一
    单向关联
        多对多
        多对一
        一对多
        一对一
    
    双向关联
        先保存主表,再保存从表
            有mappedBy的类中是主表。
            
    单向关联
        先保存主表,再保存从表
            有@JoinColumn的类是从表。
    

    单向关联-一对一

    Teacher.java
        @OneToOne(fetch=FetchType.LAZY,targetEntity=Student.class)
        @JoinColumn(name="s_id",unique=true,referencedColumnName="sid")
        private Student student;
    Student.java
        private int sid;
    
    注意:
        @JoinColumn(name="s_id",unique=true,referencedColumnName="sid")
            name:在teacher表中创建一个s_id的字段,用来存储一条student数据的sid
            referencedColumnName:关联student表中的sid字段
    

    单向关联-一对多

    Teacher.java
        private int tid;
        @OneToMany(fetch=FetchType.LAZY,targetEntity=Student.class)
        @JoinColumn(name="t_id",referencedColumnName="tid")
        private Set<Student> students = new HashSet<Student>();
        
    Student.java - 保存外键
        private int sid;
            
    注意:     
        @JoinColumn(name="t_id",referencedColumnName="tid")
            name :会在student表中添加t_id字段,关联的是teacher表中的tid字段。
    

    单向关联-多对一

    Teacher.java
        private int tid;
    
    Student.java - 保存外键
        @ManyToOne(fetch=FetchType.LAZY,targetEntity=Teacher.class)
        @JoinColumn(name="t_id",referencedColumnName="tid")
        private Teacher teacher;
        
    注意:
        @JoinColumn(name="t_id",referencedColumnName="tid")
            name :会在student表中创建一个t_id字段,关联teacher表中的tid字段
    

    单向关联-多对多

    Teacher.java
        private int tid;
        @ManyToMany(fetch=FetchType.LAZY,targetEntity=Student.class)
        @JoinTable(name="t_tech_stu",
                   joinColumns=@JoinColumn(name="t_id",referencedColumnName="tid"),
                   inverseJoinColumns=@JoinColumn(name="s_id",referencedColumnName="sid"))
        private Set<Student> students = new HashSet<Student>();
        
    Student.java
        private int sid;
        
    注意:
        @JoinTable(name="t_tech_stu",
                   joinColumns=@JoinColumn(name="t_id",referencedColumnName="tid"),
                   inverseJoinColumns=@JoinColumn(name="s_id",referencedColumnName="sid"))
            name :是中间表名
            joinColumns :
            inverseJoinColumns :
    

    双向关联-一对一

    Teacher.java
        private int tid;
        @OneToOne(fetch=FetchType.LAZY,targetEntity=Student.class,mappedBy="teacher")
        private Student student;
    Student.java
        private int sid;
        @OneToOne(fetch=FetchType.LAZY,targetEntity=Teacher.class)
        @JoinColumn(name="t_id",referencedColumnName="tid",unique=true)
        private Teacher teacher;
        
    注意:
        @JoinColumn(name="t_id",referencedColumnName="tid",unique=true)
            name :在student表中创建一个t_id的字段,关联teacher表中的tid字段
            
        @OneToOne(fetch=FetchType.LAZY,targetEntity=Student.class,mappedBy="teacher")
            mappedBy :表示teacher表不维护关联字段。交给student表管理。
    

    双向关联-一对多

    Teacher.java
        private int tid;
        @OneToMany(fetch=Fetch.LAZY,targetEntity=Student.class,mappedBy="teacher")
        private Set<Student> students = new HashSet<Student>();
        
    Student.java
        private int sid;
        @ManyToOne(fetch=Fetch.LAZY,targetEntity=Teacher.class)
        @JoinColumn(name="t_id",referencedColumnName="tid")
        private Teacher teacher;
        
    注意:
        @JoinColumn(name="t_id",referencedColumnName="tid")
            name :在student表中创建一个t_id字段,关联teacher表中的tid字段
        
        @OneToMany(fetch=Fetch.LAZY,targetEntity=Student.class,mappedBy="teacher")
            mappedBy :表示不维护关联字段
    

    双向关联-多对多

    Teacher.java
        private int tid;
        @ManyToMany(fetch=FetchType.LAZY,targetEntity=Student.class,mappedBy="teachers")
        private Set<Student> students = new HashSet<Student>();
    
    Student.java
        private int sid;
        @ManyToMany(fetch=FetchType.LAZY,targetEntity=Teacher.class)
        @JoinTable(name="t_teach_stu",
                   joinColumns=@JoinColumn(name="s_id",referencedColumnName="sid"),
                   inverseJoinColumns=@JoinColumn(name="t_id",referencedColumnName="tid"))
        private Set<Teacher> teachers = new HashSet<Teacher>();
    
            
    注意:
        @ManyToMany(fetch=FetchType.LAZY,targetEntity=Student.class,mappedBy="teachers")
            mappedBy : 表示不维护外键
            
        @JoinTable(name="t_teach_stu",
                   joinColumns=@JoinColumn(name="s_id",referencedColumnName="sid"),
                   inverseJoinColumns=@JoinColumn(name="t_id",referencedColumnName="tid"))
            name :中间表名
            joinColumns :
            inverseJoinColumns :
    

    相关文章

      网友评论

          本文标题:hibernate

          本文链接:https://www.haomeiwen.com/subject/zhbuextx.html