SSH整合JPA+Mysql
一、什么是JPA:
(1)JPA(Java Persistence API)即Java持久化規范,他為Java開發人員提供了一種對象/關系映射工具來管理Java應用中的關心數據,目的是結束現在Hibernate、TopLink、JDO等ORM框架各自為營的局面。JPA是在充分吸收了現有的Hibernate、TopLink、JDO等ORM框架的基礎上發展而來的,具有易于使用、伸縮性強等優點。
(2)JPA的總體思想和現有Hibernate、TopLink、JDO等ORM框架大體一致。總的來說,JPA包括以下3方面的技術:
①ORM映射元數據:
JPA支持XML和JDK5.0注解兩種元數據的形式,元數據描述對象和表之間的映射關系,框架據此將實體對象持久化到數據庫表中;
②API:
用來操作實體對象,執行CRUD操作,框架在后臺替代我們完成所有的事情,開發者從繁瑣的JDBC和SQL代碼中解脫出來。
③查詢語言:
這是持久化操作中很重要的一個方面,通過面向對象而非面向數據庫的查詢語言查詢數據,避免程序的SQL語句緊密耦合。
(3)提示:JPA不是一種新的ORM框架,他的出現只是用于規范現有的ORM技術,他不能取代現有的Hibernate、TopLink等ORM框架。相反,在采用JPA開發是,我們仍將使用到這些ORM框架,只是此時開發出來的應用不再依賴與某個持久愛化框架提供商。應用可以在不修改代碼的情況下在任何JPA環境下運行,做到真正低耦合,可擴展的程序設計。
?
二、基于Hibernate實現JPA的簡單程序:
1、導入所需要的pom.xml文件依賴:
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>${hibernate.version}</version></dependency>2、創建并編寫persistence.xml文件,名稱和路徑都是固定的,位于類路徑的META-INF目錄下,如果是maven工程,則是在src/main/resources/METE-INF路徑下。
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <!-- Name屬性用于定義持久化單元的名字 (name必選,空值也合法); --> <!-- transaction-type 指定事務類型(可選):本地RESOURCE_LOCAL;和全局JTA,一般用本地就可以了 --> <persistence-unit name="jpatest" transaction-type="RESOURCE_LOCAL"> <!-- <provider>org.hibernate.ejb.HibernatePersistence</provider> --><properties> <!-- 連接數據庫 --><property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver" /> <property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/jpatestdatabase?useUnicode=true&characterEncoding=UTF-8" /><property name="hibernate.connection.username" value="root" /> <property name="hibernate.connection.password" value="admin" /> <!-- 設置數據庫方言 --><property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.max_fetch_depth" value="3" /> <property name="hibernate.hbm2ddl.auto" value="update"/> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /><property name="hibernate.jdbc.fetch_size" value="18" /><property name="hibernate.jdbc.batch_size" value="10" /></properties> </persistence-unit> </persistence>persistence-uni標簽的name屬性:持久化單元的名字,這個屬性必須要有,用來后面的EntityManagerFactory生成實例的名字。
transaction-type:使用的實物類型,默認是RESOURCE_LOCAL事務,還有一個是JTA事務。
provide:EJB Persistence provide 的一個實現類,可以分為不同的ORM,例如MyBatis和Hibernate。
properties:配置數據庫廠商的屬性,比如SQL-server和mysql、Oracle等。
3、創建實體類:(可以使用標簽設置實體類屬性)
package com.zwp.bean; //注解標簽都是是位于javax的包。 import java.util.Date;import javax.persistence.Basic; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.EnumType; import javax.persistence.Enumerated; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.Lob; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType; import javax.persistence.Transient;/* @Table(name="p_table")指定數據庫表名,我所導入的jar存在沖突,會拋出異常, 可以直接使用@Entity(name="p_table")來指定表名就可以解決這個問題了, 但是如果使用這種方式修改表名,就不能創建Query對象,會拋出異常。*/ //指定需要映射的類 @Entity public class Person {public Person() {}public Person(String name) {this.name = name;}private Integer id;//主鍵private String name;private Date birthday;//時間類型private Gender gender=Gender.MAN;//枚舉類型,設置默認值是MANprivate String info;//大文本類型private Byte[] file;//二進制類型private String imagepath;//不在數據庫中生成相應的字段//@Id,設置主鍵可以標注在屬性上面,也可以標注在get方法上面,通常標識在get方法上面//@GeneratedValue設置主鍵增長類型,AUTO是默認值,可以省略,JPA只提供整形自增長方式,沒有提供uuid的增長方式@Id @GeneratedValue(strategy=GenerationType.AUTO)public Integer getId() {return id;}public void setId(Integer id) {this.id = id;}//設置字段的規范:length,字段長度;nullable,非空;name,字段名稱;@Column(length=10,nullable=false,name="personname")public String getName() {return name;}public void setName(String name) {this.name = name;}//設置時間在數據庫中的格式@Temporal(TemporalType.DATE)public Date getBirthday() {return birthday;}public void setBirthday(Date birthday) {this.birthday = birthday;}//枚舉類型@Enumerated(EnumType.STRING) @Column(length=5,nullable=false)public Gender getGender() {return gender;}public void setGender(Gender gender) {this.gender = gender;}//@Lob標明info在數據庫的字段是大文本類型@Lobpublic String getInfo() {return info;}public void setInfo(String info) {this.info = info;}//@Lob標明file在數據庫的字段是存放二進制類型//@Basic(fetch=FetchType.LAZY)標識該字段延遲加載,一般用于大內存數據@Lob @Basic(fetch=FetchType.LAZY)public Byte[] getFile() {return file;}public void setFile(Byte[] file) {this.file = file;}//@Transient標明不在數據庫中生成相應的字段@Transientpublic String getImagepath() {return imagepath;}public void setImagepath(String imagepath) {this.imagepath = imagepath;}}枚舉類:
package com.zwp.bean; //性別的枚舉 public enum Gender {MAN,WOMEN }4、測試類:基本的JPA的增刪改查
(1)添加Person對象:
//添加操作@Testpublic void save(){ //創建factory,方法的參數是持久化單元的名稱,在此時創建數據庫的表EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");//得到EntityManager對象EntityManager entityManager=factory.createEntityManager();//開始事務entityManager.getTransaction().begin();entityManager.persist(new Person("小明"));//此時是new狀態//提交事務entityManager.getTransaction().commit();//關閉entityManager.close();factory.close(); }(2)獲取對象:
//獲取數據1@Testpublic void getPerson(){ EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");EntityManager entityManager=factory.createEntityManager();//開始事務: //讀取數據是不需要開啟事務的,只有需要修改數據庫中的內容的時候才需要開啟事務Person person =entityManager.find(Person.class,1);//此時是managed托管狀態//執行業務操作,用了一分鐘,如果有人在這個時間段更改了數據,則使用刷新方法。entityManager.refresh(person);//刷新數據,不能重新使用find方法,因為只會去一級緩存里面找,因此不會更新數據System.out.println(person.getName());//關閉entityManager.close();factory.close(); } //獲取數據2:延遲加載@Testpublic void getPerson2(){ EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");EntityManager entityManager=factory.createEntityManager();//延時加載:Person person =entityManager.getReference(Person.class,1);//此時得到的是一個代理對象,沒有裝載數據System.out.println(person.getName());//在訪問的時候才會去裝載數據,如果在person對象不存在,再此處訪問會拋出異常//關閉entityManager.close();factory.close(); }(3)修改對象:
//更新操作1@Testpublic void update(){ //創建factory,方法的參數是持久化單元的名稱,在此時創建數據庫的表EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");//得到EntityManager對象EntityManager entityManager=factory.createEntityManager();//開始事務entityManager.getTransaction().begin();Person person=entityManager.find(Person.class, 1);//此時實體對象是managed托管狀態person.setName("小張");//先查再修改//提交事務entityManager.getTransaction().commit();//關閉entityManager.close();factory.close(); } //更新操作2@Testpublic void update2(){ //創建factory,方法的參數是持久化單元的名稱,在此時創建數據庫的表EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");//得到EntityManager對象EntityManager entityManager=factory.createEntityManager();//開始事務entityManager.getTransaction().begin();Person person=entityManager.find(Person.class, 1);//此時實體對象是managed托管狀態entityManager.clear();//把實體管理器中的所有實體變成游離狀態person.setName("維鵬");entityManager.merge(person);//把實體變成托管狀態,如果不變回托管狀態,數據不會同步到數據庫中//提交事務entityManager.getTransaction().commit();//關閉entityManager.close();factory.close(); }(4)刪除對象:
//刪除操作@Testpublic void delete(){ //創建factory,方法的參數是持久化單元的名稱,在此時創建數據庫的表EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");//得到EntityManager對象EntityManager entityManager=factory.createEntityManager();//開始事務entityManager.getTransaction().begin();Person person=entityManager.find(Person.class, 1);//此時實體對象是managed托管狀態entityManager.remove(person);//先查再刪//提交事務entityManager.getTransaction().commit();//關閉entityManager.close();factory.close(); }(5)在上面的幾個測試例子中,提到了實體類的三種不同的狀態,包含:New狀態、manager托管狀態、游離狀態。感興趣的可以自己再去了解一下。
5、測試類:JPQL語句:Query對象的增刪改查:
(1)查詢語句:
//JPQL://query查詢操作:@Testpublic void query(){ EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");EntityManager entityManager=factory.createEntityManager();entityManager.getTransaction().begin();//取得集合對象Query query=entityManager.createQuery("select o from Person o");List<Person> list=query.getResultList();//得到一個集合對象,通過遍歷得到里面的數據for(Person person:list){System.out.println(person.getName());}//取得單一對象//3:表示問號的索引值Query query1=entityManager.createQuery("select o from Person o where o.id =?3");query1.setParameter(3, 1);//第一個參數是問號的索引,第二個參數是id值Person person=(Person) query1.getSingleResult();//獲得單一數據//相當于hibernate的session.createQuery.uniqueResult();System.out.println(person.getName());//取得統計對象:Query query2=entityManager.createQuery("select count(o) from Person o");Long lcount=(Long) query2.getSingleResult();//相當于hibernate的session.createQuery.uniqueResult();int count=lcount.intValue();//先轉成Lon類型再轉成int類型System.out.println(count);entityManager.getTransaction().commit(); entityManager.close();factory.close(); }(2)修改語句:
//query修改操作:@Testpublic void updatequery(){ EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");EntityManager entityManager=factory.createEntityManager();entityManager.getTransaction().begin();Query query=entityManager.createQuery("update Person o set o.name=:name where o.id=:id");query.setParameter("name", "xxx");query.setParameter("id", 1);query.executeUpdate();entityManager.getTransaction().commit(); //關閉entityManager.close();factory.close(); }(3)刪除語句:
//query刪除操作@Testpublic void deletequery(){ EntityManagerFactory factory=Persistence.createEntityManagerFactory("jpatest");EntityManager entityManager=factory.createEntityManager();entityManager.getTransaction().begin();Query query=entityManager.createQuery("delete from Person o where o.id=?1");query.setParameter(1, 1);query.executeUpdate();entityManager.getTransaction().commit(); //關閉entityManager.close();factory.close(); }至此,一個簡單的JPA增刪改查程序就完成了。
這個小DEMO中,獲取EntityManagerFactory對象的方式,是通過persistence.xml文件手動獲取的。在下篇博客將介紹另一種獲取EntityManagerFactory對象的方式,即通過Spring注入方式獲取。
第二種方式可以看這篇博客:https://blog.csdn.net/a745233700/article/details/81415550
?
三、搭建SSH+JPA+Mysql整合項目:
SSH框架的搭建以及與Mysql數據庫的整合這里就不進行介紹了,感興趣的可以參考這篇博客:
https://blog.csdn.net/a745233700/article/details/81193652
這個主要介紹JPA與SSH的整合:
1、添加hibernate-entitymanager的maven依賴:
<dependency><groupId>org.hibernate</groupId><artifactId>hibernate-entitymanager</artifactId><version>${hibernate.version}</version></dependency>2、創建并編寫persistence.xml文件:
注意文件的路徑和文件名,參看上面的程序寫道的路徑和命名(因為數據源在其他地方配置,所有該文件很簡潔)
<?xml version="1.0" encoding="UTF-8"?> <persistence xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" version="1.0"> <persistence-unit name="myjpa" transaction-type="RESOURCE_LOCAL"> <properties> <property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" /> <property name="hibernate.max_fetch_depth" value="3" /> </properties> </persistence-unit> </persistence>3、配置EntityManagerFactory:
數據源保持不變,但是FactoryBean由LocalSessionFactoryBean改成LocalContainerEntityManagerFactoryBean:
<!-- SSH與JPA整合:FactoryBean,由LocalSessionFactoryBean改成LocalContainerEntityManagerFactoryBean --><bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"><!-- 讀取src目錄下META-INF下的persistence.xml,value值是persistence-unit標簽的name的值 --><property name="persistenceUnitName" value="myjpa"/> <!-- 數據源 --><property name="dataSource" ref="dataSource" /><!-- 配置JPA提供商的適配器 --><property name="jpaVendorAdapter"><bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"></bean></property><!-- 配置JPA基本屬性 --><property name="jpaProperties"><props><prop key="hibernate.show_sql">true</prop><prop key="hibernate.format_sql">true</prop><prop key="hibernate.hbm2ddl.auto">update</prop></props></property><!-- 配置實體類所在的路徑 --><property name="packagesToScan" value="com.zwp.jpa.domain" /></bean>4、配置事務管理器:
<!-- SSH與JPA整合,事務管理器改為JPA的事務管理器 --><!-- 配置JPA的事務管理器 --><bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"><property name="entityManagerFactory" ref="entityManagerFactory"></property></bean>5、創建實體類進行測試:
在路徑com.zwp.jpa.domain下創建實體類Student:
@Component @Table(name="T_student") @Entity public class Student {@Idprivate Integer id;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;} }5、部署項目,看數據庫是否產生T-student表,如果有,則成功,反之,失敗。
總結
以上是生活随笔為你收集整理的SSH整合JPA+Mysql的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 在eclipse使用git管理项目工程代
- 下一篇: Spring使用JPA进行Dao层的数据