小男孩‘自慰网亚洲一区二区,亚洲一级在线播放毛片,亚洲中文字幕av每天更新,黄aⅴ永久免费无码,91成人午夜在线精品,色网站免费在线观看,亚洲欧洲wwwww在线观看

分享

Spring Data Jpa 詳解 (配置篇)

 quasiceo 2018-08-06

前言:

  JPA全稱Java Persistence API,即Java持久化API,它為Java開(kāi)發(fā)人員提供了一種對(duì)象/關(guān)系映射工具來(lái)管理Java應(yīng)用中的關(guān)系數(shù)據(jù),結(jié)合其他ORM的使用,能達(dá)到簡(jiǎn)化開(kāi)發(fā)流程的目的,使開(kāi)發(fā)者能夠?qū)W⒂趯?shí)現(xiàn)自己的業(yè)務(wù)邏輯上。

  Spring Jpa 能夠簡(jiǎn)化創(chuàng)建 JPA 數(shù)據(jù)訪問(wèn)層和跨存儲(chǔ)的持久層功能,用戶的持久層Dao接口只需要繼承他自己定義好的(倉(cāng)庫(kù))接口,無(wú)需再寫實(shí)現(xiàn)類,就可以實(shí)現(xiàn)對(duì)象的CRUD操作,還有分頁(yè)排序等功能。

 


   寫本章之前本來(lái)想寫一個(gè)SpringMVC的,后來(lái)發(fā)現(xiàn)Jpa的配置可以大大簡(jiǎn)化MVC框架的配置,就先研究研究Spring Data Jpa。

準(zhǔn)備工作:

  •  jar包支持(不用說(shuō)都知道,本章jar包待我會(huì)放在115網(wǎng)盤供下載)
  •    web.xml配置(監(jiān)聽(tīng)Spring容器的裝載)
  •    本章采用的是阿里連接池(Druid),所以web.xml要有相關(guān)的配置
  •    Spring容器的配置(主要為beans和jpa)
  •    Jpa的主要配置(實(shí)體類管理、數(shù)據(jù)源、連接池、事務(wù)等)
  •    實(shí)體類、持久層接口、業(yè)務(wù)層的創(chuàng)建
  •    測(cè)試放在下一章節(jié)中(因?yàn)椴捎昧薙pringJunit單元測(cè)試,點(diǎn)擊前往

 先來(lái)看一下本章節(jié)用到的包結(jié)構(gòu)--如下圖

  


實(shí)例代碼演示:

****************最后我會(huì)把本章的項(xiàng)目打包供下載************注釋部分我盡可能詳細(xì)講解****************

jar包導(dǎo)入.....(略)

web.xml配置

