SpringBoot 二:配置文件與JPA操作mysql數據庫

springboot的配置文件有兩種格式,一種是application.yml一種是application.properties。

以設置端口號爲例

application.yml

server:
  port: 8088

application.properties

server.port=8088

    本人喜歡yml格式的文件,看起來層次比較清晰,yml每一層要縮進2個空格,冒號(:)和值之間有一個空格。

    多個環境可以寫多個配置文件,如application-dev.yml,application-prod.yml。application.yml可以放置一些與環境無關的配置,如除地址賬號外的數據庫連接配置。

application.yml:

#指定默認端口爲8088
server:
  port: 8088

#指定默認啓動環境爲dev
spring:
  profiles:
    active: dev
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
#將Date類型在接口返回值中轉爲該格式的String
  jackson:
    date-format: yyyy-MM-dd HH:mm:ss

application-dev.yml

spring:
  datasource:
    driver-class-name: com.mysql.jdbc.Driver
    url: jdbc:mysql://localhost:3306/match?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC
    username: root
    password: 123456
  #    打印sql,不建議正式服也打印sql,所以只配置在dev文件中。
  jpa:
    show-sql: true

?後面前兩個參數是編碼設置,useSSL是數據庫ssl設置問題Establishing SSL connection without server's identity verification is not recommended.,serverTimezone是時區問題,解決啓動時的The server time zone value '�й���׼ʱ��' is unrecognized or represents more than one time zone. You must configure either the server or JDBC driver問題。有時候mysql數據庫設置好的話後面的參數其實不需要的,

使用jpa及連接mysql數據庫需要的依賴,如果mysql版本過高的話,根據自己的數據庫版本選擇依賴版本,一般情況下可以選擇下面註釋掉的那個依賴。

        <!-- jpa -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.17</version>
        </dependency>
<!--
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>
-->

實體類College:

package com.demo.entity;

import lombok.Data;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import java.util.Date;

/**
 * @Author fusheng
 */
@Data
@Entity
@Table(name = "college")
@DynamicInsert
@DynamicUpdate
public class College {

    @Id
    @GeneratedValue(generator = "id")
    @GenericGenerator(name = "id", strategy = "uuid")
    private String id;

    @Column(name = "college_name")
    private String name;

    private String collegeAddress;

    private String collegePhone;

    private String collegeWeb;

    private Date createdTime;

    private Date updatedTime;

    private Integer isDelete;

}

@Data是lombok插件的一個註解,包含getter,setter...等。

@Entity表明它是一個數據庫表的實體類,@Table在實體類和表名不一致時說明tablename。@Id主鍵註解,可以使用jpa自帶的一些方法。@Column字段註解,當實體類中字段名和表字段不一致時需要說明。jpa會自動進行駝峯轉換,collageAddress會轉成college_address。DynamicInsert,DynamicUpdate是動態插入和動態更新,當保存的值爲null不插入這個值而不會向數據庫插入null。@GeneratedValue@GenericGenerator上面的配置是設置UUID,更多內容可自行搜索瞭解。

數據操作層CollegeRepo,下面展示2種常用的查詢

package com.demo.repo;

import com.demo.entity.College;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;

/**
 * @Author fusheng
 */
@Repository
public interface CollegeRepo extends JpaRepository<College,String> {

    College findByName(String name);

    @Query("select c from College c where c.name = ?1")
    College findByCollegeName(String name);
}

@Repository說明這是一個操作數據庫的類。此時可以直接使用jpa自帶的一些簡單方法,如findAll(),findOne(T id),delete,save等方法。也可以通過@Query註解寫sql(第二個方法)。對符合以下命名規則的方法,jpa還會自動生成sql語句(第一個方法)。

DateUtil

package com.demo.util;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * @Author fusheng
 * java8之後LocalDate,LocalDateTime比Date更適合操作時間,後期完成後再重新修改替換
 */
public class DateUtil {
    
    public final static String PATTERN_DATE = "yyyy-MM-dd";
    public final static String PATTERN_DATETIME = "yyyy-MM-dd HH:mm:ss";

    public static Date now(){
        return new Date();
    }

    public static String dateToString(Date date, String format){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        return sdf.format(date);
    }

    public static String dateToString(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_DATETIME);
        return sdf.format(date);
    }

    public static Date stringToDate(String time, String format){
        SimpleDateFormat sdf = new SimpleDateFormat(format);
        try {
            return sdf.parse(time);
        } catch (ParseException e) {
            return null;
        }
    }

    public static Date stringToDate(String time){
        SimpleDateFormat sdf = new SimpleDateFormat(PATTERN_DATETIME);
        try {
            return sdf.parse(time);
        } catch (ParseException e) {
            return null;
        }
    }
    

    public static void main(String[] args) {
        String time = "2018-09-11 12:00:00";
        Date date = stringToDate(time,PATTERN_DATETIME);
        System.out.println(date);
    }

}

