Spring Data JDBC全解析
一、JPA背景
早期的JPA的特性是懶加載和關(guān)聯(lián)查詢,一下能查出所有的關(guān)聯(lián)信息,但我們開發(fā)者在查詢SQL的時候往往只需要某幾個字段,而JPA甚至關(guān)聯(lián)表的所有字段查詢出來,如果不需要那么多message,那么查詢的性能會大大降低。
Spring官網(wǎng)為此提供了另一個解決方案——spring-data-jdbc, 另一種形式的Java持久化的API工具集,相比JPA來講,更簡單,更高效,沒有session, 一次查詢查詢出指定的結(jié)果,沒有多余數(shù)據(jù),Spring 官網(wǎng)提供了為什么使用它的理由:
1. If you load an entity, SQL statements get run. Once this is done, you have a completely loaded entity. No lazy loading or caching is done.
2. If you save an entity, it gets saved. If you do not, it does not. There is no dirty tracking and no session.
3. There is a simple model of how to map entities to tables. It probably only works for rather simple cases. If you do not like that, you should code your own strategy. Spring Data JDBC offers only very limited support for customizing the strategy with annotations.
簡單總結(jié)就是: 沒有攔截在和緩存,每次執(zhí)行完的SQL得到的就是一個指定想要的完整實體,沒有關(guān)聯(lián)的查詢或更新操作,沒有session, 更簡單、高效。
spring-data-jdbc相比mybatis有哪些好處
其實現(xiàn)在有更好的中間件mybatis和相關(guān)插件能夠幫助我們更好的執(zhí)行sql,spring-data-jdbc和mybatis同樣是基于spring開發(fā)出來的框架,那么他們優(yōu)勢和差別分別是什么
- mybatis: sql與mapper層分離,開發(fā)者可以編寫復(fù)雜的SQL以及動態(tài)SQL,適合查詢復(fù)雜的場景,能夠在xml文件里統(tǒng)一管理SQL文件,缺點是有些場景下需要編寫復(fù)雜的SQL。
- spring-data-jdbc: 無須配置和加載xml映射文件, 簡化開發(fā),對于單表查詢多的場景下,使用spring-boot-data-jdbc會比mybatis更加簡單,另外spring-boot-data-jdbc能夠與mybatis做集成,使用更加靈活,支持配置SqlSessionFactoryBean。缺點是: 復(fù)雜的業(yè)務(wù)系統(tǒng)和場景下,復(fù)雜的SQL難以維護。
Spring-data-jdbc在簡單業(yè)務(wù)場景下的表現(xiàn)會比myabtis更加方便、好用。
二、Spring Boot 整合Spring data JDBC
先看一下目錄結(jié)構(gòu):
jdbc ├─ JdbcApplication.java // main方法 ├─ config │ └─ DataSourceConfig.java // 配置數(shù)據(jù)源,采用druid ├─ controller │ └─ UserController.java // controler ├─ model │ └─ User.java // 實體類 ├─ repository // dao層,與數(shù)據(jù)庫連接層 │ ├─ UserCrudRepository.java │ └─ UserPageRepository.java ├─ service // 服務(wù)層 │ └─ UserService.java └─ util
啟動類的@EnableJdbcRepositories(basePackages = “org.spring.data.jdbc”) 注解也可以放在配置類上。

1. 配置數(shù)據(jù)源
數(shù)據(jù)庫使用mysql,那么首推alibaba的druid數(shù)據(jù)源,druid是國內(nèi)數(shù)據(jù)庫連接性能表現(xiàn)最好且功能強大數(shù)據(jù)庫中間件,druid還有自帶的數(shù)據(jù)庫監(jiān)控工具,能夠監(jiān)控慢sql,sql執(zhí)行的動態(tài)還有預(yù)防sql注入攻擊等功能。
添加pom依賴:
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!-- alibaba druid數(shù)據(jù)源-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>1.1.18</version>
</dependency>
<!--spring-data-jdbc-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>添加數(shù)據(jù)源配置:
server.port=8002 spring.datasource.url=jdbc:mysql://192.168.31.166:3306/my_shop?useUnicode=true&characterEncoding=utf-8&useSSL=false&serverTimezone=Asia/Shanghai spring.datasource.username=root spring.datasource.password=123456 spring.datasource.driver-class-name=com.mysql.jdbc.Driver
下載好jar包后,新建一個配置類DataSourceConfig:
package org.spring.data.jdbc.config;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.support.http.StatViewServlet;
import com.alibaba.druid.support.http.WebStatFilter;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.jdbc.repository.config.AbstractJdbcConfiguration;
import org.springframework.data.jdbc.repository.config.EnableJdbcRepositories;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcOperations;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionManager;
import javax.sql.DataSource;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
@Configuration
@EnableJdbcRepositories(basePackages = "org.spring.data.jdbc")
public class DataSourceConfig extends AbstractJdbcConfiguration {
/**
* 采用阿里數(shù)據(jù)源druid
*
* @return
*/
@ConfigurationProperties("spring.datasource")
@Bean
DataSource dataSource() {
return new DruidDataSource();
}
/**
* Jdbc Template
* @param dataSource
* @return
*/
@Bean
NamedParameterJdbcOperations namedParameterJdbcOperations(DataSource dataSource) {
return new NamedParameterJdbcTemplate(dataSource);
}
/**
* 事務(wù)管理器
* @param dataSource
* @return
*/
@Bean
TransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}2. 配置Druid的admin后臺
Druid提供了一種直接重寫ServletRegistrationBean和FilterRegistrationBean的方式來生成admin后臺管理頁面和過濾器。
//配置Druid監(jiān)控
//admin后臺, 訪問地址: localhost:8002/druid/
@Bean
public ServletRegistrationBean statViewServlet() {
ServletRegistrationBean bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
Map<String, String> initParams = new HashMap<>();
initParams.put("loginUsername", "admin");
initParams.put("loginPassword", "admin");
initParams.put("allow", "localhost");
initParams.put("deny", "0.0.0.0");
bean.setInitParameters(initParams);
return bean;
}
//filter
@Bean
public FilterRegistrationBean webStatFilter() {
FilterRegistrationBean bean = new FilterRegistrationBean();
bean.setFilter(new WebStatFilter());
Map<String, String> initParams = new HashMap<>();
initParams.put("exclusions", "*.js,*.css,/druid/*");
bean.setInitParameters(initParams);
bean.setUrlPatterns(Arrays.asList("/*"));
return bean;
}訪問地址: localhost:8002/druid, 即可進入到admin后臺管理頁面,如下:

輸入配置的賬號admin,密碼admin即可進入到首頁, 如下圖:

3. Spring-data-jdbc常用接口查詢策略
1)CrudRepository 增刪改查
我們可以通過繼承CrudRepository來定義基于Model的增刪改查操作, 也可以使用CrudRepository里提供對數(shù)據(jù)庫增、刪、改查操作的基本API。
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {S save(S entity);
<S extends T> Iterable<S> saveAll(Iterable<S> entities); Optional<T> findById(ID id); boolean existsById(ID id); Iterable<T> findAll(); Iterable<T> findAllById(Iterable<ID> ids); long count(); void deleteById(ID id); void delete(T entity); void deleteAllById(Iterable< extends ID> ids); void deleteAll(Iterable< extends T> entities); void deleteAll();
}
自定義接口方法:
@Repository
public interface UserCrudRepository extends CrudRepository<User, String> {
User findUserById(Integer id);
@Query("select user_name as userName from sys_user where id = :id")
String findUserNameById(@Param("id") Integer id);
}spring-data-jdbc的方便好用、可擴展性進一步顯現(xiàn)出來了,如果想分頁查詢的話,Spring-data-jdbc提供了另外一個接口PagingAndSortingRepository,也可以使用@Query()注解支持原生的sql寫入,參數(shù)使用過@Param()注入,接收的時候按照順序接收,但要用 :id來標記接收對應(yīng)的參數(shù)。
2) PagingAndSortingRepository 分頁排序
@NoRepositoryBean
public interface PagingAndSortingRepository<T, ID> extends CrudRepository<T, ID> {
Iterable findAll(Sort sort);Page<T> findAll(Pageable pageable);}
同樣的該接口類似于CrudRepository接口的用法,可以使用自帶的api,也可以擴展。
package org.spring.data.jdbc.repository;
import org.spring.data.jdbc.model.User;
import org.springframework.data.repository.PagingAndSortingRepository;
public interface UserPageRepository extends PagingAndSortingRepository<User,String> {
//按照id排序
}排序:提供了findAll()方法,Sort.Direction.ASC表示升序,Sort.Direction.DESC表示降序。
/**
* 按照指定字段排序,可以指定升序、降,0升序,1降序
*
* @param sortField 按照指定字段排序
* @param sortRule 排序規(guī)則
* @return
*/
public List<User> findUserBySort(String sortField, Integer sortRule) {
List<User> results = new ArrayList<>();
Iterable<User> userIterable = userPageRepository.findAll(Sort.by(sortRule == 0 ? Sort.Direction.ASC : Sort.Direction.DESC, sortField));
Iterator<User> userIterator = userIterable.iterator();
while (userIterator.hasNext()) {
results.add(userIterator.next());
}
return results;
}分頁:直接使用import org.springframework.data.domain.Pageable 類作為參數(shù)解析分頁的page和size就能實現(xiàn)一個簡單的分頁查詢。
public List<User> findUserByPage(Pageable page) {
return userPageRepository.findAll(page).getContent();
}
controller:
/**
* find all user by page
*/
@GetMapping("/findAllUser/by/page")
@ResponseBody
public List<User> findAllUserBySort(Pageable pageable) {
return userService.findUserByPage(pageable);
}
按照id降序排序查詢, 訪問:localhost:8002/api/user/findAllUser/by/sortsortRule=0&sortField=id,打印結(jié)果:
[
{
“id”:3,
“userName”:“zhangsan”
},
{
“id”:2,
“userName”:“zhangsan”
},
{
“id”:1,
“userName”:“bingbing”
}
]
到此這篇關(guān)于Spring Data JDBC全解析的文章就介紹到這了,更多相關(guān)spring data jdbc內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot layui hutool Excel導(dǎo)入的實現(xiàn)
本文主要介紹了springboot layui hutool Excel導(dǎo)入的實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習或者工作具有一定的參考學(xué)習價值,需要的朋友們下面隨著小編來一起學(xué)習學(xué)習吧2022-03-03
基于java SSM springboot實現(xiàn)景區(qū)行李寄存管理系統(tǒng)
這篇文章主要介紹了基于java SSM springboot實現(xiàn)的景區(qū)行李寄存管理系統(tǒng),本文給大家介紹的非常詳細,對大家的學(xué)習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2021-08-08
SpringMVC 攔截器不攔截靜態(tài)資源的三種處理方式方法
本篇文章主要介紹了SpringMVC 攔截器不攔截靜態(tài)資源的三種處理方式方法,詳細的介紹了三種方法,有興趣的可以了解一下。2017-01-01
java寫卷積神經(jīng)網(wǎng)絡(luò)(CupCnn簡介)
這篇文章主要介紹了java寫卷積神經(jīng)網(wǎng)絡(luò)(CupCnn簡介),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-04-04
淺析Spring Validation參數(shù)校驗的實現(xiàn)原理與進階用法
這篇文章主要介紹了Spring Validation參數(shù)校驗的實現(xiàn)原理與進階用法,本文展示了分組校驗,嵌套校驗,集合校驗等進階功能,并提供了自定義校驗注解的實現(xiàn)方法,希望對大家有所幫助2026-01-01