復(fù)制代碼
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www./2001/XMLSchema-instance" xmlns="http://java./xml/ns/javaee" xmlns:web="http://java./xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java./xml/ns/javaee http://java./xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">
  <display-name>springMVC</display-name>
  
  <!-- 同時(shí)加載多個(gè)spring配置文件可用  -->
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>
            classpath:spring-config/*.xml
        </param-value>
  </context-param>
  
  <!-- spring全局監(jiān)聽(tīng) -->
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
  
  <!-- 下面為Druid默認(rèn)配置,過(guò)濾掉多余的url地址 -->
  <filter>
    <filter-name>DruidWebStatFilter</filter-name>
    <filter-class>com.alibaba.druid.support.http.WebStatFilter</filter-class>
    <init-param>
      <param-name>exclusions</param-name>
      <param-value>*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*</param-value>
    </init-param>
    <init-param>
      <param-name>principalSessionName</param-name>
      <param-value>_dest_login_</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>DruidWebStatFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>
  
  <!-- StatViewServlet是一個(gè)標(biāo)準(zhǔn)的Servlet -->
  <servlet>
    <servlet-name>DruidStatView</servlet-name>
    <servlet-class>com.alibaba.druid.support.http.StatViewServlet</servlet-class>
  </servlet>
  <servlet-mapping>
    <servlet-name>DruidStatView</servlet-name>
    <url-pattern>/druid/*</url-pattern>
  </servlet-mapping>
  
  <!-- Spring Servlet,由于把bean全部交給了SpringJap,所以Spring-mvc里面現(xiàn)在為空 -->
  <servlet>
    <servlet-name>springServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>/WEB-INF/spring-mvc.xml</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>springServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>
  
  <!-- 首頁(yè) -->
  <welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
  </welcome-file-list>
</web-app>
復(fù)制代碼

spring-mvc.xml

復(fù)制代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www./schema/beans" xmlns:xsi="http://www./2001/XMLSchema-instance"
    xmlns:context="http://www./schema/context" xmlns:mvc="http://www./schema/mvc"
    xsi:schemaLocation="http://www./schema/mvc http://www./schema/mvc/spring-mvc-3.1.xsd
        http://www./schema/beans http://www./schema/beans/spring-beans-3.1.xsd
        http://www./schema/context http://www./schema/context/spring-context-3.1.xsd">

    <!-- bean配置在spring-jpa.xml里,所以這里暫為空,用來(lái)初始化spring容器-->
</beans>
復(fù)制代碼

spring-jpa.xml

復(fù)制代碼
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www./schema/beans" xmlns:xsi="http://www./2001/XMLSchema-instance"
       xmlns:tx="http://www./schema/tx"
       xmlns:context="http://www./schema/context"
       xmlns:jpa="http://www./schema/data/jpa"
       xmlns:task="http://www./schema/task"
       xmlns:aop="http://www./schema/aop"
       xsi:schemaLocation="http://www./schema/aop http://www./schema/aop/spring-aop-3.1.xsd
        http://www./schema/beans http://www./schema/beans/spring-beans-3.1.xsd
        http://www./schema/tx http://www./schema/tx/spring-tx-3.1.xsd
        http://www./schema/task http://www./schema/task/spring-task-3.0.xsd
        http://www./schema/context http://www./schema/context/spring-context-3.1.xsd
        http://www./schema/data/jpa http://www./schema/data/jpa/spring-jpa.xsd"
       default-lazy-init="true">

    <description>SpringJpa配置</description>
    
    <!-- 如果spring用了jpa,并且類型為L(zhǎng)ocalContainerEntityManagerFactoryBean,則組件注冊(cè)在此配置文件出現(xiàn)即可,其余配置文件可忽略
           使用component來(lái)替代annotation 自動(dòng)注冊(cè)bean, 并保證@Required、@Autowired的屬性被注入\ -->
    <context:component-scan base-package="com.spring.jpa"/>
    
    <!-- spring啟動(dòng)時(shí)掃描項(xiàng)目路徑下的properties文件,后續(xù)用${key }方式取出對(duì)應(yīng)值,這樣可以代碼解耦和,后續(xù)只需修改properties文件即可 -->
    <bean id="propertyPlaceholderConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
        <property name="locations">
            <list>
                <!-- dataSourse連接池相關(guān)屬性,代碼不在此貼出,會(huì)放在打包好的項(xiàng)目里面 -->
                <value>classpath:db.properties</value>
            </list>
        </property>
    </bean>
    
    <!-- 定義實(shí)體管理器工廠
         Jpa配置   LocalContainerEntityManagerFactoryBean這個(gè)選項(xiàng)Spring扮演了容器的角色。完全掌管JPA -->
          點(diǎn)我查看 spring生成EntityManagerFactory的三種方式 
    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
           <!-- 指定數(shù)據(jù)源 -->
        <property name="dataSource" ref="dataSource"/>
        <!-- 指定Jpa持久化實(shí)現(xiàn)廠商類,這里以Hibernate為例 -->
        <property name="jpaVendorAdapter" ref="hibernateJpaVendorAdapter"/>
        <!-- 指定Entity實(shí)體類包路徑 -->
        <property name="packagesToScan" >
            <array>
                <value>com.spring.jpa</value>
            </array>
        </property>
        <!-- 指定JPA屬性;如Hibernate中指定是否顯示SQL的是否顯示、方言等 -->
        <property name="jpaProperties">
            <props>
                <prop key="hibernate.dialect">org.hibernate.dialect.Oracle10gDialect</prop>
                <prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
                <prop key="hibernate.cache.provider_class">org.hibernate.cache.NoCacheProvider</prop>
                <prop key="hibernate.show_sql">true</prop>
                <prop key="hibernate.format_sql">true</prop>
                <prop key="hibernate.hbm2ddl.auto">validate</prop>
            </props>
        </property>
    </bean>
    
    <!-- 重要配置:?jiǎn)⒂脪呙璨⒆詣?dòng)創(chuàng)建代理的功能  -->
    <jpa:repositories base-package="com.spring.jpa"  transaction-manager-ref="transactionManager" entity-manager-factory-ref="entityManagerFactory"/>
    
    <!-- Hibernate對(duì)Jpa的實(shí)現(xiàn) -->
    <bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>

    <!-- Jpa 事務(wù)管理器  -->
    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
        <property name="entityManagerFactory" ref="entityManagerFactory"/>
    </bean>

    <!-- 開(kāi)啟注解事務(wù) -->
    <tx:annotation-driven transaction-manager="transactionManager" proxy-target-class="true" />

    <!-- 數(shù)據(jù)源配置,使用應(yīng)用內(nèi)的DBCP數(shù)據(jù)庫(kù)連接池 -->
    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
        <!--property name="driverClassName" value="${db.driverClass}"/-->
        <property name="url" value="${db.jdbcUrl}" />
        <property name="username" value="${db.user}" />
        <property name="password" value="${db.password}" />

        <!-- 配置初始化大小、最小、最大 -->
        <property name="initialSize" value="${db.initialSize}" />
        <property name="minIdle" value="${db.minIdle}" />
        <property name="maxActive" value="${db.maxActive}" />
        <!-- 配置獲取連接等待超時(shí)的時(shí)間 --> 
        <property name="maxWait" value="${db.maxWait}" />
        <!-- 配置間隔多久才進(jìn)行一次檢測(cè),檢測(cè)需要關(guān)閉的空閑連接,單位是毫秒 -->
        <property name="timeBetweenEvictionRunsMillis" value="${db.timeBetweenEvictionRunsMillis}" />
        <!-- 配置一個(gè)連接在池中最小生存的時(shí)間,單位是毫秒 -->
        <property name="minEvictableIdleTimeMillis" value="${db.minEvictableIdleTimeMillis}" />

        <property name="validationQuery" value="SELECT 'x' from dual" />
        <property name="testWhileIdle" value="true" />
        <property name="testOnBorrow" value="false" />
        <property name="testOnReturn" value="false" />
        <!-- 打開(kāi)PSCache,并且指定每個(gè)連接上PSCache的大小 -->
        <property name="poolPreparedStatements" value="${db.poolPreparedStatements}" /> 
        <property name="maxPoolPreparedStatementPerConnectionSize" value="${db.maxPoolPreparedStatementPerConnectionSize}" />
    </bean>
    
    <!-- 啟動(dòng)對(duì)@AspectJ(面向切面)注解的支持 --> 
    <aop:aspectj-autoproxy />
    
</beans>
復(fù)制代碼

 


  配置好了配置文件后,我們?cè)搧?lái)寫對(duì)應(yīng)的實(shí)體類,Dao,和service了,下面給出簡(jiǎn)單的3個(gè)類:

User 實(shí)體類

User Entity

IUserDao 持久層(jpa對(duì)持久層簡(jiǎn)化的核心基礎(chǔ))

復(fù)制代碼
package com.spring.jpa.user;

import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;

/**
 * 持久層接口
 * @author liuyt
 * @date  2014-10-30 下午2:09:48
 */
