SpringData 基於SpringBoot快速入門


SpringData 基於SpringBoot快速入門

本章通過學習SpringData 和SpringBoot 相關知識將面向服務架構(SOA)的單點登錄系統(SSO)需要的代碼實現。這樣可以從實戰中學習兩個框架的知識,又可以為單點登錄系統打下基礎。通過本章你將掌握 SpringBoot項目的搭建,Starter pom的使用,配置全局文件,核心注解SpringBootApplication 介紹以及單元測試 SpringBootTest注解的使用。SpringData 的入門使用,Repository接口的使用,查詢方法關鍵字的規則定義,@Query,@Modifying 注解的使用,最后是開發中的建議和遇到的問題。文章底部提供源碼。

SpringBoot 知識

SpringBoot 是一個用於簡化Spring應用搭建開發的框架。開發過程中,我們經常通過配置xml文件來整合第三方技術。而這些重復整合的工作交給了SpringBoot完成。SpringBoot使用"習慣優於配置"的理念幫我們快速搭建並運行項目。對主流的開發框架能無配置集成。筆者用的開發工具是sts(Spring Tool Suite),其操作和eclipse幾乎一致。若沒有這個工具,創建Maven項目是一樣的。

項目搭建

Starter pom

先看看Maven項目核心配置文件 pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<groupId>com.itdragon</groupId>
	<artifactId>springbootStudy</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>war</packaging>
	<name>springbootStudy</name>
	<description>Demo project for Spring Boot</description>
	<!-- 
		添加 spring boot的父級依賴,它是SpringBoot項目的標志
		spring-boot-starter-parent 它是一個特殊的starter,提供了很多相關的Maven依賴,不用再為version而頭疼了,大大簡化了開發
	-->
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.5.9.RELEASE</version>
		<relativePath/> <!-- lookup parent from repository -->
	</parent>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency><!-- 添加web依賴 ,包含spring和springmvc等-->
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency><!-- 添加對jpa的支持,包含spring-data和Hibernate -->
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency><!-- mysql連接的jar包 -->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
		<dependency><!-- 因為SpringBoot內嵌的tomcat不支持jsp頁面,同時SpringBoot也不推薦用jsp -->
           <groupId>org.apache.tomcat.embed</groupId>
           <artifactId>tomcat-embed-jasper</artifactId>
           <scope>provided</scope>
        </dependency>
        <dependency><!-- jsp標簽庫 -->
           <groupId>javax.servlet</groupId>
           <artifactId>jstl</artifactId>
        </dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin><!-- SpringBoot 編譯插件 -->
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

細心的同學會發現該文件中出現大量的 spring-boot-starter-* 的語句。SpringBoot之所以能簡化開發的秘密就在這里------ Starter pom
spring-boot-starter-parent :父級依賴,SpringBoot項目的標志。里面封裝了很多jar的版本
spring-boot-starter-web :對web項目的支持,其中包含了SpringMVC和tomcat
spring-boot-starter-data-jpa :對JPA的支持,其中包含了常用的SpringData和Hibernate,沒有Mybatis哦
spring-boot-starter-tomcat :使用tomcat作為Servlet容器
spring-boot-starter-test :對常用測試框架的支持,如JUnit
還有很多......

配置全局文件

再看看SpringBoot項目全局配置文件 application.properties

# 配置tomcat端口號
server.port=8081

# 配置SpringMVC視圖解析器
spring.mvc.view.prefix=/WEB-INF/views/
spring.mvc.view.suffix=.jsp

# 配置連接池,默認使用的是tomcat的連接池,但實際很少用tomcat的連接池
spring.datasource.url=jdbc:mysql://localhost:3306/jpa?useUnicode=true&characterEncoding=UTF8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# 配置方言 否則提示:Access to DialectResolutionInfo cannot be null when 'hibernate.dialect' not set
spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect
# 自動更新數據庫表結構,也可以是 validate | update | create | create-drop
spring.jpa.properties.hibernate.hbm2ddl.auto=update
# 顯示sql語句
spring.jpa.show-sql=true

全局配置文件可以是application.properties 也可以是 application.yml,建議放在resources目錄下。更多配置: https://github.com/ITDragonBlog/daydayup/blob/master/SpringBoot/SpringData/springbootStudy/src/main/resources/springboot.properties

核心注解

最后是SpringBoot HelloWorld項目的入口類,只需要下面一個java文件,執行main方法,即可實現頁面的跳轉和數據返回的功能。

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

