<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    JPA學習筆記

    目錄
    目錄 1
    一、JPA基礎 2
    1.1 JPA基礎 2
    1.2JPA開發(fā)過程 3
    1.3 實體的生命周期及實體管理器常用方法 4
    二、環(huán)境搭建 5
    2.1 添加JPA支持 6
    2.2 添加配置文件 6
    2.3測試配置 6
    2.4 環(huán)境搭建附表 6
    三、常用注解 12
    3.1 批注完全參考 12
    3.2 ID相關的 12
    3.3主鍵生成策略 13
    3.4字段、添加字段、添加表關聯(lián) 13
    3.5映射相關 14
    3.6其他 14
    四、JPA映射 14
    4.1一對一映射 15
    4.1.1共享主鍵映射 15
    4.1.2關聯(lián)外鍵映射 17
    4.1.3添加表關聯(lián) 17
    4.2一對多關聯(lián) 18
    4.2.1添加字段的一對多、多對一關聯(lián) 18
    4.2.2添加表的一對多、多對一關聯(lián) 19
    4.3多對多關聯(lián) 20
    4.4繼承映射 21
    五、JPQL 21
    六、常見異常 22

     

     

     

     

    一、JPA基礎
    1.1 JPA基礎
    JPA: java persistence api 支持XML、JDK5.0注解倆種元數(shù)據(jù)的形式,是SUN公司引入的JPA ORM規(guī)范


    元數(shù)據(jù):對象和表之間的映射關系


    實體: entity,需要使用Javax.persistence.Entity注解或xml映射,需要無參構造函數(shù),類和相關字段不能使用final關鍵字
     游離狀態(tài)實體以值方式進行傳遞,需要serializable


    JPA是一套規(guī)范、有很多框架支持(如Hibernate3.2以上、Toplink,一般用Hibernate就行 oracle可以用toplink)
      
     JPQL
     1、與數(shù)據(jù)庫無關的,基于實體的查詢語言
     2、操作的是抽象持久化模型
     3、JPQL是一種強類型語言,一個JPQL語句中每個表達式都有類型 
     4、EJBQL的擴展
     5、支持projection(可以查詢某個實體的字段而不需要查詢整個實體)、批量操作(update、delete)、子查詢、join、group by having(group by聚合后 having 聚合函數(shù) 比較 條件)
     
     
     弱類型語言:沒有明顯的類型、根據(jù)情況變化、容易出錯
     強類型語言:沒個變量都有固定的類型。不容易出錯
     
     
     雖然JPA規(guī)范中明確表示無法訪問一個集合關系字段
     
     抽象模型類型:JPQL規(guī)范將一個實體(屬性)中所飲食的各種類型稱為抽象模型類型
      狀態(tài)字段
      關聯(lián)字段
      
     查詢多個字段查出來的是個對象值數(shù)組
    1.2JPA開發(fā)過程
     JPA配置文件聲明持久化單元 --> 配置文件persistence.xml
     編寫帶標注的實體類
     編寫Dao類
     
     
     
    xml配置
     
     事務類型分為:RESOURCE_LOCAL
    本地事務、JTA(java事務API)
     
     注解
      @Entity  將JavaBean標注為一個實體 name屬性
      @Table  數(shù)據(jù)庫中的表,name名稱、catalog數(shù)據(jù)庫名 @Secondary Table/@Secondary Tables多個表
      @Id   定義了實體的主鍵信息
      @GeneratedValue逐漸省城策略
         @GeneratedValue(Strategy = GenerationType.SEQUENCE)
         @SequenceGenerator(name="SEQ_TEST",sequenceName="User_SEQ",allocationSize=25)
      @column  屬性、字段對應的表字段
      @Temporal 屬性是時間類型的話可以細分
         DATE  java.sql.Date
         TIME  java.sql.Time 
         TIMESTAMP java.sql.Timestamp
      @Lob  標注CLOB、BLOB
      @Base 是否延遲加載@Base(fetch = FETCHTYPE.LAZY/FETCHTYPE.EAGER) 
      @Transient 實體bean中,所有非static、非transient狀態(tài)變量、字段都要被持久化
         如果有字段、變量在數(shù)據(jù)庫中沒有對應,標注為transient就可以不被持久化
      標注方式: 標注在字段上
         標注在變量上
      
     實體類寫法:
      1、必須有無參的構造函數(shù)
      2、沒有final類型的變量或方法
      3、不可以是public類型的,只能通過get、set方法讀寫
      
     管理實體
      Persistence
      EntityManagerFactory
      EntityManager
      
      Persistence.createEntityManagerFactory('persistence.xml中配置的persistence unit').createEntityManager()獲取EntityManager
      
    1.3 實體的生命周期及實體管理器常用方法  
      EntityManager聲明周期    Java對象   實體管理器    數(shù)據(jù)庫
       1、 新實體(new)     存在    不存在     不存在    
       2、持久化實體(managed)   存在    存在     存在
       3、分離的實體(detached)   不存在    不存在     存在
       4、刪除的實體(removed)   存在    存在     不存在
       
       
            new  
            ↓persist()  
         find()  ↓  commit()、clear()
        DB  → → → → → → managed  → → → → → → detached
            ↓   ←merge()
            ↓   
            ↓remove()
            removed
       常用方法
       1、persist(Object)       持久化
       2、remove(Object)       刪除對象
       3、find(Class entityClass,Object key)  根據(jù)主鍵查詢
       4、flush()         實體與底層同步,執(zhí)行sql
       5、createQuery()       創(chuàng)建JPQL查詢對象
       5、createNativeQuery()      根據(jù)普通SQL查詢
       5、createNamedQuery()      命名查詢@NamedQuerie標注 
       5、merge(Object)       將一個detached的實體持久化到EntityManager中
       5、close()         關閉管理器
    ———————————————————————————————————————
    javax.persistence.Query   
    int executeUpdate()   執(zhí)行更新、刪除、添加
    Object getSingleResult() 執(zhí)行查詢(返回一條記錄) 
    List getResultList()  執(zhí)行查詢(返回結果鏈表)
    Query setParameter(int position,object value) 給Query對象設置參數(shù)
    Query setMaxResults(int maxResult)    給Query對象設置返回數(shù)
    Query setFirstResult(int firstResult)  給Query對象設置返回偏移
        
        
    參數(shù)查詢(只能用一種)
         命名參數(shù)查詢 "select u from User where id = :uid";  setParameter("uid",value);
         位置參數(shù)查詢

    ------------------------------------------------------------

    Person person = em.find(Person.class,1);
    //相當于Hibernate的get
    Person person = em.getReference(Person.class,1);  
    //相當于Hibernate的load返回一個代理對象
       //注意延遲加載時的 事務沒關閉的時候才好用

    find 如果找不到返回的是個null,這時候下面在調用null的方法報nullpoint異常
    reference相當于延遲加載  如果找不到,會在第一次使用就報EntityNotFound異常
         
      回調函數(shù)(相當于攔截器,下面的方法執(zhí)行前后調用指定的方法)     
        @Prepersist      
        @PostPersist
        @PreRemove
        @PostRemove
        @PreUpdate
        @PostUpdate
        @PostLoad    載入實體時(find、查詢、refresh)

    -----------------------------------------------------------------
    二、環(huán)境搭建
    2.1 添加JPA支持
    1、準備JPA用到的jar包(JPA支持包)
    2、window → preferences → Java → BuildPath → User Libraries
        →new  User Library
        →Add  Jars

    3、項目   → 右鍵 → properties(alt+Enter)
    → Java Build Path  → Libraries
        → Add Library  → User Library  → 自己定義的JPA支持包

    2.2 添加配置文件
     1、項目中SRC目錄下添加META-INF目錄(與Web項目下META-INF同名)
     2、在新添加的META-INF中添加配置文件persistences.xml
      persistence.xml配置信息 (Hibernate)
      數(shù)據(jù)庫連接信息查詢
      主要配置信息:
       事務類型:本地事務、JTA事務
    JPA供應商
      數(shù)據(jù)庫驅動、URL、User、Password
     3、在SRC目錄下添加log4j.properties文件(顯示數(shù)據(jù)庫操作信息的)


    2.3測試配置
     1、MySQL測試數(shù)據(jù)庫
      2、實體注解
     3、JUNIT測試方法

     

     


    2.4 環(huán)境搭建附表

    persistence.xml配置信息
    <?xml version="1.0" encoding="UTF-8"?>
    <persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence  <!-- name="持久化單元命名"  transaction-type="本地事務/JTA" -->
     <persistence-unit name="JPA" transaction-type="RESOURCE_LOCAL">
      <!-- 供應商 -->
      <provider>org.hibernate.ejb.HibernatePersistence</provider>
      
      
      <properties>
       <!-- 參數(shù):數(shù)據(jù)庫驅動名、地址、用戶、密碼、方言、顯示執(zhí)行SQL語句 -->
       <property name="hibernate.connection.driver_class" value=""/>
       <property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver"/>
       <property name="hibernate.connection.url" value="jdbc:mysql://127.0.0.1:3306/JPA"/>
       <property name="hibernate.connection.username" value="root"/>
       <property name="hibernate.connection.password" value="123456"/>
       <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLDialect"/>
       <property name="hibernate.show_sql" value="true"/>
       
       <!-- 其他設置 -->
       <property name="minPoolSize" value="5"/>
       <property name="initialPoolSize" value="10"/>
       <property name="idleConnectionTestPeriod" value="120"/>
       <property name="acquireIncrement" value="10"/>
       <property name="checkoutTimeout" value="3600"/>
       <property name="numHelperThreads" value="4"/>
       <property name="maxStatements" value="400"/>
       <property name="maxStatementsPerConnection" value="20"/>
       <property name="maxIdleTime" value="180"/>
       <property name="acquireRetryAttempts" value="30"/>
       <property name="maxPoolSize" value="200"/>
      
      </properties>
     </persistence-unit>
    </persistence>

    自動創(chuàng)建|更新|驗證數(shù)據(jù)庫表結構。如果不是此方面的需求建議set value="none"。
    容易造成數(shù)據(jù)丟失,一般在測試的時候才用

    <property name="hibernate.hbm2ddl.auto" value="create"></property>、validate  驗證數(shù)據(jù)庫表結構
    create  每次加載Hibernate都會刪除上一次的表結構,根據(jù)model重新生成
    create-drop每次加載創(chuàng)建,sessionFactory關閉表就自動刪除
    update  加載Hibernate就更想你表結構

    環(huán)境測試代碼
    實體注解
    @Entity
    @Table(name="Person")
    public class Person {
     @Id
     @Column(name="pid")
     private Integer id;
     @Column(name="pname")
     private String name;
     public Integer getId() {
      return id;
     }
     public void setId(Integer id) {
      this.id = id;
     }
     public String getName() {
      return name;
     }
     public void setName(String name) {
      this.name = name;
     }
     
    }

    JUNIT測試方法
    public EntityManager testGetEM(){
      EntityManagerFactory emf = Persistence.createEntityManagerFactory("JPA");
      EntityManager em = emf.createEntityManager();
      return em;
     }
     public void testAddPerson(){
      Person p = new Person();
      p.setId(1);
      p.setName("ader");
      EntityManager em = testGetEM();
      EntityTransaction et = em.getTransaction();
      try {
       et.begin();
       em.persist(p);
       et.commit();
      } catch (Exception e) {
       e.printStackTrace();
      }
     }

     MySQL測試數(shù)據(jù)庫
    drop database if exists jpa;
    create database jpa;
    use jpa;
    drop table if exists person;
    drop table if exists  ident;
    drop table if exists  rel;
    create table person(
     pid int primary key auto_increment,
     pname varchar(50)
    )
    ;
    create table ident(
     iid int primary key auto_increment,
     iname varchar(50)
    );
    create table rel(
     personid int,
     identid int
    );

     

     

    JPA支持包
    antlr-2.7.6.jar
    cglib-2.1.3.jar
    classes12.jar
    commons-collections-3.1.jar
    dom4j-1.6.1.jar
    ehcache-1.2.3.jar
    ejb3-persistence.jar
    hibernate3.jar
    hibernate-annotations.jar
    hibernate-cglib-repack-2.1_3.jar
    hibernate-commons-annotations.jar
    hibernate-entitymanager.jar
    javassist-3.4.GA.jar
    jta-1.1.jar
    log4j-1.2.15.jar
    persistence-api-1.0.jar
    slf4j-api-1.5.2.jar
    slf4j-log4j12.jar


    Hibernate核心包(8個文件):hibernate-distribution-3.3.1.GA.ZIP
    -----------------------------------------------------------------
    hibernate3.jar
    lib\bytecode\cglib\hibernate-cglib-repack-2.1_3.jar (CGLIB庫,Hibernate用它來實現(xiàn)PO字節(jié)碼的動態(tài)
    生成,非常核心的庫,必須使用的jar包)
    lib\required\*.jar
    Hibernate注解包(3個文件):hibernate-annotations-3.4.0.GA.ZIP
    -----------------------------------------------------------------
    hibernate-annotations.jar
    lib\ejb3-persistence.jar, hibernate-commons-annotations.jar
    Hibernate針對JPA的實現(xiàn)包(3個文件):hibernate-entitymanager-3.4.0.GA.ZIP
    -----------------------------------------------------------------
    hibernate-entitymanager.jar
    lib\test\log4j.jar, slf4j-log4j12.jar

     


    數(shù)據(jù)庫連接信息查詢
    1、Hibernate JDBC屬性
    屬性名  用途
    hibernate.connection.driver_class jdbc驅動類
    hibernate.connection.url jdbc URL
    hibernate.connection.username 數(shù)據(jù)庫用戶
    hibernate.connection.password 數(shù)據(jù)庫用戶密碼
    hibernate.dialect 數(shù)據(jù)庫方言

    2、驅動包
    Db2:db2java.jar(JDBC直連)
       :db2jcc.jar(Hibernate要用到此驅動jar文件和上面的驅動jar文件)
    sybase:jconn3d.jar
    MSSQL:msbase.jar+mssqlserver.jar+msutil.jar
    MySQL:mysql-connector-java-3.1.12-bin.jar
    Oracle10g:ojdbc14.jar

    3、連接字符串(可以先添加驅動包然后到包里找Driver.class)
    a、MSSQL
    驅動:com.microsoft.jdbc.sqlserver.SQLServerDriver
    地址:jdbc:microsoft:sqlserver://127.0.0.1:1433;DatabaseName=數(shù)據(jù)庫

    b、Oracle10g
    驅動:oracle.jdbc.driver.OracleDriver
    地址:jdbc:oracle:thin:@127.0.0.1:1521:全局標識符

    c、MySQL
    驅動:org.gjt.mm.mysql.Driver
    地址:jdbc:mysql://127.0.0.1:3306/數(shù)據(jù)庫

    d、Access
    驅動:sun.jdbc.odbc.JdbcOdbcDriver
    地址:jdbc:odbc:Driver={MicroSoft Access Driver (*.mdb)};DBQ=c:\\demodb.mdb

    e、DB2
    驅動:COM.ibm.db2.jdbc.net.DB2Driver
    地址:jdbc:db2://127.0.0.1:6789/demodb
    4、Hibernate SQL方言 (hibernate.dialect)
    RDBMS 方言
    DB2 org.hibernate.dialect.DB2Dialect
    DB2 AS/400 org.hibernate.dialect.DB2400Dialect
    DB2 OS390 org.hibernate.dialect.DB2390Dialect
    PostgreSQL org.hibernate.dialect.PostgreSQLDialect
    MySQL org.hibernate.dialect.MySQLDialect
    MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect
    MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect
    Oracle (any version) org.hibernate.dialect.OracleDialect
    Oracle 9i/10g org.hibernate.dialect.Oracle9Dialect
    Sybase org.hibernate.dialect.SybaseDialect
    Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect
    Microsoft SQL Server org.hibernate.dialect.SQLServerDialect
    SAP DB org.hibernate.dialect.SAPDBDialect
    Informix org.hibernate.dialect.InformixDialect
    HypersonicSQL org.hibernate.dialect.HSQLDialect
    Ingres org.hibernate.dialect.IngresDialect
    Progress org.hibernate.dialect.ProgressDialect
    Mckoi SQL org.hibernate.dialect.MckoiDialect
    Interbase org.hibernate.dialect.InterbaseDialect
    Pointbase org.hibernate.dialect.PointbaseDialect
    FrontBase org.hibernate.dialect.FrontbaseDialect
    Firebird org.hibernate.dialect.FirebirdDialect

    -----------------------------------------------------------------
    三、常用注解
    3.1 批注完全參考
    @Entity要將 Java 類指定為 JPA 實體,請使用批注
    詳細信息
     
    3.2 ID相關的
    復合主鍵需要
    1、 實現(xiàn)序列話
    2、 重寫hascode、equal方法
    3、 有構造方法
    @Embeddable 復合主鍵設置可以被引用
    @EmbeddedId 引用獨立復合主鍵ID
    3.3主鍵生成策略
    使用Hibernate的主鍵生成策略生成字符串主鍵
    @Id
    @GenericGenerator(name="generator",strategy="uuid")
    @GeneratedValue(generator="generator")
    @Column(name="id")

    使用Hibernate的主鍵生成策略與其他類共享主鍵
    @Id
     @GenericGenerator(name = "generator",
                 strategy = "foreign",
                  parameters = {
                  @Parameter(name = "property", value = "person")
                })
      @GeneratedValue(generator = "generator")
    @Column(name="cid")
    3.4字段、添加字段、添加表關聯(lián)
    @Column 持久化字段
     可添加、可更新、可為空
     長度、表名、字段名、unique是否唯一

    @JoinColumn
     name 列名
    referencedColumnName指向對象的列名
    unique約束唯一
    @JoinColumns多個連接的列
    @JoinColumns({
    @JoinColumn(name="ADDR_ID", referencedColumnName="ID"),
    @JoinColumn(name="ADDR_ZIP", referencedColumnName="ZIP")
        })
    @JoinTable
    @JoinTable(
    name="EJB_PROJ_EMP",
    joinColumns=@JoinColumn(name="EMP_ID", referencedColumnName="ID"),
    inverseJoinColumns=@JoinColumn(name="PROJ_ID", referencedColumnName="ID")
    )

    3.5映射相關
    @OneToOne
    @ManyToOne
    @ManyToMany
    cascade級聯(lián)、CURD
    fetch一次性全部讀取相關對象,還是lazy加載
    optional 關聯(lián)對象是否允許為空
    targetEntity關聯(lián)對象


    3.6其他
     排序
    @OrderBy("lastname ASC", "seniority DESC")

    共享主鍵
    @PrimaryKeyJoinColumn

    標注為非持久話對象
    @Transient
    時間類型
    @Temporal(TemporalType.…………)
    枚舉類型
    @Enumerated(EnumType.…………)

     

     

    @Lob //聲明屬性對應的是一個大文件數(shù)據(jù)字段。
    @Basic(fetch = FetchType.LAZY) //設置為延遲加載,當我們在數(shù)據(jù)庫中取這條記錄的時候,不會去取
    -----------------------------------------------------------------
    四、JPA映射
    4.1一對一映射
    4.1.1共享主鍵映射
     1、一端提供主鍵、一端共享主鍵
      設置生成策略generator,主鍵值gereratedValue(generator=””)
      uuid字符串ID
      foreign引用別人ID作為自己的主鍵(需要設置引用對象參數(shù))
     2、oneToOne
      targetEntity 關聯(lián)的目標對象,是類名.class形式
    fetch   抓去策略,有關聯(lián)的一起抓去、還是lazy加載
    cascade   級聯(lián)
    mappedBy  本對象被映射為*(在PrimaryKeyJoinColumn的另一端)
     3、PrimaryKeyJoinColumn設置在一端即可
      name    自身字段
      referenceColumnName指向對象的字段
     注意:
    只要一個PrimaryKeyJoinColumn,另一端的oneToOne 設置mappedBy
    都只有一個
    注意:
    1、向共享主鍵的對象設置提供主鍵的對象,然后持久化共享主鍵對象
     2、需要設置級聯(lián)
    3、共享主鍵端維護關系、提供主鍵端被維護使用mappedBy

     
    Person提供主鍵
     @Id
        @GenericGenerator(name = "generator", strategy = "uuid")
        @GeneratedValue(generator = "generator")
     @Column(name="pid")
     private String id;
     
     @Column(name="pname",length=2)
     private String name;

     @OneToOne(mappedBy="person",fetch=FetchType.EAGER,targetEntity=Idcard.class)
     private Idcard idcard;

     Idcard共享主鍵
     @Id
     @GenericGenerator(name = "generator",
                strategy = "foreign",
                parameters = {
                  @Parameter(name = "property", value = "person")
                })
        @GeneratedValue(generator = "generator")
     @Column(name="cid")
     private String id;
     @Column(name="cno")
     private String no;
     @OneToOne(targetEntity=Person.class,fetch=FetchType.EAGER,cascade=CascadeType.ALL)
     @PrimaryKeyJoinColumn(name="id",referencedColumnName="id")
     private Person person;

     @Id
     @GenericGenerator(name = "generator",
                strategy = "foreign",
                parameters = {
                  @Parameter(name = "property", value = "person")
                })
                @GeneratedValue(generator = "generator")
     @Column(name="cid")
     private String id;
     @Column(name="cno")
     private String no;
     @OneToOne(mappedBy="idcard",fetch=FetchType.EAGER,targetEntity=Person.class)
     private Person person;


    使用共享主鍵關聯(lián)
    Person p = new Person();
       p.setName("ader");
       Idcard idcard = new Idcard();
       idcard.setNo("321321");
       idcard.setPerson(p);

     

     


    4.1.2關聯(lián)外鍵映射
     關系的維護端
    @OneToOne(級聯(lián))
     @JoinColumn(name="本表中關聯(lián)字段",referencedColumnName="指向字段")
     被維護端
    @OneToOne(mappedBy=””)

    關系維護端添加一個字段作為外鍵指向被維護段。被維護端聲明mappedBy
    @Entity
     @Table(name="Test_Trousers")
     public class Trousers {
        @Id
        public Integer id;
        @OneToOne
        @JoinColumn(name = "zip_id")
        public TrousersZip zip;
     }

     @Entity
     @Table(name="Test_TrousersZip")
     public class TrousersZip {
        @Id
        public Integer id;
        @OneToOne(mappedBy = "zip")
        public Trousers trousers;
     }
    4.1.3添加表關聯(lián)
     添加關聯(lián)表的一一關聯(lián)
     @OneToOne
     @JoinTable(name ="關聯(lián)表名稱",
      joinColumns = @JoinColumn(name="關聯(lián)本表的字段"),
      inverseJoinColumns = @JoinColumn(name="要關聯(lián)的表的字段")
     )
     @Entity
     @Table(name="Test_People")
     public class People {
        @Id
        public Integer id;
        @OneToOne
        @JoinTable(name ="TestPeoplePassports",
          joinColumns = @JoinColumn(name="perple_fk"),
          inverseJoinColumns = @JoinColumn(name="passport_fk")
        )
        public Passport passport;
     }

     @Entity
     @Table(name="Test_Passport")
     public class Passport {
        @Id
        public Integer id;
        @OneToOne(mappedBy = "passport")
        public People people;
     }

     

    4.2一對多關聯(lián)
      
      我們維護的多是他們的關系 而不是實體所以建議使用添加關系表
      在多的一端:添加字段、或者添加表 設置級聯(lián)添加
      在一端: mappedBy
      用法:new一個一的一端對象  set到多的對象中,在持久化多的一端

     4.2.1添加字段的一對多、多對一關聯(lián)
     manyToOne  多對一
     oneToMany    用一個set存放對象
    添加字段關聯(lián),一般是在多的一端維護關系,設置級聯(lián)。一的一端mappedBy


     @Id
     @GenericGenerator(name="t1",strategy="uuid")
     @GeneratedValue(generator="t1")
     @Column(name="cid")
     private String cid;
     @Column(name="cname")
     private String cname;
     @OneToMany(fetch=FetchType.EAGER,mappedBy="cls")
     private Set<Student> studentSet;


     @Id
     @GenericGenerator(name="t2",strategy="uuid")
     @GeneratedValue(generator="t2")
     @Column(name="id")
     private String id;
     @Column(name="name")
     private String name;
     @ManyToOne(fetch=FetchType.EAGER,cascade=CascadeType.PERSIST,targetEntity=Clas.class)
     @JoinColumn(name="classid",referencedColumnName="cid")
     private Clas cls;


    4.2.2添加表的一對多、多對一關聯(lián)
     多的一端
    @Id
     @GenericGenerator(name="generator",strategy="uuid")
     @GeneratedValue(generator="generator")
     @Column(name="id")
     private String id;
     @Column(name="name")
     private String name;
     @ManyToOne(targetEntity=C.class,cascade = CascadeType.PERSIST)
     @JoinTable(name="csrel",
       joinColumns=@JoinColumn(name="sid",referencedColumnName="id"),
       inverseJoinColumns=@JoinColumn(name="cid",referencedColumnName="cid")
     )
     private C c;
     一的一端
     @Id
     @GenericGenerator(name="generator",strategy="uuid")
     @GeneratedValue(generator="generator")
     @Column(name="cid")
     private String id;
     @Column(name="cname")
     private String name;
     
     @OneToMany(targetEntity=S.class,mappedBy="c")
     private Set<S> sset;


    4.3多對多關聯(lián)
    添加表關聯(lián)

    假設Teacher 和 Student是多對多的關系,具體元數(shù)據(jù)聲明如下:
    pubic class Teacher{       
    @ManyToMany(targetEntity = Student.class, cascade = CascadeType.PERSIST)       
    @JoinTable(table = @Table(name = "M2M_TEACHER_STUDENT"),       
    joinColumns = @JoinColumn(name = "TEACHER_ID", referencedColumnName = "ID"), 
    inverseJoinColumns = @JoinColumn(name = "STUDENT_ID", referencedColumnName = "ID"))       
    public List<Student> getStudents() {
    return students;
    }                                     
    }

    public class Student{       
    @ManyToMany(targetEntity = Teacher.class, mappedBy = "students")       
    public List<Teacher> getTeachers() {              
    return teachers;        }
    }
    ************************************************
    Student student = em.find(Student.class, 1);
    Teacher teacher = em.getReference(Teacher.class, 1);
    student.removeTeacher(teacher);
    在一個事務中
    ************************************************


    4.4繼承映射
    繼承關系映射在同一張表中

    @Entity
    @Table(name = "customer")
    @Inheritance(strategy = InheritanceType.SINGLE_TABLE)
    @DiscriminatorColumn(name = "flag", discriminatorType = DiscriminatorType.STRING)
    public class Customer{
    }

    @Entity
    @DiscriminatorValue(value = "A")
    public class CustomerA extends Customer{
    }

    @Entity
    @DiscriminatorValue(value = "B")
    public class CustomerB extends Customer{
    }

    SINGLE_TABLE:父子類都保存到同一個表中,通過字段值進行區(qū)分。
    JOINED:父子類相同的部分保存在同一個表中,不同的部分分開存放,通過表連 接獲取完整數(shù)據(jù);

    TABLE_PER_CLASS:每一個類對應自己的表,一般不推薦采用這種方式。
    --------------------------------------------------------------
    五、JPQL
    JPQL 是一種強類型語言,一個JPQL語句中每個表達式都有類型。
      JPQL類似Hibernate的HQL
    單字段 返回具體類型
    多字段 返回多個具體類型的數(shù)組

    查詢單個字段,返回List   List<String>
    查詢單個字段,返回List 只有一條記錄 還是List<String>

    查詢多個字段,返回List   List<Object[]>  對象數(shù)組由多個字段值組成
    查詢多個字段,返回List 只有一條記錄 還是List<Object[]>


     一條記錄getSingleResult 多條記錄
    單一字段 單一值對象 List<Object>
    多個字段 值對象組成的數(shù)組 List<Object[]>
    實體對象 一個對象entity List<entity>

    JPA操作的實體
     需要@Entity name注解
     或者是限定詞(com.sunyard.User為全稱,User為限定詞)
    標識變量
     select  u from User;   //這里u就是標識變量
    路徑表達式
     表示福報 +  訪問操作符(.) + 狀態(tài)字段/關聯(lián)字段
     狀態(tài)字段:包括一個實體不代表關聯(lián)關系的任何字段
     關聯(lián)字段:包括了實體中任何有關聯(lián)關系的字段或者屬性
    參數(shù)(select u from User u where uid=?1 and uname=:name)
     ?1    位置參數(shù)setParameter(’name’,’value’)
     :name   命名參數(shù)setParameter(’name’,’value’)
     不建議在SQL語句中直接寫參數(shù),防止注入。

    六、常見異常
    1、異常信息:org.hibernate.hql.ast.QuerySyntaxException: person is not mapped
     異常環(huán)境:查詢
     異常原因:查詢語句中Person類沒有大寫

    2、java.lang.ClassCastException: [Ljava.lang.Object; cannot be cast to java.lang.String
     異常環(huán)境:查詢、遍歷顯示
     異常原因:轉型出錯
     
    3、javax.persistence.NonUniqueResultException: result returns more than one elements
     異常環(huán)境:查詢、getSingleResult
     異常原因:getSingleResult只能獲取一條數(shù)據(jù),而查詢語句返回的是多條數(shù)據(jù)
     
    4、 org.hibernate.PropertyValueException: not-null property references a null or transient value: com.sunyard.entities.Person.name
     異常環(huán)境:數(shù)據(jù)插入
     異常原因:JPA的Entity中一個屬性定義為nullable=false,插入數(shù)據(jù)該字段為null

    5、 執(zhí)行添加沒反應、沒異常
     異常原因:沒有開啟事務、沒有提交事務
     
    6、javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.sunyard.entities.Person
     異常環(huán)境:OneToOne 共享主鍵關聯(lián)
     異常原因:一對一中,一個提供主鍵、另一個共享其主鍵,共享主鍵的對象可以set 提供主鍵的對象 然后添加到數(shù)據(jù)庫中
        方向弄反了 后果就是沒人提供主鍵
       
    7、org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing:   
     異常環(huán)境:多對一添加
     異常原因:在多的一端維護 ,沒有添加級聯(lián)
     
    8、javax.persistence.PersistenceException: [PersistenceUnit: JPA] Unable to configure EntityManagerFactory
     異常原因:很多、實體管理器Factory沒有成功創(chuàng)建,是注解的問題
    9、org.hibernate.MappingException: Unable to find column with logical name: sid in org.hibernate.mapping.
     異常環(huán)境:添加表做多對一關聯(lián)映射
     異常原因:表字段寫反了,name添加表字段名referencedColumnName指向本表字段名

    posted on 2012-11-01 09:05 Mr.lu 閱讀(20243) 評論(3)  編輯  收藏

    評論

    # re: JPA學習筆記 2013-11-20 08:37 qunhao12

    說得很細很全面,收藏了  回復  更多評論   

    # re: JPA學習筆記 2015-06-12 18:02 zuidaima

    springdata jpa相關demo源代碼下載:http://zuidaima.com/share/kjpa-p1-s1.htm  回復  更多評論   

    # re: JPA學習筆記 2016-03-09 18:16 劉高潮

    非常實用  回復  更多評論   


    只有注冊用戶登錄后才能發(fā)表評論。


    網(wǎng)站導航:
     
    <2016年3月>
    282912345
    6789101112
    13141516171819
    20212223242526
    272829303112
    3456789

    導航

    統(tǒng)計

    常用鏈接

    留言簿(2)

    隨筆檔案

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 女人18毛片特级一级免费视频| 成年女人免费视频播放体验区| 国产大片51精品免费观看| 亚洲剧场午夜在线观看| 亚洲免费视频观看| 亚洲人成电影在线观看青青| 亚洲精品视频免费看| 亚洲一区二区三区四区在线观看| 香港a毛片免费观看 | 免费观看美女用震蛋喷水的视频| 亚洲AV永久青草无码精品| 亚洲国产韩国一区二区| 18禁止看的免费污网站| 亚洲一级毛片视频| 午夜私人影院免费体验区| 麻豆亚洲AV成人无码久久精品 | 一区视频免费观看| 亚洲成a人片在线观看日本| 久久午夜伦鲁片免费无码| 亚洲国产精品网站久久| 在线观看成人免费视频| 免费精品视频在线| 拍拍拍又黄又爽无挡视频免费| 亚洲日韩一区二区三区| 成年人网站免费视频| 亚洲日韩精品无码专区加勒比☆| 国产精品公开免费视频| 中国在线观看免费的www| 国产三级免费观看| a级毛片免费在线观看| 亚洲色图.com| 国产精品成人无码免费| 成人影片一区免费观看| 久久亚洲最大成人网4438| 成人免费午间影院在线观看| 一级毛片免费毛片毛片| 亚洲综合精品香蕉久久网97| 四虎影视免费在线| 免费在线观看一级片| 亚洲国产精品无码久久一区二区 | 色偷偷亚洲第一综合|