hibernate

AQ#說明

1.基礎(chǔ)的jar包
    required + jpa + mysql數(shù)據(jù)庫連接
    
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 關(guān)系
        數(shù)據(jù)庫表
    M  Mapping 映射
        dao中的增刪改查操作  方式:1.xx.hbm.xml  2.注解
        
    ORM是規(guī)則是概念
    ORM的實現(xiàn)
        hibernate框架
        mybatis框架
        自己代碼實現(xiàn)(反射)
        
3.對dao操作,有哪些選擇襟交,優(yōu)缺點
    1.jdbc
    2.DbUtils組件
    3.自己封裝jdbc工具類邓线,簡化jdbc操作
    4.hibernate框架
    5.mybatis框架
    
    對比
        執(zhí)行效率最高:純jdbc操作
        開發(fā)效率最高:hibernate
        兼容性好:hibernate桑腮,可以跨數(shù)據(jù)庫平臺
        
4.使用步驟:
    1.建庫生宛、建表
    2.寫實體類
    3.寫映射文件
    4.寫數(shù)據(jù)庫配置文件
    5.測試api
        
    
基本映射 base

主鍵映射 
    基本主鍵映射
    復合主鍵映射

復合屬性  compattr
      修改列名2種方式
      
集合映射 collection
    基本數(shù)據(jù)類型/自定義類型
    List
    Set
    Map 
    