@Controller
@SpringBootApplication
public class SpringbootStudyApplication {
	
	@RequestMapping("/")
	public String index() {
		return "index";
	}
	
	@RequestMapping("hello")
	@ResponseBody
	public String helloWorld() {
		return "Hello SpringBoot !";
	}

	public static void main(String[] args) {
		SpringApplication.run(SpringbootStudyApplication.class, args);
	}
}

@SpringBootApplication:是 SpringBoot 的核心注解,一般用在入口類上。它是一個組合注解,其中主要內容有一下三個
@SpringBootConfiguration:是一個類級注釋,指示對象是一個bean定義的源,可以理解為xml中的beans,一般和 @Bean 注解一起使用。
@EnableAutoConfiguration:啟用 Spring 應用程序上下文的自動配置,試圖猜測和配置您可能需要的bean。自動配置類通常采用基於你的 classpath 和已經定義的 beans 對象進行應用。
@ComponentScan:該注解會自動掃描指定包下的全部標有 @Component、@Service、@Repository、@Controller注解 的類,並注冊成bean

SpringData入口類

package com.itdragon;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class StartApplication {
	
	public static void main(String[] args) {
		SpringApplication.run(StartApplication.class, args);
	}

}

SpringDataJPA 知識

SpringData 是一個用於簡化數據庫訪問,並支持雲服務的開源框架。支持非關系型數據庫(NoSQL) 和 關系型數據庫。其主要目的是使數據庫的訪問變得方便快捷。
SpringData JPA 是由Spring提供的簡化JPA開發的框架,致力於減少數據訪問層的開發量。

POJO層

創建實體類User 表,對應數據庫表名是 itdragon_user,id作為自增長的主鍵,plainPassword是不保存到數據庫的明文密碼。

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.persistence.Transient;

/**
 * 用戶實體類
 * @author itdragon
 *
 */
@Table(name="itdragon_user")
@Entity
public class User {
	
	@Id
	@GeneratedValue(strategy=GenerationType.AUTO)
	private Long id;						// 自增長主鍵
	private String account;					// 登錄的賬號
	private String userName;				// 注冊的昵稱
	@Transient
	private String plainPassword; 			// 登錄時的密碼,不持久化到數據庫
	private String password;				// 加密后的密碼
	private String salt;					// 用於加密的鹽
	private String iphone;					// 手機號
	private String email;					// 郵箱
	private String platform;				// 用戶來自的平台
	private String createdDate;				// 用戶注冊時間
	private String updatedDate;				// 用戶最后一次登錄時間
	
	// 省略get/set/toString 方法
}

Repository接口層

創建UserRepository,這是SpringData 的核心知識點,我們先看代碼

import java.util.List;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.data.repository.query.Param;
import com.itdragon.pojo.User;

/**
 * 核心知識:SpringData Repository 接口
 * 
 * CrudRepository 接口提供了最基本的對實體類的添刪改查操作 
 * - T save(T entity);					//保存單個實體 
 * - T findOne(ID id);					// 根據id查找實體         
 * - void delete(ID/T/Iterable);		// 根據Id刪除實體,刪除實體,批量刪除 
 * PagingAndSortingRepository 提供了分頁與排序功能
 * - <T, ID extends Serializable> 			// 第一個參數傳實體類,第二個參數傳注解數據類型
 * - Iterable<T> findAll(Sort sort); 		// 排序 
 * - Page<T> findAll(Pageable pageable); 	// 分頁查詢(含排序功能)
 * JpaSpecificationExecutor 提供了Specification(封裝 JPA Criteria查詢條件)的查詢功能
 * - List<T> findAll(Specification<T> spec);
 * - Page<T> findAll(Specification<T> spec, Pageable pageable);
 * - List<T> findAll(Specification<T> spec, Sort sort);
 * 
 * 開發建議
 * 1. 這里值列出的是常用方法
 * 2. CrudRepository 中的findAll() 方法要慎用。當數據庫中數據量大,多線程腳本調用findAll方法,系統可能會宕機。
 * 3. CrudRepository 中的deletAll()方法要慎用。這是物理刪除,現在企業一般采用邏輯刪除。
 * 4. PagingAndSortingRepository 和 JpaSpecificationExecutor 能滿足大部分業務需求。
 */
