目錄
目錄 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指向本表字段名