1. 程式人生 > >SpringBoot學習(二)--構建RESTFUL API並用JdbcTemplate進行儲存

SpringBoot學習(二)--構建RESTFUL API並用JdbcTemplate進行儲存

RESTFUL API

首先,REST是所有Web應用都應該遵守的架構設計指導原則。面向資源是REST最明顯的特徵,對於同一個資源的一組不同的操作。在這裡我們是對一個User物件進行操作。增刪改查。REST要求,必須通過統一的介面來對資源執行各種操作。對於每個資源只能執行一組有限的操作。(7個HTTP方法:GET/POST/PUT/DELETE/PATCH/HEAD/OPTIONS)
REST總是使用http協議。有下列幾個常用操作。
GET(SELECT):從伺服器取出資源(一項或多項)。
POST(CREATE):在伺服器新建一個資源。
PUT(UPDATE):在伺服器更新資源(客戶端提供改變後的完整資源)。
PATCH(UPDATE):在伺服器更新資源(客戶端提供改變的屬性)。
DELETE(DELETE):從伺服器刪除資源。


構造User物件(/domain)

public class User {
    private Long id;
    private String name;
    private Integer age;

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getName() {

        return name;
    }

    public
void setName(String name) { this.name = name; } public Long getId() { return id; } public void setId(Long id) { this.id = id; } }

實現對User物件的操作介面(/web)


import com.kaihong.springboot.domain.User;
import com.kaihong.springboot.domain.UserDao;
import org.springframework.beans.factory.annotation.Autowired;
import
org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/users") public class UserController { @Autowired UserDao userDao;//對user進行增刪改查的dao @RequestMapping(value="/", method = RequestMethod.GET) public String getUsersSum(){ //處理“/users/"的GET請求。獲取現在資料庫中的總的user數量 return userDao.getAllUsers().toString(); } @RequestMapping(value="/", method = RequestMethod.POST) public String postUser(@ModelAttribute User user){ // 處理"/users/"的POST請求,用來建立User userDao.create(user.getName(),user.getAge()); return "success"; } @RequestMapping(value="/{id}", method = RequestMethod.GET) public User getUser(@PathVariable Long id){ //處理"/users/id"的GET請求,用來通過id獲取User物件 return userDao.getUserById(id); } @RequestMapping(value="/{id}", method = RequestMethod.PUT) public String putUser(@PathVariable Long id, @ModelAttribute User user){ // 處理"/users/{id}"的PUT請求,用來更新User資訊 userDao.updateById(id, user); return "success"; } @RequestMapping(value="/{id}", method = RequestMethod.DELETE) public String deleteUser(@PathVariable Long id){ //處理"/users/id"的DELETE請求,用來根據id刪除User userDao.deleteAllUsers(); return "success"; } }

為了連線資料庫,需要新增依賴如下

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>5.1.21</version>
</dependency>

在application.properties中配置資料庫的資訊,資料庫的名稱,使用者名稱密碼要更改。

spring.datasource.url=jdbc:mysql://localhost:3306/test
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver

Spring的JdbcTemplate是自動配置的,你可以直接使用@Autowired來注入到你自己的bean中來使用。

  1. 定義包含有插入、刪除、查詢的抽象介面UserDao(/domain)
package com.kaihong.springboot.domain;


public interface UserDao {

    void create(String name, Integer age);

    void deleteByName(String name);

    Integer getAllUsers();

    void deleteAllUsers();

    User getUserById(Long id);

    void updateById(Long id, User u);
}

通過JdbcTemplate實現UserService中定義的資料訪問操作

package com.kaihong.springboot.domain;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service("userDao")
public class UserDaoImpl implements UserDao {

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Override
    public void create(String name, Integer age) {
        jdbcTemplate.update("insert into USER(NAME, AGE) values(?,?)",name,age);
    }

    @Override
    public void deleteByName(String name) {
        jdbcTemplate.update("delete from USER where name=?", name);
    }

    @Override
    public Integer getAllUsers() {
        return jdbcTemplate.queryForObject("select count(1) from USER",Integer.class);
    }


    @Override
    public void deleteAllUsers() {
        jdbcTemplate.update("delete from USER");
    }

    @Override
    public User getUserById(Long id){
        User u=new User();
        String name=jdbcTemplate.queryForObject("select name from USER where id=?",
                String.class, new Object[]{id});
        Integer age=jdbcTemplate.queryForObject("select age from USER where id=?",
                Integer.class, new Object[]{id});
        u.setAge(age);
        u.setId(id);
        u.setName(name);
        return u;
    }

    @Override
    public void updateById(Long id, User u){
        jdbcTemplate.update("update USER set name=?, age=? where id=?",u.getName(),u.getAge(),id);
    }
}

jdbcTemplate的操作簡單。直接用@Autowired註解就可以注入。


測試

剛開始是使用JUnit進行測試。但是正確處理http請求後從test跳轉到UserController時userDao總是注入失敗,空指標異常,查了很久都不知道怎麼解決。網上大多是非Controller下注入失敗的例子,可能是Junit不熟,之後再回來解決。
Caused by: java.lang.NullPointerException
at com.kaihong.springboot.controller.UserController.getUsersSum(UserController.java:21)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:205)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:133)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:97)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:967)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:901)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970)
… 38 more

最後使用Postman進行測試,不會注入失敗。Postman官網下載即可。
post
這是post請求傳送內容的例子。
最後測試成功。


一些註解

@Autowired:@Autowired是一種函式,可以對成員變數、方法和建構函式進行標註,來完成自動裝配的工作,@Autowired標註可以放在成員變數上,也可以放在成員變數的set方法上。在這裡我就直接用來匯入一整個Dao。
@Autowired是根據型別進行自動裝配的,如果需要按名稱進行裝配,則需要配合@Qualifier使用。比如介面Persion有兩個實現類,Student和Teacher。為了確定例項化時是哪個就需要

@Autowired
@Qualifier("student")
private Persion persion;

這樣例項化的就是Student.在上面的例子中因為UserDao只有一個實現類,所以可以不需要。另外要注意的是這裡的Qualifier要配合Service使用,見下。

@Service:@Service表示告訴Spring建立這個類的例項。一個介面有多個實現類時,需要在增加名字,如@Service(“student”),@Service(“teacher”).這樣就能跟@Qualifier配合使用了。