public interface UserRepository extends PagingAndSortingRepository<User, Long>, 
	JpaSpecificationExecutor<User>{
	
	/**
	 * 重點知識:SpringData 查詢方法定義規范
	 * 
	 * 1. 查詢方法名一般以 find | read | get 開頭,建議用find
	 * 	findByAccount : 通過account查詢User
	 * 	account是User的屬性,拼接時首字母需大寫
	 * 2. 支持的關鍵詞有很多比如 Or,Between,isNull,Like,In等
	 * 	findByEmailEndingWithAndCreatedDateLessThan : 查詢在指定時間前注冊,並以xx郵箱結尾的用戶
	 * 	And : 並且
	 * 	EndingWith : 以某某結尾
	 * 	LessThan : 小於
	 * 
	 * 注意
	 * 若有User(用戶表) Platform(用戶平台表) 存在一對一的關系,且User表中有platformId字段
	 * SpringData 為了區分:
	 * findByPlatFormId 	表示通過platformId字段查詢
	 * findByPlatForm_Id 	表示通過platform實體類中id字段查詢
	 * 
	 * 開發建議
	 * 表的設計,盡量做單表查詢,以確保高並發場景減輕數據庫的壓力。
	 */
	
	// 1 通過賬號查用戶信息
	User findByAccount(String account);
	// 2 獲取指定時間內以xx郵箱結尾的用戶信息
	List<User> findByEmailEndingWithAndCreatedDateLessThan(String email, String createdDate);

	/**
	 * 重點知識:使用 @Query 注解
	 * 
	 * 上面的方法雖然簡單(不用寫sql語句),但它有最為致命的問題-----不支持復雜查詢,其次是命名太長
	 * 1. 使用@Query 注解實現復雜查詢,設置 nativeQuery=true 使查詢支持原生sql
	 * 2. 配合@Modifying 注解實現創建,修改,刪除操作
	 * 3. SpringData 默認查詢事件為只讀事務,若要修改數據則需手動添加事務注解
	 * 
	 * 注意
	 * 若@Query 中有多個參數,SpringData 提供兩種方法:
	 * 第一種 ?1 ... ?2 		要求參數順序一致
	 * 第二種 :xxx ... :yyy 	xxx 和 yyy 必須是實體類對應的屬性值,不要求參數順序但參數前要加上@Param("xxx")
	 * 模糊查詢可使用 %xxx%
	 * 
	 * 開發建議
	 * 1. 參數填寫的順序要保持一致,不要給自己添加麻煩
	 * 2. 建議使用@Query,可讀性較高
	 */
	// 3 獲取某平台活躍用戶數量
	@Query(value="SELECT count(u.id) FROM User u WHERE u.platform = :platform AND u.updatedDate <= :updatedDate")
	long getActiveUserCount(@Param("platform")String platform, @Param("updatedDate")String updatedDate);
	
	// 4 通過郵箱或者手機號模糊查詢用戶信息
	@Query(value="SELECT u FROM User u WHERE u.email LIKE %?1% OR u.iphone LIKE %?2%")
	List<User> findByEmailAndIhpneLike(String email, String iphone);
	
	// 5 修改用戶郵箱
	@Modifying
	@Query("UPDATE User u SET u.email = :email WHERE u.id = :id")
	void updateUserEmail(@Param("id") Long id, @Param("email") String email);

       // 6 傳入的值是對象
       @Modifying
       @Query("update Variable v set v.lastSavedValue =:#{#variable.lastSavedValue}, v.lastSavedValueTime =:#{#variable.lastSavedValueTime} where v.id=:#{#variable.id}")
       Variable updateVariableValue(Variable: variable);
	
}

代碼中共有五個方法,每個方法都包含了很多的知識點。
方法一和方法二主要介紹的是SpringData關鍵字的用法。
1 關鍵字的解析
這里用findByPlatFormId() 方法來介紹SpringData 解析查詢方法的流程。
第一步:去除關鍵字findBy
第二步:剩下的PlatFormId 首字母小寫並在User對象中找是否有該屬性,若有則查詢並結束。若沒有則第三步
第三步:platFormId,從右到左截取到第一個大寫字母,再判斷剩下的platForm是否為User對象,如此循環直到結束為止。
2 級聯屬性區分
若查詢的屬性是實體類,為了避免誤會和沖突,用"_"表示屬性中的屬性
3 查詢分頁排序
若findByPlatFormId() 方法想要排序或者分頁,是可以在后面加Pageable,Sort參數。
findByPlatFormId(String platFormId, Pageable pageable)
findByPlatFormId(String platFormId, Sort sort)
4 其他的關鍵字
關鍵字

