Spring Data 簡單學習
前言
苦逼的學生黨終於快迎接放假了~~~ 雖然臨近期末,明明還沒預習但還是想搞一些奇奇怪怪的…………最近,有一個自己的想法想在暑假搞出來以便將來可以寫在簡歷之類的,因爲學過一些Spring全家桶,就順手練一下還有做一下學習筆記。這裏的案例是爲了那個項目準備的,所以會融入到那個項目中,還有我會儘可能多打註釋的。另外,立個flag,暑假儘可能寫博客記錄一下學習生活。
這一篇主要是關於 Spring Data 的學習筆記。
- 案例地址(歡迎大家支持給顆star):https://github.com/FunriLy/LiveChat
Spring Data 介紹
注意:這裏的介紹來源於網絡!而且,等會用到的是主要是JPA部分
看了這麼多專業的介紹,其實Spring Data項目旨在爲大家提供一種通用的編碼模式,統一我們的API。spring Data 項目的目的是爲了簡化構建基於 Spring 框架應用的數據訪問計數,包括非關係數據庫、Map-Reduce 框架、雲數據服務等等;另外也包含對關係數據庫的訪問支持。
Spring Data 包含多個子項目:
- Commons - 提供共享的基礎框架,適合各個子項目使用,支持跨數據庫持久化
- Hadoop - 基於 Spring 的 hadoop 作業配置和一個 POJO 編程模型的 MapReduce 作業
- Key-Value - 集成了 Redis 和 Riak ,提供多個常用場景下的簡單封裝
- Document - 集成文檔數據庫:CouchDB 和 MongoDB 並提供基本的配置映射和資料庫支持
- Graph - 集成 Neo4j 提供強大的基於 POJO 的編程模型
- Graph Roo AddOn - Roo support for Neo4j
- JDBC Extensions - 支持 Oracle RAD、高級隊列和高級數據類型
- JPA - 簡化創建 JPA 數據訪問層和跨存儲的持久層功能
- Mapping - 基於 Grails 的提供對象映射框架,支持不同的數據庫
- Examples - 示例程序、文檔和圖數據庫
- Guidance - 高級文檔
看了這麼多專業的介紹,其實Spring Data項目旨在爲大家提供一種通用的編碼模式,統一我們的API。
初學SpringData
利用SpringBoot框架集合SpringData框架!
1. 資源配置
pom.xml配置:
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<!--SpringBoot其他配置就不羅列了,主要是與Data有關的-->
<!--JPA 操作數據庫-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<!--MySQL-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<!--servlet-->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>3.1.0</version>
<scope>provided</scope>
</dependency>
application.properties配置:
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/XXXXXX?characterEncoding=utf8&useSSL=false
spring.datasource.username=XXXXXX
spring.datasource.password=XXXXXX
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
2. 數據庫建表和Model層建立
Model層建立User實體:
@Entity //實體類,利用對象關係映射生成數據庫表
@Table(name = "users", schema = "livechat", catalog = "")
public class User implements Serializable{
private static final long serialVersionUID = 1l;
@Id
private String id;
@Column(nullable = false, name = "name")
private String name;
}
數據庫建表:
CREATE TABLE `users` (
`id` varchar(25) NOT NULL,
`name` varchar(8) NOT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
3. 繼承Repository接口
Repository是一個標記接口,繼承該接口的Bean被Spring容器識別爲一個RepositoryBean:
1. 可以使用 Query 註解查詢
1. spring data repository 接口中的方法默認只有查詢和保存,沒有更新和刪除的事務
1. SpringData的命名規範:(find | get | read) + By + field + ( + 關鍵字 + field )
如,findByName、findByNameAndId
public interface UserRepositoy extends Repository<User, String> {
// SQL = select * from users where name = ?
public User findByName(String name);
public User getById(String id);
public User save(User user);
/**
* 關於 * ,IDEA語法報錯但不影響運行,應該是IDEA本身提示的問題
* 但是有一個語法提示感覺有點彆扭,所以我將它註釋了
*/
// @Query(value = "select * from users u where u.name = :name", nativeQuery = true)
// public User myselect(@Param("name") String name);
}
我將單元測試全部集中到一起了,所以將在後面進行測試。
4. 繼承CrudRepository
由於Repository
接口的侷限性,所以我一般都是用CrudRepository
。但Repository
可以自定義接口。CrudRepository
接口繼承於 Repository 接口,並新增了簡單的增、刪、查等方法。
方法列表:
long count();
boolean exists(Integer arg0);
<S extends StudentPO> S save(S arg0);
<S extends StudentPO> Iterable<S> save(Iterable<S> arg0);
void delete(Integer arg0);
void delete(Iterable<? extends StudentPO> arg0);
void delete(StudentPO arg0);
void deleteAll();
StudentPO findOne(Integer arg0);
Iterable<StudentPO> findAll();
Iterable<StudentPO> findAll(Iterable<Integer> arg0);
UserDao.java:
public interface UserDao extends CrudRepository<User, String> {
//可以用 @Query 註解添加自己的事務方法
}
5. 單元測試
因爲案例用的是SpringBoot 1.5.x,JUnit單元測試優化,並且換註解@SpringApplicationConfiguration(Application.class)
爲@SpringBootTest
。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest
public class UserDaoTest {
@Autowired
private UserRepositoy repositoy;
@Autowired
private UserDao userDao;
@Test
public void test_reposity(){
//先在數據庫中添加一條記錄{id='123456', name='funrily'}
String name = "funrily";
System.out.println("====測試Reposity===");
User user = repositoy.findByName("funrily");
System.out.println(user.toString());
// User next = repositoy.myselect("funrily");
// System.out.println(next.toString());
//
// repositoy.save(new User("654321", "fangrui"));
// next = repositoy.findByName("fangrui");
// System.out.println(next.toString());
}
/**
* 查詢表種記錄的數量
*/
@Test
public void test_count(){
long cout = userDao.count();
System.out.println("count = " + cout);
}
@Test
public void test_exists(){
//根據主鍵判斷是否存在
boolean isExist = userDao.exists("123456");
System.out.println("IsExist :" + isExist);
}
@Test
public void test_save(){
//單個保存
User user = new User("127.0.0.1", "host");
System.out.println(userDao.save(user));
//批量保存
User user1 = new User("1", "1");
User user2 = new User("2", "2");
User user3 = new User("3", "3");
User user4 = new User("4", "4");
List<User> users = new ArrayList<>();
users.add(user1);
users.add(user2);
users.add(user3);
users.add(user4);
System.out.println("批量保存:" + userDao.save(users));
}
@Test
public void test_find(){
//通過id查詢一個記錄
User user = userDao.findOne("127.0.0.1");
System.out.println("通過id查找一個記錄:" + user);
//根據id列表查詢,其內部實際上使用了 in 關鍵字
List<String> idList = new ArrayList<>();
idList.add("1");
idList.add("2");
System.out.println("根據id列表查詢:" + userDao.findAll(idList));
//查找所有的記錄
System.out.println("所有的記錄:" + userDao.findAll());
}
/**
* 關於delete的單元測試需要在上面的單元測試通過後
* 數據庫中有相應的記錄纔可以執行成功
*/
@Test
public void test_delete(){
//通過id刪除一條記錄
userDao.delete("127.0.0.1");
System.out.println("通過id刪除一條記錄後,記錄是否存在:" + userDao.exists("127.0.0.1"));
//刪除某個特定的記錄
User user = userDao.findOne("123456"); //查找一個記錄
if (user != null && user.getId() != null && !user.getId().equals("")){
userDao.delete(user);
System.out.println("通過id刪除一條記錄後,記錄是否存在:" + userDao.exists("123456"));
}
//根據id列表刪除記錄
List<User> userList = new ArrayList<>();
userList.add(userDao.findOne("1"));
userList.add(userDao.findOne("2"));
userDao.delete(userList);
//刪除所有的記錄
userDao.deleteAll();
}
}
補充點
@Query 註解
使用@Query註解可以自定義JPQL語句,語句可以實現更靈活的查詢。@Modifying 註解
可以通過自定義的JPQL來完成update和delete操作。在@Query註解中編寫JPQL語句,但必須使用@Modify進行修飾,主要功能是通知SpringData,這是一個Update或者Delete。
Spring-data的能力遠不止本文提到的這些,這裏的使用只是介紹了常見的使用方式。諸如@Modifying操作、分頁排序、原生SQL支持以及與Spring MVC的結合使用等等內容,我瞭解還不夠,如果以後有時間再來補坑吧~
參考資料
http://blog.csdn.net/z69183787/article/details/30265243
http://blog.csdn.net/luckyzhoustar/article/details/49362951