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

     

     

     

     

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


    元數據:對象和表之間的映射關系


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


    JPA是一套規范、有很多框架支持(如Hibernate3.2以上、Toplink,一般用Hibernate就行 oracle可以用toplink)
      
     JPQL
     1、與數據庫無關的,基于實體的查詢語言
     2、操作的是抽象持久化模型
     3、JPQL是一種強類型語言,一個JPQL語句中每個表達式都有類型 
     4、EJBQL的擴展
     5、支持projection(可以查詢某個實體的字段而不需要查詢整個實體)、批量操作(update、delete)、子查詢、join、group by having(group by聚合后 having 聚合函數 比較 條件)
     
     
     弱類型語言:沒有明顯的類型、根據情況變化、容易出錯
     強類型語言:沒個變量都有固定的類型。不容易出錯
     
     
     雖然JPA規范中明確表示無法訪問一個集合關系字段
     
     抽象模型類型:JPQL規范將一個實體(屬性)中所飲食的各種類型稱為抽象模型類型
      狀態字段
      關聯字段
      
     查詢多個字段查出來的是個對象值數組
    1.2JPA開發過程
     JPA配置文件聲明持久化單元 --> 配置文件persistence.xml
     編寫帶標注的實體類
     編寫Dao類
     
     
     
    xml配置
     
     事務類型分為:RESOURCE_LOCAL
    本地事務、JTA(java事務API)
     
     注解
      @Entity  將JavaBean標注為一個實體 name屬性
      @Table  數據庫中的表,name名稱、catalog數據庫名 @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狀態變量、字段都要被持久化
         如果有字段、變量在數據庫中沒有對應,標注為transient就可以不被持久化
      標注方式: 標注在字段上
         標注在變量上
      
     實體類寫法:
      1、必須有無參的構造函數
      2、沒有final類型的變量或方法
      3、不可以是public類型的,只能通過get、set方法讀寫
      
     管理實體
      Persistence
      EntityManagerFactory
      EntityManager
      
      Persistence.createEntityManagerFactory('persistence.xml中配置的persistence unit').createEntityManager()獲取EntityManager
      
    1.3 實體的生命周期及實體管理器常用方法  
      EntityManager聲明周期    Java對象   實體管理器    數據庫
       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)  根據主鍵查詢
       4、flush()         實體與底層同步,執行sql
       5、createQuery()       創建JPQL查詢對象
       5、createNativeQuery()      根據普通SQL查詢
       5、createNamedQuery()      命名查詢@NamedQuerie標注 
       5、merge(Object)       將一個detached的實體持久化到EntityManager中
       5、close()         關閉管理器
    ———————————————————————————————————————
    javax.persistence.Query   
    int executeUpdate()   執行更新、刪除、添加
    Object getSingleResult() 執行查詢(返回一條記錄) 
    List getResultList()  執行查詢(返回結果鏈表)
    Query setParameter(int position,object value) 給Query對象設置參數
    Query setMaxResults(int maxResult)    給Query對象設置返回數
    Query setFirstResult(int firstResult)  給Query對象設置返回偏移
        
        
    參數查詢(只能用一種)
         命名參數查詢 "select u from User where id = :uid";  setParameter("uid",value);
         位置參數查詢

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

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

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

    -----------------------------------------------------------------
    二、環境搭建
    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)
      數據庫連接信息查詢
      主要配置信息:
       事務類型:本地事務、JTA事務
    JPA供應商
      數據庫驅動、URL、User、Password
     3、在SRC目錄下添加log4j.properties文件(顯示數據庫操作信息的)


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

     

     


    2.4 環境搭建附表

    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>
       <!-- 參數:數據庫驅動名、地址、用戶、密碼、方言、顯示執行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>

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

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

    環境測試代碼
    實體注解
    @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測試數據庫
    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用它來實現PO字節碼的動態
    生成,非常核心的庫,必須使用的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的實現包(3個文件):hibernate-entitymanager-3.4.0.GA.ZIP
    -----------------------------------------------------------------
    hibernate-entitymanager.jar
    lib\test\log4j.jar, slf4j-log4j12.jar

     


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

    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=數據庫

    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/數據庫

    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、 實現序列話
    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字段、添加字段、添加表關聯
    @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級聯、CURD
    fetch一次性全部讀取相關對象,還是lazy加載
    optional 關聯對象是否允許為空
    targetEntity關聯對象


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

    共享主鍵
    @PrimaryKeyJoinColumn

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

     

     

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


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

     

     


    4.1.2關聯外鍵映射
     關系的維護端
    @OneToOne(級聯)
     @JoinColumn(name="本表中關聯字段",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添加表關聯
     添加關聯表的一一關聯
     @OneToOne
     @JoinTable(name ="關聯表名稱",
      joinColumns = @JoinColumn(name="關聯本表的字段"),
      inverseJoinColumns = @JoinColumn(name="要關聯的表的字段")
     )
     @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一對多關聯
      
      我們維護的多是他們的關系 而不是實體所以建議使用添加關系表
      在多的一端:添加字段、或者添加表 設置級聯添加
      在一端: mappedBy
      用法:new一個一的一端對象  set到多的對象中,在持久化多的一端

     4.2.1添加字段的一對多、多對一關聯
     manyToOne  多對一
     oneToMany    用一個set存放對象
    添加字段關聯,一般是在多的一端維護關系,設置級聯。一的一端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添加表的一對多、多對一關聯
     多的一端
    @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多對多關聯
    添加表關聯

    假設Teacher 和 Student是多對多的關系,具體元數據聲明如下:
    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:父子類都保存到同一個表中,通過字段值進行區分。
    JOINED:父子類相同的部分保存在同一個表中,不同的部分分開存放,通過表連 接獲取完整數據;

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

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

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


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

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

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

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

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

    posted on 2012-11-01 09:05 Mr.lu 閱讀(20242) 評論(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 劉高潮

    非常實用  回復  更多評論   


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


    網站導航:
     
    <2015年6月>
    31123456
    78910111213
    14151617181920
    21222324252627
    2829301234
    567891011

    導航

    統計

    常用鏈接

    留言簿(2)

    隨筆檔案

    文章檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 亚洲午夜福利在线观看| 亚洲国产精品成人久久| 亚洲婷婷国产精品电影人久久| 亚洲国产精品一区二区第一页| 免费精品国产自产拍在线观看 | 亚洲一区在线观看视频| 高潮内射免费看片| 久久99国产综合精品免费| 国产美女无遮挡免费网站| 久久亚洲国产视频| 亚洲av最新在线观看网址| a毛片免费观看完整| 免费高清小黄站在线观看| 久久综合日韩亚洲精品色| 国产AV日韩A∨亚洲AV电影| 亚洲电影在线免费观看| 中文字幕亚洲一区| 亚洲AV无码之国产精品| 91九色视频无限观看免费| 中文字幕精品亚洲无线码一区 | 国产男女猛烈无遮挡免费网站| 美女视频黄免费亚洲| 国产午夜无码片免费| 日本媚薬痉挛在线观看免费| 久久久国产精品亚洲一区| 伊人久久国产免费观看视频| 成年男女男精品免费视频网站| 亚洲av无码一区二区三区乱子伦 | 国产成人综合亚洲AV第一页| 国产精品成人啪精品视频免费 | 国产亚洲精品无码拍拍拍色欲| 亚洲AV永久无码天堂影院| 免费鲁丝片一级观看| 国产亚洲蜜芽精品久久| 亚洲国产精品自产在线播放| 国产成人亚洲合集青青草原精品 | 亚洲综合精品伊人久久| 8090在线观看免费观看| 亚洲国产日韩女人aaaaaa毛片在线| 国内精品久久久久影院免费| va亚洲va日韩不卡在线观看|