方法三到方法五主要介紹的是 @Query 注解的使用。
1 傳參方式
索引參數:?n ,n從1開始,表示第一個參數。方法傳入的參數的照順序和個數要和 n 保持一致。
命名參數::key ,傳參必須有 @Param("key") 注解修飾
2 原生的sql
@Query 注解支持本地查詢,即用原生的sql語句。如:@Query(value="xxxx", nativeQuery=true)
3 Modifying
若直接執行修改操作,SpringDataJPA 會提示錯誤信息 Executing an update/delete query 。是因為Spring Data 默認所有的查詢均聲明為只讀事務。
所以我們要在Service層添加 @Transactional 注解。

SpringDataJPA 核心知識Repository接口
1 Repository: 空接口,標識作用,表明任何繼承它的均為Repository接口類
2 CrudRepository: 繼承 Repository,實現了一組 CRUD 相關的方法 
3 PagingAndSortingRepository: 繼承 CrudRepository,實現了一組分頁排序相關的方法
4 JpaRepository: 繼承 PagingAndSortingRepository,實現一組 JPA 規范相關的方法
5 JpaSpecificationExecutor: 不屬於Repository體系,實現一組 JPA Criteria 查詢相關的方法 
PagingAndSortingRepository 和 JpaSpecificationExecutor 基本滿足企業中大部分的需求。也可以自定義Repository,只需繼承 JpaRepository 即可具備了通用的數據訪問控制層的能力。
進入各自接口類中,使用快捷鍵 Ctrl + o 即可查看當前類的所有方法,所以這里就不貼出來了。

Service層

創建UserService 並加上注解 @Transactional

import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.itdragon.common.ItdragonResult;
import com.itdragon.pojo.User;
import com.itdragon.repository.UserRepository;

@Service
@Transactional
public class UserService {
	
	@Autowired
	private UserRepository userRepository;
	
    public ItdragonResult registerUser(User user) {
    	// 檢查用戶名是否注冊,一般在前端驗證的時候處理,因為注冊不存在高並發的情況,這里再加一層查詢是不影響性能的
    	if (null != userRepository.findByAccount(user.getAccount())) {
    		return ItdragonResult.build(400, "");
    	}
    	userRepository.save(user);
    	// 注冊成功后選擇發送郵件激活。現在一般都是短信驗證碼
    	return ItdragonResult.build(200, "");
    }
    
    public ItdragonResult editUserEmail(String email) {
    	// 通過Session 獲取用戶信息, 這里假裝從Session中獲取了用戶的id,后面講解SOA面向服務架構中的單點登錄系統時,修改此處代碼 FIXME
    	long id = 3L;
    	// 添加一些驗證,比如短信驗證
    	userRepository.updateUserEmail(id, email);
    	return ItdragonResult.ok();
    }
    
}

單元測試

SpringBoot 的單元測試,需要用到 @RunWith 和 @SpringBootTest注解,代碼注釋中有詳細介紹。

import java.util.List;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.test.context.junit4.SpringRunner;
import com.itdragon.StartApplication;
import com.itdragon.common.ItdragonUtils;
import com.itdragon.pojo.User;
import com.itdragon.repository.UserRepository;
import com.itdragon.service.UserService;

/**
 * @RunWith	它是一個運行器
 * @RunWith(SpringRunner.class) 表示讓測試運行於Spring測試環境,不用啟動spring容器即可使用Spring環境
 * @SpringBootTest(classes=StartApplication.class)  表示將StartApplication.class納入到測試環境中,若不加這個則提示bean找不到。
 * 
 * @author itdragon
 *
 */
@RunWith(SpringRunner.class)
@SpringBootTest(classes=StartApplication.class)
public class SpringbootStudyApplicationTests {
	
	@Autowired
	private UserService userService;
	@Autowired
	private UserRepository userRepository;

	@Test
	public void contextLoads() {
	}
	
	@Test	// 測試注冊,新增數據
	public void registerUser() {
		User user = new User();
		user.setAccount("gitLiu");
		user.setUserName("ITDragonGit");
		user.setEmail("itdragon@git.com");
		user.setIphone("12349857999");
		user.setPlainPassword("adminroot");
		user.setPlatform("github");
		user.setCreatedDate(ItdragonUtils.getCurrentDateTime());
		user.setUpdatedDate(ItdragonUtils.getCurrentDateTime());
		ItdragonUtils.entryptPassword(user);
		userService.registerUser(user);
	}
	
