hibernate

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

    
        
    
    
    


主键/联合主键

//主键
@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配置

    
        
        
    
    


继承体系中生成表的情况 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 address = new ArrayList();
    
注意:
    @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 = new ArrayList
(); 注意: @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 address = new HashSet();

注意:
    @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 = new HashSet
(); 注意: @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 address = new HashMap();

注意:
    @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 address = new HashMap();
        
注意: 
    @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 students = new HashSet();
    
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 students = new HashSet();
    
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 students = new HashSet();
    
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 students = new HashSet();

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 teachers = new HashSet();

        
注意:
    @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)