關(guān)聯(lián)映射 oneway/bothway
    單向關(guān)聯(lián)(一邊配置關(guān)聯(lián)):oneway
        一對一(1--1):
        一對多(1--N):
        多對一(N--1):
        多對多(N--N):
    雙向關(guān)聯(lián)(兩邊配置關(guān)聯(liá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();
//數(shù)據(jù)庫操作
transaction.commit();

基礎(chǔ)

//1.注解方式
@Entity //把pojo轉(zhuǎn)化成持久化類
@Table(name="user") // 指定表名
public class User {

    @Id //主鍵列
    @GeneratedValue(strategy=GenerationType.AUTO) //自增長
    @Column(name="u_id") //指定數(shù)據(jù)庫列名 如果不寫就跟屬性名一致 (映射列名  )
    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") //規(guī)定長度 和 初始化值
    private int age;
    
    @Column(name="u_address",
            insertable=false, // 不允許插入
            updatable=false)// 不允許修改
    private String address;
    
    @Column(name="u_salary", precision=6, // 總位數(shù)
            scale=2) // 小數(shù)點后面位數(shù)
    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 自增長但是不支持并發(fā)
            assigned 手動指定主鍵的值
            uuid 使用uuid做為主鍵   主鍵是String類型
            foreign 外鍵策略  一對一映射時用到
-->

主鍵/聯(lián)合主鍵

//主鍵
@Entity
@Table(name="user")
public class User {

    /*
     * GenerationType.IDENTITY: 適宜MySQL、SqlServer有自增長列的數(shù)據(jù)庫
     * GenerationType.SEQUENCE:適宜Oracle這種沒有自增長有sequence的數(shù)據(jù)庫
     * GenerationType.AUTO:讓Hibernate根據(jù)數(shù)據(jù)庫方言自動選擇主鍵生成策略
     * GenerationType.TABLE: 適宜所有的數(shù)據(jù)庫,因為它會單獨生成一張表來維護主鍵生成
     * */
    @Id
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;
}


//聯(lián)合主鍵
public class PersonKey implements Serializable{
    private String firstName;
    private String lastName;
}
@Entity
@Table(name="Person")
public class Person {
    @Embedded
    private PersonKey key;
}


//修改聯(lián)合主鍵表中名字-第一種方式
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;
}

//修改聯(lián)合主鍵表中名字-第二種方式
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{}

注意:
    所有的持久化都會生成表(子類會把父類中的屬性繼承過來生成在自己的表中)
    這種策略主鍵不能用自增長
    查詢時會出現(xiàn)union運算

總結(jié)保存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

總結(jié)

雙向關(guān)聯(lián)
    多對多
    多對一
    一對多
    一對一
單向關(guān)聯(lián)
    多對多
    多對一
    一對多
    一對一

雙向關(guān)聯(lián)
    先保存主表法精,再保存從表
        有mappedBy的類中是主表多律。
        
單向關(guān)聯(lián)
    先保存主表痴突,再保存從表
        有@JoinColumn的類是從表。

單向關(guān)聯(lián)-一對一

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表中創(chuàng)建一個s_id的字段狼荞,用來存儲一條student數(shù)據(jù)的sid
        referencedColumnName:關(guān)聯(lián)student表中的sid字段

單向關(guān)聯(lián)-一對多

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字段辽装,關(guān)聯(lián)的是teacher表中的tid字段。

單向關(guān)聯(lián)-多對一

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表中創(chuàng)建一個t_id字段相味,關(guān)聯(lián)teacher表中的tid字段

單向關(guān)聯(lián)-多對多

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 :

雙向關(guān)聯(lián)-一對一

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表中創(chuàng)建一個t_id的字段拾积,關(guān)聯(lián)teacher表中的tid字段
        
    @OneToOne(fetch=FetchType.LAZY,targetEntity=Student.class,mappedBy="teacher")
        mappedBy :表示teacher表不維護關(guān)聯(lián)字段。交給student表管理丰涉。

雙向關(guān)聯(lián)-一對多

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表中創(chuàng)建一個t_id字段拓巧,關(guān)聯(lián)teacher表中的tid字段
    
    @OneToMany(fetch=Fetch.LAZY,targetEntity=Student.class,mappedBy="teacher")
        mappedBy :表示不維護關(guān)聯(lián)字段

雙向關(guān)聯(lián)-多對多

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 :
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市一死,隨后出現(xiàn)的幾起案子玲销,更是在濱河造成了極大的恐慌,老刑警劉巖摘符,帶你破解...
    沈念sama閱讀 216,544評論 6 501
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異策吠,居然都是意外死亡逛裤,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,430評論 3 392
  • 文/潘曉璐 我一進店門猴抹,熙熙樓的掌柜王于貴愁眉苦臉地迎上來带族,“玉大人,你說我怎么就攤上這事蟀给◎觯” “怎么了?”我有些...
    開封第一講書人閱讀 162,764評論 0 353
  • 文/不壞的土叔 我叫張陵跋理,是天一觀的道長择克。 經(jīng)常有香客問我,道長前普,這世上最難降的妖魔是什么肚邢? 我笑而不...
    開封第一講書人閱讀 58,193評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮拭卿,結(jié)果婚禮上骡湖,老公的妹妹穿的比我還像新娘。我一直安慰自己峻厚,他們只是感情好响蕴,可當我...
    茶點故事閱讀 67,216評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著惠桃,像睡著了一般浦夷。 火紅的嫁衣襯著肌膚如雪辖试。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,182評論 1 299
  • 那天军拟,我揣著相機與錄音剃执,去河邊找鬼。 笑死懈息,一個胖子當著我的面吹牛肾档,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播辫继,決...
    沈念sama閱讀 40,063評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼怒见,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了姑宽?” 一聲冷哼從身側(cè)響起遣耍,我...
    開封第一講書人閱讀 38,917評論 0 274
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎炮车,沒想到半個月后舵变,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,329評論 1 310
  • 正文 獨居荒郊野嶺守林人離奇死亡瘦穆,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,543評論 2 332
  • 正文 我和宋清朗相戀三年纪隙,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片扛或。...
    茶點故事閱讀 39,722評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡绵咱,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出熙兔,到底是詐尸還是另有隱情悲伶,我是刑警寧澤,帶...
    沈念sama閱讀 35,425評論 5 343
  • 正文 年R本政府宣布住涉,位于F島的核電站麸锉,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏秆吵。R本人自食惡果不足惜淮椰,卻給世界環(huán)境...
    茶點故事閱讀 41,019評論 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望纳寂。 院中可真熱鬧主穗,春花似錦、人聲如沸毙芜。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,671評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽腋粥。三九已至晦雨,卻和暖如春架曹,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背闹瞧。 一陣腳步聲響...
    開封第一講書人閱讀 32,825評論 1 269
  • 我被黑心中介騙來泰國打工绑雄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人奥邮。 一個月前我還...
    沈念sama閱讀 47,729評論 2 368
  • 正文 我出身青樓万牺,卻偏偏與公主長得像,于是被迫代替她去往敵國和親洽腺。 傳聞我的和親對象是個殘疾皇子脚粟,可洞房花燭夜當晚...
    茶點故事閱讀 44,614評論 2 353

推薦閱讀更多精彩內(nèi)容