@Repository
public interface IUserDao extends PagingAndSortingRepository<User, Long>{
    /**
     * 通過(guò)前面的配置可以看出,Spring 對(duì) JPA 的支持已經(jīng)非常強(qiáng)大,開(kāi)發(fā)者無(wú)需過(guò)多關(guān)注 EntityManager 的創(chuàng)建、事務(wù)處理等 JPA 相關(guān)的處理
     * ***********************************************************************
     * 然而spring對(duì)Jpa的支持不止于此,它要從根本上來(lái)簡(jiǎn)化我們的業(yè)務(wù)代碼                        **
     * 在沒(méi)用使用jpa支持的時(shí)候,我們的代碼應(yīng)該是這樣的:                                    **
     *     1、IUserDao   持久層接口                                                **
     *     2、IUserDaoImpl   持久層實(shí)現(xiàn)類                                            **                
     *     3、IUserService    業(yè)務(wù)層接口.....后面不在列舉                                    **
     * 每寫一個(gè)實(shí)體類,都要衍生出5、6個(gè)類來(lái)對(duì)他進(jìn)行操作,即使有了注解,我們可以依賴注入方式來(lái)拿到實(shí)現(xiàn)類,    **
     * 但是通用的CRUD等操作卻不免在每個(gè)實(shí)現(xiàn)類里聲明,你又說(shuō),我可以定義一個(gè)父類,利用泛型反射原理就可以了,    **
     * 但那樣你還需要為每個(gè)Dao聲明自己的實(shí)現(xiàn)類來(lái)繼承你的父類                                    **
     * ***********************************************************************
     * 那么問(wèn)題來(lái)了...(不是挖掘機(jī)技術(shù))對(duì)持久層的簡(jiǎn)化技術(shù)哪家強(qiáng)?      Spring Data Jpa            **
     * 你唯一要做的就只是聲明持久層的接口,來(lái)繼承他自身已經(jīng)封裝好的持久層接口,正如本類IUserDao一樣        **
     * 可使用的接口有:                                                            **********
     *     Repository:是 Spring Data的一個(gè)核心接口,它不提供任何方法,開(kāi)發(fā)者需要在自己定義的接口中聲明需要的方法。**
     *     CrudRepository:繼承Repository,提供增刪改查方法,可以直接調(diào)用。                            **
     *     PagingAndSortingRepository:繼承CrudRepository,具有分頁(yè)查詢和排序功能(本類實(shí)例)        **
     *     JpaRepository:                         繼承PagingAndSortingRepository,針對(duì)JPA技術(shù)提供的接口            **
     *     JpaSpecificationExecutor:          可以執(zhí)行原生SQL查詢                                    **
     *    繼承不同的接口,有兩個(gè)不同的泛型參數(shù),他們是該持久層操作的類對(duì)象和主鍵類型。                            **
     *********************************************************************************
     */
}
復(fù)制代碼

  這里為了方便演示,就不寫業(yè)務(wù)層接口了,直接上業(yè)務(wù)層service代碼