數據插入請求實體CollegeReq

package com.demo.dto.req;

import lombok.Data;

import javax.validation.constraints.NotNull;

/**
 * @Author fusheng
 */
@Data
public class CollegeReq {
    @NotNull
    private String name;

    @NotNull
    private String address;

    private String phone;

    private String web;
}

CollegeService:

package com.demo.service;

import com.demo.dto.req.CollegeReq;
import com.demo.entity.College;
import com.demo.repo.CollegeRepo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import static com.demo.util.DateUtil.now;

/**
 * @Author fusheng
 */
@Service
public class CollegeService {

    @Autowired
    CollegeRepo repo;

    public College findCollegeByName(String name){
        return repo.findByName(name);
    }

    public College findCollegeById(String id){
        return repo.findOne(id);
    }

    public void saveCollege(CollegeReq req){
        College college = new College();
        college.setName(req.getName());
        college.setCollegeAddress(req.getAddress());
        college.setCollegePhone(req.getPhone());
        college.setCollegeWeb(req.getWeb());
        college.setCreatedTime(now());
        repo.save(college);
    }
}

Controller:

package com.demo.controller;

import com.demo.dto.req.CollegeReq;
import com.demo.entity.College;
import com.demo.service.CollegeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.validation.Valid;

/**
 * @Author fusheng
 */
@RestController
public class MatchController {
    @Autowired
    CollegeService service;

    @GetMapping(value = "/college")
    public College getCollegeByName(@RequestParam(name = "name") String name){
        return service.findCollegeByName(name);
    }

    @GetMapping(value = "/college2")
    public College getCollegeById(@RequestParam(name = "id") String id){
        return service.findCollegeById(id);
    }

    @PostMapping(value = "/college/save")
    public String saveCollege(@RequestBody@Valid CollegeReq req){
        service.saveCollege(req);
        return "success";
    }
}

在上面的內容中,jpa節省了大量的sql語句,但是有些複雜的查詢呢,這邊在推薦一個類QueryDslPredicateExecutor。

public interface CollegeRepo extends JpaRepository<College,String>,QueryDslPredicateExecutor<College>

//依賴
    <dependencies>
        <!--query dsl -->
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>com.querydsl</groupId>
            <artifactId>querydsl-apt</artifactId>
            <scope>provided</scope>
        </dependency>
    </dependencies>

<build>
        <plugins>
            <plugin>
                <groupId>com.mysema.maven</groupId>
                <artifactId>apt-maven-plugin</artifactId>
                <version>1.1.3</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>process</goal>
                        </goals>
                        <configuration>
                            <outputDirectory>target/generated-sources/java</outputDirectory>
                            <processor>com.querydsl.apt.jpa.JPAAnnotationProcessor</processor>
                        </configuration>
                    </execution>
                </executions>
            </plugin>
        </plugins>
    </build>

之後需要執行 maven compile命令,會生成一個QCollege.class文件。使用如下:

    public College findByNameAndTime(String name, String address){
        QCollege qCollege = QCollege.college;
        Predicate predicate = qCollege.name.eq(name).and(qCollege.collegeAddress.like("%" + address + "%"));
        return repo.findOne(predicate);
    }

接下來簡單介紹一下OneToMany和ManyToOne的使用。

@Data
@Entity
@Table(name = "compete_team")
@DynamicInsert
@DynamicUpdate
public class CompeteTeam {
    @Id
    @GeneratedValue(generator = "id")
    @GenericGenerator(name = "id", strategy = "uuid")
    private String id;

    private String collegeId;

    private String teamName;

    private String teamSlogan;
    private Date createdTime;

    private Date updatedTime;

    private Integer isDelete;

    @ManyToOne
    @JoinColumn(name = "collegeId",insertable = false,updatable = false)
    private College college;
}

College.java類增加代碼

    @OneToMany(mappedBy = "college")
    private List<CompeteTeam> teamList;

使用示例:

public CollegeTeamDto findCollegeTeam(String collegeName){
        QCollege qCollege = QCollege.college;
        Predicate predicate = qCollege.name.eq(collegeName)
                .and(qCollege.teamList.any().isDelete.eq(0));
        College college = repo.findOne(predicate);
        CollegeTeamDto teamDto = new CollegeTeamDto();
        teamDto.setCollegeName(college.getName());
        teamDto.setCollegeAddress(college.getCollegeAddress());
        teamDto.setTeamList(
             college.getTeamList().stream()
                    .map(this::convert)
                    .collect(Collectors.toList())
        );
        return teamDto;
    }

    private Team convert(CompeteTeam competeTeam){
        Team team = new Team();
        team.setTeamName(competeTeam.getTeamName());
        team.setTeamSlogan(competeTeam.getTeamSlogan());
        return team;

    }

以上就是該篇文章的全部內容,有些知識可能說的不夠詳細,不對之處歡迎指出。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章