在與spring 與jpa(Java持久化API【java Persistence API】)整合以前,最好先去學習一下jpa的一些要求,這樣能夠在整合的時候,剩下更多時間。java
在spring 中使用Jpa 的第一步是要在spring應用上下文中將實體管理器工廠安照bean的形式來進行配置。mysql
1配置實體類管理工廠web
jpa中要獲取EntityManager 實例須要經過EntityManagerFactory來獲取建立。而在JPA中有兩種實體管理器①應用程序管理類型(Application-managed)②容器管理類型的(Container-managed),這裏咱們使用②,由於這種最適合Java EE容器。兩種實體管理器工廠實現同一個接口:EntityManager。而主要區別在於二者對EntityManager的建立上,①是由EntityManagerFactory建立,②則是經過PersistenceProvider的CreateEntityManagerFactory()建立。①對應的 spring中的工廠是:LocalEntityManagerFactoryBean生產EntitymanagerFactory;②對應的LocalContainerEntityManagerFactoryBean。spring
2實例sql
(1)這裏使用maven來管理項目pom.xml:數據庫
使用logback+slf4j來進行日誌的管理,在百度百科中:SLF4J,即簡單日誌門面(Simple Logging Facade for Java),不是具體的日誌解決方案,它只服務於各類各樣的日誌系統。按照官方的說法,SLF4J是一個用於日誌系統的簡單Facade,容許最終用戶在部署其應用時使用其所但願的日誌System,在官網中:可用於各類日誌框架(例如java.util.logging,logback,log4j),容許最終用戶在部署 時插入所需的日誌記錄框架。apache
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.7.12</version>
</dependency>api<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-core</artifactId>
<version>1.1.2</version>
</dependency>
<!-- 對slf4j的整合 -->
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.1.2</version>
</dependency>安全
spring配置mvc
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-tx</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-beans -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-beans</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-context -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
jpa:這裏使用hibernate做爲jpa的實現
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-orm</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.hibernate/hibernate-core -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>4.3.11.Final</version>
</dependency>
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-entitymanager</artifactId>
<version>4.3.11.Final</version>
</dependency>
數據庫
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.38</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.apache.commons/commons-dbcp2 -->
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-dbcp2</artifactId>
<version>2.1.1</version>
</dependency>
若是是web項目也能夠加入springweb
<!-- https://mvnrepository.com/artifact/org.springframework/spring-web -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-web</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<!-- https://mvnrepository.com/artifact/org.springframework/spring-webmvc -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.9.RELEASE</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
</dependency>
2配置
logback簡單配置,jdbc.properties再次省略
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoder 默認配置爲PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
spring-dao.xml配<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx.xsd
>
<context:property-placeholder location="classpath:jdbc.properties"/>
<bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
<property name="driverClassName" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</bean>//代替了jpa的xml配置
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="packagesToScan" value="com.spring.entity"/>
<property name="dataSource" ref="dataSource"/>
<property name="persistenceProvider">
<bean class="org.hibernate.jpa.HibernatePersistenceProvider"></bean>
</property>
<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>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
</props>
</property>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>//事物,在jpa中必須在方法上加上事物處理
<tx:annotation-driven transaction-manager="transactionManager"/>
<context:annotation-config/>
<context:component-scan base-package="springJdbc.controller,com.spring.controller,com.spring.jpa"/>
</beans>
dao
@Repository
@Transactional
public class JpaDao {
Logger log = LoggerFactory.getLogger(this.getClass());//摘自spring實戰,這裏方便你們有更深的瞭解
//有的地方多是@PersistenceUnit,
//private EntityManagerFactory entityManagerFactory;
//調用的時候還要 entityManagerFactory.createEntityManager().persist(user);
//須要注意的是EntityManagerFactory屬性, 它
//使用了@PersistenceUnit註解, 所以, Spring會
//將EntityManagerFactory注入到Repository之中。 有了
//EntityManagerFactory以後, JpaDao 的方法
//就能使用它來建立EntityManager了, 而後EntityManager能夠
//針對數據庫執行操做。 每次咱們都要create一次,還要從新建立一個EntityManager。
//這裏的問題在於EntityManager並非線程安全的, 通常來說並不
//適合注入到像Repository這樣共享的單例bean中。 可是, 這並不意味
//着咱們沒有辦法要求注入EntityManager。 以下的程序清單展示了
//如何藉助@PersistentContext註解爲JpaDao
//設置EntityManager。
//這裏的真相是@PersistenceContext並不會真正注
//入EntityManager——至少, 精確來說不是這樣的。 它沒有將真正
//的EntityManager設置給Repository, 而是給了它一
//個EntityManager的代理。 真正的EntityManager是與當前事務
//相關聯的那一個, 若是不存在這樣的EntityManager的話, 就會創
//建一個新的。 這樣的話, 咱們就能始終以線程安全的方式使用實體管
//理器
//另外, 還須要瞭解@PersistenceUnit和@PersistenceContext
//並非Spring的註解, 它們是由JPA規範提供的
@PersistenceContext
private EntityManager entityManagerFactory;
public void add(User user){
log.info("user name:{}",user.getName());
entityManagerFactory.persist(user);
entityManagerFactory.close();
}public void select (){
String sql = "select * from user";
Query query = entityManagerFactory.createNativeQuery(sql);
List list=query.getResultList();
for(int i=0;i<list.size();i++){
Object[] obj = (Object[])list.get(i);
System.out.println(obj[0]+":"+obj[1]+obj[2]);
}
entityManagerFactory.close();
}
}
實體
@Entity
public class User {@Id
@GeneratedValue
private Integer id;
private String name;
private String password;略getset方法
簡單的controller測試
@Controller
@RequestMapping("/jpa")public class JpaController{
@Autowired
private JpaDao jpaDao;
@Autowired
private UserReporstory userRes;
@RequestMapping(value="/add" ,method=RequestMethod.GET)
public String add(){
jpaDao.select();
return "index.jsp";
}
@RequestMapping(value="/add3" ,method=RequestMethod.GET)
public String add3(){
User user = new User();
user.setName("mdl");
user.setPassword("mdl");
jpaDao.add(user);
return "index.jsp";
}
3在編寫spring與jpa的時候,要寫好多的充分代碼要是用spring data jpa就方便多了
在maven中加入
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-jpa</artifactId>
<version>1.10.5.RELEASE</version>
</dependency>
在spring配置文件中
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa.xsd<jpa:repositories base-package="springdata.dao" repository-impl-postfix="Hill" />
寫一個接口繼承JpaRepository,User是映射的對象,Integer是主鍵的類型
public interface UserRepository extends JpaRepository<User, Integer>{
//它還會繼承18個執行持久化操做的通用方法 ,此時, 你可能會想下一步就該編寫一個類實現 ,若是真是這樣就沒有必要用spring data了
//若是基本方法不能知足你的要求,你能夠自定義User findByName(String name);
//Spring Data容許在方法名中使用四種動詞: get、 read、 find和count ,又想了解的,能夠查閱相關知識
這裏仍是推薦jpa結合spring data jpa,使用jpa實現比較複雜的邏輯
}
public class UserRepositoryHill implements UserTop{
//jpa的實現。能夠參考上面的jpa實現的方法
}
注意, UserRepositoryHill 並無實現
UserRepository接口。 Spring Data JPA負責實現這個接
口。 UserRepositoryHill (將它與Spring Data的Repository關
聯起來的是它的名字) 實現了UserTop, 它以下所
示:public interface UserTop(){
void top();
}
咱們還須要確保top()方法會被聲明
在UserRepository接口中。 要實現這一點, 避免代碼重複的
簡單方式就是修改UserRepository, 讓它擴
展UserTop:public interface UserRepository extends JpaRepository<User, Integer>,UserTop{}
注意UserRepositoryHill 中的Hill,是在spring data jpa中配置的<jpa:repositories base-package="springdata.dao" repository-impl-postfix="Hill" />這裏你能夠隨便制定
測試
@Autowired
private UserReporstory userRes;@RequestMapping(value="/add1" ,method=RequestMethod.GET)
public String add1(){
User user = new User();
user.setName("hary");
user.setPassword("hary");
userRes.save(user);
return "index.jsp";
}
最好但願你們也多點建議: