1. 程式人生 > >Spring Boot 學習第二步 配置MySQL資料庫+JPA

Spring Boot 學習第二步 配置MySQL資料庫+JPA

在web伺服器中少不了的是與資料庫打交道,這裡我們採用的是MySQL資料庫,也許你對於在Spring中如何進行MySQL資料庫配置非常熟悉,這裡我們介紹一下如何在Spring Boot環境下配置,並感受一下它的優越性。

Maven pom.xml檔案的配置

  <dependency>
       <groupId>org.springframework.boot</groupId>
       <artifactId>spring-boot-starter-data-jpa</artifactId>
 </dependency
>

application.properties配置檔案

如果看過Spring Boot學習第一步(配置環境)的話,就會發現整個工程裡面是找不到application.properties這個配置檔案的,所以我們要做的就是在src/main/resources這個資料夾下面新建一個application.properties,並把相應的配置程式碼寫進去。

#DB Configuration:
spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306
/testdb spring.datasource.username = root spring.datasource.password = 123456 #JPA Configuration: spring.jpa.database=MySQL spring.jpa.show-sql=true spring.jpa.generate-ddl=true spring.jpa.hibernate.ddl-auto=update #spring.jpa.database-platform=org.hibernate.dialect.MySQL5Dialect spring.jpa
.hibernate.naming_strategy=org.hibernate.cfg.ImprovedNamingStrategy #spring.jpa.database=org.hibernate.dialect.MySQL5InnoDBDialect #spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.MYSQL5Dialect

編寫Model裡面的UserLogin.java

package cn.springboot.SpringBootFirst.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
import javax.validation.constraints.NotNull;


@Entity
@Table(name="logintable")
public class UserLogin {    
    @Id
    @NotNull
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    @NotNull
    @Column(name="login_name")
    private  String loginName;

    @NotNull
    @Column(name="login_password")
    private  String loginPassword;

    public UserLogin(){}

    public UserLogin(String a, String b){
        this.loginName = a;
        this.loginPassword = b;
    }

//Getter and Setter
}

這個實體類是與資料庫中的表進行一一對應的,在這個實體類的編寫上面有很多需要注意的地方:
1:要知道什麼能少,什麼不能少 比如@Id就不能少

錯誤1:com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column ‘userlogin0_.login_name’ in ‘field list’
新手一般會犯上面的錯誤:經過多番嘗試,發現jpa會有很多的命名規範,第一點就是對於MySQL資料庫中的屬性的大小寫有要求。在MySQL資料庫中,如果屬性名中包含大寫字母就會出這個錯,比如loginName但是如果全是小寫字母如username 或者 user_name就沒有這個錯誤。

編寫DAO裡面的 UserLoginDao.java

package cn.springboot.SpringBootFirst.dao;

import javax.transaction.Transactional;
import org.springframework.data.repository.CrudRepository;
import cn.springboot.SpringBootFirst.model.UserLogin;

@Transactional
public interface UserLoginDao extends CrudRepository<UserLogin, Long>{
     UserLogin findByloginName(String loginName);
}

看完上面的Dao中的程式碼,就會發現函式體裡面異常簡單,找不到絲毫的持久層應該出現的程式碼。這就是Spring Date Repository所做的事情。那下面我們就來簡單的學習一下Spring Data Repository的相關知識(當然最後的目的是學好JAP)。

持久層程式碼的如何編寫:通常我們會在持久層宣告一個介面(如上面程式碼中的interface UserLoginDao),然後讓該介面來繼承介面Repository(此介面是Spring Data JPA)中最為核心的介面,但是它只是一個標記型介面,其中包含任何方法,當然如果有需要,Spring Data也提供了很多它的子介面,其中封裝了常用的增刪改查和分頁相關的方法。

正如上面我的程式碼中所寫的那樣,我實現的是CrudRepository介面。
如果持久層介面較多,且每一個介面都需要宣告相似的增刪改查方法,直接繼承 Repository 就顯得有些囉嗦,這時可以繼承CrudRepository,它會自動為域物件建立增刪改查方法,供業務層直接使用。開發者只是多寫了 “Crud” 四個字母,即刻便為域物件提供了開箱即用的十個增刪改查方法。

但是,使用 CrudRepository也有副作用,它可能暴露了你不希望暴露給業務層的方法。比如某些介面你只希望提供增加的操作而不希望提供刪除的方法。針對這種情況,開發者只能退回到 Repository 介面,然後到 CrudRepository 中把希望保留的方法聲明覆制到自定義的介面中即可。分頁查詢和排序是持久層常用的功能,Spring Data 為此提供了 PagingAndSortingRepository 介面,它繼承自 CrudRepository 介面,在 CrudRepository 基礎上新增了兩個與分頁有關的方法。但是,我們很少會將自定義的持久層介面直接繼承自 PagingAndSortingRepository,而是在繼承 Repository 或 CrudRepository 的基礎上,在自己宣告的方法引數列表最後增加一個 Pageable 或 Sort 型別的引數,用於指定分頁或排序資訊即可,這比直接使用 PagingAndSortingRepository 提供了更大的靈活性。

JpaRepository 是繼承自 PagingAndSortingRepository 的針對 JPA 技術提供的介面,它在父介面的基礎上,提供了其他一些方法,比如 flush(),saveAndFlush(),deleteInBatch() 等。如果有這樣的需求,則可以繼承該介面。

上述四個介面,開發者到底該如何選擇?其實依據很簡單,根據具體的業務需求,選擇其中之一。筆者建議在通常情況下優先選擇 Repository 介面。因為 Repository 介面已經能滿足日常需求,其他介面能做到的在 Repository 中也能做到,彼此之間並不存在功能強弱的問題。只是 Repository 需要顯示宣告需要的方法,而其他則可能已經提供了相關的方法,不需要再顯式宣告,但如果對 Spring Data JPA 不熟悉,別人在檢視程式碼或者接手相關程式碼時會有疑惑,他們不明白為什麼明明在持久層介面中聲明瞭三個方法,而在業務層使用該介面時,卻發現有七八個方法可用,從這個角度而言,應該優先考慮使用 Repository 介面。

編寫Controller中的UserLoginController.java

package cn.springboot.SpringBootFirst.controller;

import java.util.Iterator;

import javax.annotation.Resource;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import cn.springboot.SpringBootFirst.model.UserLogin;
import cn.springboot.SpringBootFirst.dao.UserLoginDao;

@RestController
public class UserLoginController {

    @Resource
    UserLoginDao userLoginDAO;

    @RequestMapping("/userLogin")
    @ResponseBody
    public String login(String userName, String password){
        UserLogin ul = userLoginDAO.findByloginName(userName);
        /*String result = "";
        Iterable<UserLogin> it = userLoginDAO.findAll();
        for(UserLogin ul:it){
            result += ul.getLogin_name();
        }*/

        if(ul==null)
        {
            return "Login Error";
        }

        else
        {
            return ul.getLoginName()+" "+ul.getLoginPassword();
        }
        //return result;
    }

}