Spring MVC系列之JDBC Demo(SpringBoot)(八)


前言

前面我們了解了Spring MVC的基本使用,其實和.NET或.NET Core MVC無異,只是語法不同而已罷了,本節我們將和和數據庫打交道,從最基礎的JDBC講解起,文中若有錯誤之處,還望指正。

JDBC Demo

我們需要下載三個包:JDBC驅動包(mysql-connector-java)、spring boot啟用jdbc(spring-boot-starter-jdbc)、對數據進行序列化的json包(jackson-databind),如下:

<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-jdbc</artifactId>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
</dependency>

接下來我們在配置文件中,通過JDBC連接MySQL數據庫,如下:

spring.datasource.url = jdbc:mysql://localhost:3306/user?serverTimezone=UTC
spring.datasource.username = root
spring.datasource.password = root

這里需要注意的是對於不同的JDBC驅動版本,可能會拋出如下錯誤,這是由於在JDBC指定版本中存在的bug,所以要么如上顯式指定serverTimezone,要么添加JDBC版本

The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver 
(via the serverTimezone configuration property) to use a more specifc time zone value if you want to utilize time zone support

接下來我們定義對用戶進行增、刪、改、查的接口,如下:

public interface UserRepository {

    int save(User user);

    int update(User user);

    int deleteById(int id);

    List<User> findAll();

}

接下來我們再來看用戶類,我們將對提交用戶信息通過注解進行校驗,同時我們對之前添加的愛好的數據類型為數組序列化為JSON后存到MySQL數據庫,如下:

public class User {

    private ObjectMapper objectMapper = new ObjectMapper();

    public User() {
    }

    public User(int userId,
                String firstName,
                String lastName,
                String gender,
                String email,
                String userName,
                String password,
                String country,
                String favoritesJson) throws JsonProcessingException {
        this.userId = userId;
        this.firstName = firstName;
        this.lastName = lastName;
        this.gender = gender;
        this.email = email;
        this.userName = userName;
        this.password = password;
        this.country = country;

        this.favorites = objectMapper.readValue(favoritesJson, new TypeReference<String[]>() {
        });
    }

    private int userId;
    @NotNull(message = "名字必填")
    private String firstName;
    @NotNull(message = "姓氏必填")
    private String lastName;
    @NotNull(message = "性別必填")
    private String gender;
    @NotNull(message = "郵箱必填")
    @Email(message = "請輸入有效的郵箱")
    private String email;
    @NotNull(message = "用戶名必填")
    private String userName;
    @NotNull(message = "密碼必填")
    private String password;
    private String country;

    public int getUserId() {
        return userId;
    }

    public String getFavoritesJson() {
        String favoritesJson = null;
        try {
            favoritesJson = objectMapper.writeValueAsString(this.favorites);
        } catch (JsonProcessingException ex) {
        }
        return favoritesJson;
    }

    public void setUserId(int userId) {
        this.userId = userId;
    }

    private String[] favorites;

    public String[] getFavorites() {
        return favorites;
    }

    public void setFavorites(String[] favorites) {
        this.favorites = favorites;
    }

    public String getCountry() {
        return country;
    }

    public void setCountry(String country) {
        this.country = country;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getEmail() {
        return email;
    }

    public void setEmail(String email) {
        this.email = email;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }
}

最后則是實現上述用戶接口,這里我們使用JDBC中的參數化類(避免SQL注入)進行增刪改查,如下:

@Repository
public class NamedParameterJdbcUserRepository implements UserRepository {

    @Autowired
    public NamedParameterJdbcTemplate namedParameterJdbcTemplate;

    @Override
    public int save(User user) {
        MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
        mapSqlParameterSource.addValue("userName",user.getUserName());
        mapSqlParameterSource.addValue("password",user.getPassword());
        mapSqlParameterSource.addValue("firstName",user.getFirstName());
        mapSqlParameterSource.addValue("lastName",user.getLastName());
        mapSqlParameterSource.addValue("gender",user.getGender());
        mapSqlParameterSource.addValue("email",user.getEmail());
        mapSqlParameterSource.addValue("country",user.getCountry());
        mapSqlParameterSource.addValue("favorites",user.getFavoritesJson());

        return namedParameterJdbcTemplate.update(
                "insert into users (userName, password,firstName,lastName,gender,email,country,favorites)" +
                        " values(:userName,:password,:firstName,:lastName,:gender,:email,:country,:favorites)",
             mapSqlParameterSource);
    }

    @Override
    public int update(User user) {
        return 0;
    }

    @Override
    public int deleteById(int id) {
        MapSqlParameterSource mapSqlParameterSource = new MapSqlParameterSource();
        mapSqlParameterSource.addValue("userId", id);
        return namedParameterJdbcTemplate.update("delete from  users where userId = :userId", mapSqlParameterSource);
    }

    @Override
    public List<User> findAll() {
        return namedParameterJdbcTemplate.query(
                "select * from users",
                (rs, rowNum) ->
                {
                    try {
                        return new User(
                                rs.getInt("userId"),
                                rs.getString("firstName"),
                                rs.getString("lastName"),
                                rs.getString("gender"),
                                rs.getString("email"),
                                rs.getString("userName"),
                                rs.getString("password"),
                                rs.getString("country"),
                                rs.getString("favorites")
                        );
                    } catch (JsonProcessingException e) {
                        e.printStackTrace();
                        return null;
                    }
                });
    }
}

然后在進行提交用戶時,在上一節內容基礎上進行改造,添加校驗注解,若有錯誤則返回,否則提交成功后則跳轉到用戶列表,如下:

    @RequestMapping(value = "/user", method = RequestMethod.POST)
    public String user(@Valid @ModelAttribute("user") User user, BindingResult bindingResult) {
        if (bindingResult.hasErrors()) {
            return "user";
        } else {
            jdbcUserRepository.save(user);
            return "users";
        }
    }

這里需要注意的是:對於空字符串即使添加了校驗注解后依然會忽略,所以我們還需要初始化綁定器注解去除空字符串並對其進行校驗,如下:

    @InitBinder
    public void initBinder(WebDataBinder dataBinder) {

        StringTrimmerEditor stringTrimmerEditor = new StringTrimmerEditor(true);

        dataBinder.registerCustomEditor(String.class, stringTrimmerEditor);
    }

表單提交我們使用的是spring提供給我們的庫,渲染用戶列表,我們則是通過腳本並利用bootstrap-table實現,最終界面所呈現出的效果,如下: 

 

 

 

總結

如上只是給出了部分重要代碼,這里我已經將本節通過JDBC進行增刪改查代碼上傳到github(https://github.com/wangpengxpy/SpringBoot),切換分支即可,后續會將每一塊內容分別創建一個分支,以便供我復習和有需要的童鞋使用,本節我們到此結束,我們下節見。


免責聲明!

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



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