UserService 業(yè)務(wù)層

復(fù)制代碼
package com.spring.jpa.user;

import java.util.List;
import javax.annotation.Resource;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;
/**
 * User業(yè)務(wù)層,依賴持久層  IUserDao
 * @author liuyt
 * @date  2014-10-30 下午2:37:21
 */
@Service
public class UserService {
    // 推薦用Resource來(lái)替代AutoWrite注解
    @Resource
    private IUserDao userDao;
    
    // 新增用戶
    public void saveUser(User user) {
        userDao.save(user);
    }
    
    // 刪除用戶,參數(shù)也可以為一個(gè)含有id的User對(duì)象
    public void deleteUser(Long id) {
        userDao.delete(id);
    }
    
    // 查詢所有user對(duì)象,findOne為查詢單個(gè)
    public List<User> findAllUsers() {
        return (List<User>) userDao.findAll();
    }
    
    /**
     * 根據(jù)一個(gè)分頁(yè)對(duì)象查詢user集合(還可以添加一個(gè)Store排序?qū)傩裕?     * PageRequest    是spring自己封裝的請(qǐng)求分頁(yè)類,實(shí)現(xiàn)了Pageable接口,包涵從請(qǐng)求中獲得的分頁(yè)屬性(當(dāng)前頁(yè)和大?。┖瞳@取方法
     * 通過(guò)調(diào)用分頁(yè)方法,返回一個(gè)Page<>一個(gè)泛型集合的分頁(yè)對(duì)象,里面包涵了通過(guò)查詢計(jì)算出的各個(gè)屬性和結(jié)果集
     * 詳細(xì)類結(jié)構(gòu)和屬性請(qǐng)參閱源碼
     * @param page
     * @return
     */
    public Page<User> findAllUserByPage(PageRequest page) {
        return (Page<User>) userDao.findAll(page);
    }
}
復(fù)制代碼

 


  至此,整體SpringJpa框架就搭建好了,剩下的就是寫頁(yè)面和控制器進(jìn)行測(cè)試了,這里不做演示,因?yàn)闀?huì)在下一章節(jié)利用SpringJUnit單元測(cè)試,通過(guò)注解的方式進(jìn)行方法測(cè)試,詳情請(qǐng)移步:SpringJUnit4單元測(cè)試


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請(qǐng)注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購(gòu)買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請(qǐng)點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請(qǐng)遵守用戶 評(píng)論公約

    類似文章 更多