	@Test	// 測試SpringData 關鍵字
	public void findByEmailEndingWithAndCreatedDateLessThan() {
		List<User> users = userRepository.findByEmailEndingWithAndCreatedDateLessThan("qq.com", ItdragonUtils.getCurrentDateTime());
		System.out.println(users.toString());
	}
	
	@Test	// 測試SpringData @Query 注解和傳多個參數
	public void getActiveUserCount() {
		long activeUserCount = userRepository.getActiveUserCount("weixin", ItdragonUtils.getCurrentDateTime());
		System.out.println(activeUserCount);
	}
	
	@Test	// 測試SpringData @Query 注解,傳多個參數 和 like 查詢
	public void findByEmailAndIhpneLike() {
		List<User> users = userRepository.findByEmailAndIhpneLike("163.com", "6666");
		System.out.println(users.toString());
	}
	
	@Test	// 測試SpringData @Query 注解 和 @Modifying 注解
	public void updateUserEmail() {
		/**
		 * org.springframework.dao.InvalidDataAccessApiUsageException:Executing an update/delete query; nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query
		 * userRepository.updateUserEmail(3L, "update@email.com");
		 */
		userService.editUserEmail("update@email.com");
	}
	
	@Test	// 測試SpringData PagingAndSortingRepository 接口
	public void testPagingAndSortingRepository() {
		int page = 1; 	// 從0開始,第二頁
		int size = 3;	// 每頁三天數據
		PageRequest pageable = new PageRequest(page, size, new Sort(new Order(Direction.ASC, "id")));
		Page<User> users = userRepository.findAll(pageable);
		System.out.println(users.getContent().toString()); // 當前數據庫中有5條數據,正常情況可以打印兩條數據,id分別為4,5 (先排序,后分頁)
	}
	
	@Test	// 測試SpringData JpaSpecificationExecutor 接口
	public void testJpaSpecificationExecutor(){
		int pageNo = 1;
		int pageSize = 3;
		PageRequest pageable = new PageRequest(pageNo, pageSize);
		Specification<User> specification = new Specification<User>() {
			@Override
			public Predicate toPredicate(Root<User> root,
					CriteriaQuery<?> query, CriteriaBuilder cb) {
				Predicate predicate = cb.gt(root.get("id"), 1); // 查詢id 大於 1的數據
				return predicate;
			}
		};
		Page<User> users = userRepository.findAll(specification, pageable);
		System.out.println(users.getContent().toString());	// 當前數據庫中有5條數據,正常情況可以打印一條數據,id為5
	}
	
}

可能存在的問題

項目啟動時提示 Unknown character set: 'utf8mb4'

導致的原因可能是mysql服務器版本安裝不正確,解決方法有兩種。
第一種:換mysql-connector-java jar包版本為 5.1.6 (不推薦); 當前jar版本為 5.1.44。
第二種:重裝mysql版本,當前最新版本是5.7。教程都准備好了。
https://www.cnblogs.com/sshoub/p/4321640.html (mysql安裝)
http://blog.csdn.net/y694721975/article/details/52981377 (mysql卸載)

SpringBoot 連接池配置疑惑

我們只是在全局配置文件中設置了相關值,就完成了連接池的配置,想必大家都有所疑惑。其實當我們在pom.xml文件中加入spring-boot-starter-data-jpa 依賴時,SpringBoot就會自動使用tomcat-jdbc連接池。
當然我們也可以使用其他的連接池。
https://www.cnblogs.com/gslblog/p/7169481.html (springBoot數據庫連接池常用配置)
https://www.cnblogs.com/xiaosiyuan/p/6255292.html (SpringBoot使用c3p0)

STS工具 ctrl + shift + o 重新導包快捷鍵失效

解決方法:preference -> general -> keys ,找到 Organize Imports ,然后 在 When 里面選擇 Editing Java Source

總結

1 SpringDataJPA 是簡化JPA開發的框架,SpringBoot是簡化項目開發的框架。
2 spring-boot-starter-parent 是SpringBoot項目的標志
3 SpringBootApplication 注解是SpringBoot項目的入口
4 SpringData 通過查詢關鍵字和 @Query注解實現對數據庫的訪問
5 SpringData 通過PagingAndSortingRepository 實現分頁,排序和常用的crud操作

源碼地址:https://github.com/ITDragonBlog/daydayup/tree/master/SpringBoot/SpringData

到這里 SpringData 基於SpringBoot快速入門就結束了,如果有什么問題請指教,如果覺得不錯可以點一下推薦。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM