Spring Data,是為資料通路提供熟悉且一緻的基于Spring的程式設計模型,同時仍然保留底層資料存儲的特殊特性。
它是對于資料通路技術,關系資料庫和非關系資料庫,map-reduce架構和基于雲的資料服務變得容易。Spring Data是一個總括項目,其中包含很多特定于資料庫相關的子項目。

首先,先帶大家看一下本篇文章的大緻介紹。
沒目錄怎麼知道這篇到底有多少幹貨呢?
- Spring Data是什麼
- Spring Data能幹什麼
- Spring Data的第一個HelloWorld程式
- 通過名字來确定方法
- 通過注解的形式來實作查詢
- 寫本地的SQL查詢
- 增删改的玩法
- 使用架構中提供的增删改查的方法
- 分頁和排序
- JpaRepository的使用
是不是很清晰呢,現在開始進入正文,一個一個來:
我們傳統的開發中,我們的整個DAO層的代碼上都是相對來說,都是比較複雜的,在這種情況下,Spring團隊就考慮到一個問題,能不能開發一個架構,這個架構能夠最大限度的減少DAO層的開發呢?
Spring Data就是為了簡化DAO層操作的一個架構
傳統的增删改查在我們的Spring Data中已經實作了,也就是說大部分的DAO層操作部分不用寫了,僅僅隻是需要編寫複雜的業務的調用就可以啦
寫的這部分的代碼,是需要寫接口的聲明就可以啦,不用寫實作,這個實作是自動實作的
Spring Data能幹什麼
主要用途:
- 傳統的增删改查
- 排序
- 分頁
- 排序後分頁
即使你需要寫DAO,也隻是寫聲明就可以啦,不用寫實作
Spring Data的第一個HelloWorld程式(JPA、Hibernate、Spring、SpringMVC、Spring Data)
導包
編寫配置檔案
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:jpa="http://www.springframework.org/schema/data/jpa"
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
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/data/jpa
http://www.springframework.org/schema/data/jpa/spring-jpa-1.2.xsd">
<!--引入Properties檔案-->
<context:property-placeholder location="classpath:config/db.properties"/>
<!--配置c3p0的連接配接池-->
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${driverClass}"></property>
<property name="jdbcUrl" value="${url}"></property>
<property name="user" value="${user}"></property>
<property name="password" value="${password}"></property>
<property name="acquireIncrement" value="${acquireIncrement}"></property>
<property name="maxPoolSize" value="${maxPoolSize}"></property>
<property name="minPoolSize" value="${minPoolSize}"></property>
<property name="maxStatements" value="${maxStatements}"></property>
</bean>
<!--配置JPA實作産品的擴充卡-->
<bean id="jpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
</bean>
<!--配置EntityManager對象-->
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<!--注入資料源-->
<property name="dataSource" ref="dataSource"></property>
<!--掃描entity包的-->
<property name="packagesToScan" value="com.qy.helloworld"></property>
<!--注入JPA實作産品的擴充卡-->
<property name="jpaVendorAdapter" ref="jpaVendorAdapter"></property>
<!--配置的是Hibernate的其他配置 除了連接配接資料庫4大要素之外的其餘配置-->
<property name="jpaProperties">
<props>
<!--是否自動建立表 -->
<prop key="hibernate.hbm2ddl.auto">update</prop>
<!--配置是否展示SQL-->
<prop key="hibernate.show_sql">true</prop>
<!--是否格式化SQL-->
<prop key="hibernate.format_sql">true</prop>
<!--連接配接資料庫的方言-->
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5Dialect</prop>
</props>
</property>
</bean>
<!--配置事務環境-->
<bean id="jpaTransactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<!--注入dataSource-->
<property name="dataSource" ref="dataSource"></property>
<!--注入entityManagerFactory對象-->
<property name="entityManagerFactory" ref="entityManagerFactory"></property>
</bean>
<!--使用事務-->
<tx:annotation-driven transaction-manager="jpaTransactionManager"/>
<!--配置AOP的自動代理-->
<aop:aspectj-autoproxy></aop:aspectj-autoproxy>
<!--配置Spring的包掃描-->
<context:component-scan base-package="com.qy.helloworld"></context:component-scan>
<!--Spring data的包的掃描 這裡的掃描掃描的是DAO層所在的位置-->
<jpa:repositories base-package="com.qy.helloworld" entity-manager-factory-ref="entityManagerFactory" transaction-manager-ref="jpaTransactionManager"></jpa:repositories>
</beans>
編寫實體類和映射
@Entity
@Table(name="t_user")
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
private int userId;
private String userName;
private String password;
}
編寫Repository類
public interface UserRepository extends Repository<User,Integer>{
/**
* 這個的意思是通過id找使用者
* @Title: getByUserId
* @Description: TODO
* @param: @param userId
* @param: @return
* @return: User
* @throws
*/
public User getByUserId(int userId);
}
測試
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
//擷取DAO的對象
UserRepository userRepository=applicationContext.getBean(UserRepository.class);
User users=userRepository.findByUserId(1);
}
代碼示範:
舉例如下
:
public interface UserRepository extends Repository<User,Integer>{
/**
* 這個的意思是通過id找使用者
* @Title: getByUserId
* @Description: TODO
* @param: @param userId
* @param: @return
* @return: User
* @throws
*/
public User getByUserId(int userId);
/**
* 記住查詢的開頭隻能是 get 或者 find 開頭 By:通過什麼查詢
* @Title: findByUserId
* @Description: TODO
* @param: @param userId
* @param: @return
* @return: User
* @throws
*/
public User findByUserId(int userId);
/**
* 通過使用者名的模糊查詢
* @Title: findByUserNameLike
* @Description: TODO
* @param: @param userName
* @param: @return
* @return: List<User>
* @throws
*/
public List<User> findByUserNameLike(String userName);
/**
* 通過使用者名和密碼的Like來進行查詢
* @Title: findByUserNameLikeAndPasswordLike
* @Description: TODO
* @param: @param userName
* @param: @return
* @return: List<User>
* @throws
*/
public List<User> findByUserNameLikeAndPasswordLike(String userName,String password);
/**
* 使用者名和密碼like 然後id小于一個範圍
* @Title: findByUserNameLikeAndPasswordLikeAndUserIdLessThan
* @Description: TODO
* @param: @param userName
* @param: @param password
* @param: @param userId
* @param: @return
* @return: List<User>
* @throws
*/
public List<User> findByUserNameLikeAndPasswordLikeAndUserIdLessThan(String userName,String password,int userId);
}
注意:一般情況下不會通過名字直接來寫相應的方法,因為如果條件過多那麼這個時候我們就存在名字特别長的問題
通過注解的模式來實作查詢
舉例如下
/**
* 查詢所有 沒有條件直接查詢
* @Title: findUserAll
* @Description: TODO
* @param: @return
* @return: List<User>
* @throws
*/
@Query("from User")
public List<User> findUserAll();
/**
* 通過id來查找資料 參數直接拼接到後面
* @Title: findUserById
* @Description: TODO
* @param: @param userId
* @param: @return
* @return: List<User>
* @throws
*/
@Query("from User u where u.userId<3")
public List<User> findUserById();
/**
* 通過id查詢存在占位符的情況
* @Title: findUserById1
* @Description: TODO
* @param: @param userId
* @param: @return
* @return: List<User>
* @throws
*/
@Query("from User u where u.userId<?")
public List<User> findUserById1(int userId);
/**
* 多條件的查詢 可以指定目前的參數映射的這個位置
* @Title: getUserByNameAndId
* @Description: TODO
* @param: @param userName
* @param: @param userId
* @param: @return
* @return: User
* @throws
*/
@Query("from User u where u.userId=?2 and u.userName=?1")
public User getUserByNameAndId(String userName,int userId);
/**
* 模糊查詢的時候動态拼接上 %的問題
* @Title: findUserByLike1
* @Description: TODO
* @param: @param userName
* @param: @return
* @return: List<User>
* @throws
*/
@Query("from User u where u.userName like concat ('%',?,'%')")
public List<User> findUserByLike1(String userName);
寫本地的SQL 查詢
舉例如下
/**
* 通過
* @Title: findUserAll11
* @Description: TODO
* @param: @return
* @return: List<User>
* @throws
*/
@Query(nativeQuery=true,value="select * from t_user")
public List<User> findUserAll11();
添加業務邏輯 增加事務環境
@Service
@Transactional //提供一個事務的環境
public class UserService {
@Autowired
private UserRepository userRepository=null;
/**
* 資料的更新
* @Title: update
* @Description: TODO
* @param: @param userName
* @param: @param password
* @param: @param userId
* @return: void
* @throws
*/
public void update(String userName,String password,int userId){
userRepository.update(userName, password, userId);
}
public void delete(int userId){
userRepository.delete(userId);
}
public void insert(String userName,String password){
userRepository.insert(userName, password);
}
}
編寫repository的對象
public interface UserRepository extends Repository<User,Integer>{
/**
* 實作增删改的方法
* @Title: add
* @Description: TODO
* @param: @param userName
* @param: @param password
* @return: void
* @throws
*/
@Modifying //這個注解的作用表示的是更新資料
@Query("update User u set u.userName=?,u.password=? where u.userId=?")
public void update(String userName,String password,int userId);
/**
* 更新資料
* @Title: delete
* @Description: TODO
* @param: @param userId
* @return: void
* @throws
*/
@Modifying //這個注解的作用表示的是更新資料
@Query("delete User u where u.userId=?")
public void delete(int userId);
/**
* 添加資料
* @Title: insert
* @Description: TODO
* @param: @param userName
* @param: @param password
* @return: void
* @throws
*/
@Modifying //這個注解的作用表示的是更新資料
@Query(nativeQuery=true,value="insert into t_user(userName,password) values(?,?)")
public void insert(String userName,String password);
}
測試
@Test
public void testHelloWorld() throws Exception {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
//擷取DAO的對象
UserService userService=applicationContext.getBean(UserService.class);
userService.insert("小羽","做程式的");
}
提供的是Repository
public interface UserRepository extends CrudRepository<User,Integer>{
}
提供的Repository
public interface UserRepository extends PagingAndSortingRepository<User,Integer>{
}
測試
public class Test001 {
@Test
public void testPaging() throws Exception {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
//擷取DAO的對象
UserRepository userRepository=applicationContext.getBean(UserRepository.class);
/**
* 第一個參數:目前的頁的頁數是多少 頁數是從0開始的 第二頁:2-1
* 第二個參數:表示的是每一頁條目數
*/
Page<User> pages=userRepository.findAll(new PageRequest(2-1,2));
System.out.println("查詢到的資料:"+pages.getContent());
System.out.println("資料的條目數:"+pages.getSize());
System.out.println("頁數:"+pages.getNumber());
System.out.println("資料條目的總數:"+pages.getTotalElements());
System.out.println("一共的頁數:"+pages.getTotalPages());
System.out.println("排序的規則:"+pages.getSort());
}
/**
* 排序
* @Title: testSort
* @Description: TODO
* @param: @throws Exception
* @return: void
* @throws
*/
@Test
public void testSort() throws Exception {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
//擷取DAO的對象
UserRepository userRepository=applicationContext.getBean(UserRepository.class);
/**
* 排序
* 第一個參數:升序或者降序 Direction.ASC/DESC
* 第二個參數: 排序的這個列
*/
List<User> users=(List<User>) userRepository.findAll(new Sort(Direction.DESC,"userId"));
System.out.println(users);
}
/**
* 排序後分頁
* @Title: testSortAndPaging
* @Description: TODO
* @param: @throws Exception
* @return: void
* @throws
*/
@Test
public void testSortAndPaging() throws Exception {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
//擷取DAO的對象
UserRepository userRepository=applicationContext.getBean(UserRepository.class);
Page<User> pages=userRepository.findAll(new PageRequest(2-1,2,new Sort(Direction.DESC,"userId")));
System.out.println(pages.getContent());
}
}
提供的repository
public interface UserRepository extends JpaRepository<User,Integer>{
}
測試
public class Test001 {
@Test
public void testPaging() throws Exception {
ClassPathXmlApplicationContext applicationContext=new ClassPathXmlApplicationContext("config/bean-base.xml");
//擷取DAO的對象
UserRepository userRepository=applicationContext.getBean(UserRepository.class);
// long count=userRepository.count();
// User user=userRepository.findOne(15);
// user.setUserName("小羽");
//儲存或者更新資料
// userRepository.saveAndFlush(user);
List<User> users=userRepository.findAll();
//批處理
userRepository.deleteInBatch(users);
//System.out.println("統計:"+count);
}
}
結語
Spring Data是我們開發中離不開的經常用到的技術,其涉及的技術和知識面其實遠不止上面列出的這些。
後續淺羽會繼續更新關于Spring Data的開發知識,隻希望能對大家有所幫助,謝謝大家的支援!
寫作秉持初心,緻力于讓每一位網際網路人共同進步。
往期好文
往期推薦
Spring Data開發手冊|Java持久化API(JPA)需要了解到什麼程度呢?
動态資源技術JSP|Java與Html的美好相遇
尚能飯否|技術越來越新,我對老朋友jQuery還是一如既往熱愛
告别祈禱式程式設計|單元測試在項目裡的正确落地姿勢
元件必知必會|那些年我們使用過的輪子—Filter和Proxy
ES開發指南|如何快速上手ElasticSearch
玩轉Redis|學會這10點讓你分分鐘拿下Redis,滿足你的一切疑問
超級詳細|Linux系統下從0到1的玩法大全
如果你覺得淺羽的文章對你有幫助的話,請在微信搜尋并關注「 淺羽的IT小屋 」微信公衆号,我會在這裡分享一下計算機資訊知識、理論技術、工具資源、軟體介紹、後端開發、面試、工作感想以及一些生活随想等一系列文章。所見所領,皆是生活。慢慢來,努力一點,你我共同成長...