Spring Data JPA -- 环境搭建

1.新建SpringBoot项目,在 pom.xml 导入需要的依赖

所需依赖:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>com.chen</groupId>
    <artifactId>chen</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>chen</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!--导入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>
            <scope>runtime</scope>
        </dependency>
        <!-- lombok简化实体类代码 -->
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <optional>true</optional>
        </dependency>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
            <exclusions>
                <exclusion>
                    <groupId>org.junit.vintage</groupId>
                    <artifactId>junit-vintage-engine</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.新建项目架构

3.在 application.properties 进行配置

server.port=80

#数据库配置
spring.datasource.url=jdbc:mysql://localhost:3306/chen?useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=123456

# 参数说明 create-运行项目时创建表,update-运行项目时更新表,none-不做操作
spring.jpa.hibernate.ddl-auto=none
# 打印sql语句
spring.jpa.show-sql=true

5.利用aop进行全局异常处理

package com.chen.aop;

import com.chen.domain.AppConstant;
import com.chen.restful.RestResponse;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import java.io.IOException;

/**
 * 全局异常处理类
 *
 * @author chen
 */
@ControllerAdvice
@ResponseBody
public class GlobalExceptionHandler {

    private static final String logExceptionFormat = "服务器异常: Code: %s Detail: %s";
    private static Logger log = LoggerFactory.getLogger(GlobalExceptionHandler.class);

    //运行时异常
    @ExceptionHandler(RuntimeException.class)
    public RestResponse runtimeExceptionHandler(RuntimeException ex) {
        System.err.println("RuntimeException:");
        return resultOut(AppConstant.RunTime, "服务器内部错误,运行异常", ex);
    }

    //空指针异常
    @ExceptionHandler(NullPointerException.class)
    public RestResponse nullPointerExceptionHandler(NullPointerException ex) {
        System.err.println("NullPointerException:");
        return resultOut(AppConstant.NullPointer, "空指针异常", ex);
    }

    //类型转换异常
    @ExceptionHandler(ClassCastException.class)
    public RestResponse classCastExceptionHandler(ClassCastException ex) {
        System.err.println("ClassCastException:");
        return resultOut(AppConstant.ClassCast, "类型转换异常", ex);
    }

    //IO异常
    @ExceptionHandler(IOException.class)
    public RestResponse iOExceptionHandler(IOException ex) {
        System.err.println("IOException:");
        return resultOut(AppConstant.IO, "IO异常", ex);
    }

    //未知方法异常
    @ExceptionHandler(NoSuchMethodException.class)
    public RestResponse noSuchMethodExceptionHandler(NoSuchMethodException ex) {
        System.err.println("NoSuchMethodException:");
        return resultOut(AppConstant.NoSuchMethod, "未知方法异常", ex);
    }

    //数组越界异常
    @ExceptionHandler(IndexOutOfBoundsException.class)
    public RestResponse indexOutOfBoundsExceptionHandler(IndexOutOfBoundsException ex) {
        System.err.println("IndexOutOfBoundsException:");
        return resultOut(AppConstant.IndexOutOfBounds, "数组越界异常", ex);
    }

    //400错误
    @ExceptionHandler({HttpMessageNotReadableException.class})
    public RestResponse requestNotReadable(HttpMessageNotReadableException ex) {
        System.err.println("HttpMessageNotReadableException");
        return resultOut(AppConstant.HttpMessageNotReadable, "400 bad request", ex);
    }

    //400错误
    @ExceptionHandler({TypeMismatchException.class})
    public RestResponse requestTypeMismatch(TypeMismatchException ex) {
        System.err.println("TypeMismatchException:");
        return resultOut(AppConstant.TypeMismatch, "400 bad request", ex);
    }

    //400错误
    @ExceptionHandler({MissingServletRequestParameterException.class})
    public RestResponse requestMissingServletRequest(MissingServletRequestParameterException ex) {
        System.err.println("MissingServletRequestParameterException:");
        return resultOut(AppConstant.MissingServletRequestParameter, "400 bad request", ex);
    }

    //405错误
    @ExceptionHandler({HttpRequestMethodNotSupportedException.class})
    public RestResponse request405(HttpRequestMethodNotSupportedException ex) {
        System.err.println("HttpRequestMethodNotSupportedException:");
        return resultOut(AppConstant.HttpRequestMethodNotSupported, "405 Method not allowed", ex);
    }

    //406错误
    @ExceptionHandler({HttpMediaTypeNotAcceptableException.class})
    public RestResponse request406(HttpMediaTypeNotAcceptableException ex) {
        System.err.println("HttpMediaTypeNotAcceptableException:");
        return resultOut(AppConstant.HttpMediaTypeNotAcceptable, "406 Not Acceptable", ex);
    }

    //500错误
    @ExceptionHandler({ConversionNotSupportedException.class, HttpMessageNotWritableException.class})
    public RestResponse server500(RuntimeException ex) {
        System.err.println("RuntimeException:");
        return resultOut(AppConstant.HttpMediaTypeNotAcceptable, "500 error", ex);
    }

    //栈溢出
    @ExceptionHandler({StackOverflowError.class})
    public RestResponse requestStackOverflow(StackOverflowError ex) {
        System.err.println("StackOverflowError:");
        return resultOut(AppConstant.StackOverflow, "栈溢出异常", ex);
    }

    //除数不能为0
    @ExceptionHandler({ArithmeticException.class})
    public RestResponse arithmeticException(ArithmeticException ex) {
        System.err.println("ArithmeticException:");
        return resultOut(AppConstant.Arithmetic, "除数不能为0", ex);
    }

    //其他错误
    @ExceptionHandler({Exception.class})
    public RestResponse exception(Exception ex) {
        System.err.println("Exception:");
        return resultOut(AppConstant.other, "其他异常", ex);
    }

    /**
     * 对返回数据集中处理
     *
     * @param code
     * @param msg
     * @param ex
     * @param <T>
     * @return
     */
    private <T extends Throwable> RestResponse resultOut(int code, String msg, T ex) {
        ex.printStackTrace();
        log.error(String.format(logExceptionFormat, code, ex.getMessage()));
        return RestResponse.fail(code).msg(msg);
    }

}

6.封装常量类

package com.chen.domain;

/**
 * 对常量进行封装,利于后期代码的维护
 *
 * @author chen
 */
public class AppConstant {

    // 文本消息
    public static final String MESSAGE = "message";

    // 单个对象
    public static final String ITEM = "item";

    // 返回的对象列表
    public static final String LIST = "list";

    // 状态码
    public static final String CODE = "code";

    // 代表执行成功
    public static int OK = 0;

    // 代表执行失败
    public static int FAIL = 1;

    // 代表服务器运行异常
    public static int RunTime = 2;

    // 代表空指针异常
    public static int NullPointer = 3;

    // 类型转换异常
    public static int ClassCast = 4;

    // IO异常
    public static int IO = 5;

    // 未知方法异常
    public static int NoSuchMethod = 6;

    // 数组越界异常
    public static int IndexOutOfBounds = 7;

    // 400错误
    public static int HttpMessageNotReadable=8;

    // 400错误
    public static int TypeMismatch=9;

    // 400错误
    public static int MissingServletRequestParameter=10;

    // 405错误
    public static int HttpRequestMethodNotSupported=11;

    // 406错误
    public static int HttpMediaTypeNotAcceptable=12;

    // 500错误
    public static int Run500=13;

    // 栈溢出
    public static int StackOverflow=14;

    // 除数为0异常
    public static int Arithmetic=15;

    // 其他异常
    public static int other=16;

}

7.封装rest数据

package com.chen.restful;

import com.chen.domain.AppConstant;

import java.util.HashMap;
import java.util.List;

/**
 * REST 接口返回数据
 *
 * @author chen
 */
public class RestResponse extends HashMap<String, Object> {

    /**
     * 禁止通过构造函数构造对象,只能通过静态方法获取实例。
     *
     * @see #ok()
     * @see #ok(String)
     * @see #fail()
     * @see #fail(String)
     */
    private RestResponse() {
    }

    /**
     * 设置接口返回的文本消息,属性 key: message
     *
     * @param msg
     * @return
     */
    public RestResponse msg(String msg) {
        this.put(AppConstant.MESSAGE, msg);
        return this;
    }

    /**
     * 设置接口返回的数据对象,属性 key: item
     *
     * @param item
     * @return
     */
    public RestResponse item(Object item) {
        this.put(AppConstant.ITEM, item);
        return this;
    }

    /**
     * 设置接口返回的数据对象列表,属性 key: list
     *
     * @param list
     * @return
     */
    public RestResponse list(List<?> list) {
        this.put(AppConstant.LIST, list);
        return this;
    }

    /**
     * 设置接口返回的数据项,并指定数据项的属性 key
     *
     * @param key
     * @param value
     * @return
     */
    public RestResponse put(String key, Object value) {
        super.put(key, value);
        return this;
    }

    /**
     * 接口执行成功的返回数据,其中属性 CODE = 0
     *
     * @return
     */
    public static RestResponse ok() {
        RestResponse result = new RestResponse();
        result.put(AppConstant.CODE, AppConstant.OK);
        return result;
    }

    /**
     * 接口执行成功的返回数据,并设置文本消息
     *
     * @param msg
     * @return
     */
    public static RestResponse ok(String msg) {
        RestResponse result = new RestResponse();
        result.put(AppConstant.CODE, AppConstant.OK).msg(msg);
        return result;
    }

    /**
     * 接口执行成功的返回数据,并设置对象数据
     *
     * @param item
     * @return
     */
    public static RestResponse ok(Object item) {
        RestResponse result = new RestResponse();
        result.put(AppConstant.CODE, AppConstant.OK).item(item);
        return result;
    }

    /**
     * 接口执行成功的返回数据,并设置列表对象数据
     *
     * @param list
     * @return
     */
    public static RestResponse ok(List<?> list) {
        RestResponse result = new RestResponse();
        result.put(AppConstant.CODE, AppConstant.OK).list(list);
        return result;
    }

    /**
     * 接口执行失败的返回数据,其中属性 CODE = 1
     *
     * @return
     */
    public static RestResponse fail() {
        RestResponse result = new RestResponse();
        result.put(AppConstant.CODE, AppConstant.FAIL);
        return result;
    }

    /**
     * 接口执行失败的返回数据,并设置文本消息,其中属性 CODE = 1, message = {msg}
     *
     * @param msg
     * @return
     */
    public static RestResponse fail(String msg) {
        RestResponse result = new RestResponse();
        result.put(AppConstant.CODE, AppConstant.FAIL).msg(msg);
        return result;
    }

    /**
     * 接口执行失败的返回数据,自定义状态码,其中属性 CODE = {errcode}
     *
     * @param errcode
     * @return
     */
    public static RestResponse fail(int errcode) {
        RestResponse result = new RestResponse();
        result.put(AppConstant.CODE, errcode);
        return result;
    }
}

8.编写测试实体类

package com.chen.domain.entity;

import lombok.Data;

import javax.persistence.*;

@Data
@Entity(name = "test_user")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "user_id")
    private Long userId;

    @Column(name = "user_name")
    private String userName;

    @Column(name = "age")
    private Integer age;

}

注解说明:

@Entity //声明实体类

@Table(name="") //建立实体类和表的映射关系

@Id//声明当前私有属性为主键

@GeneratedValue(strategy=GenerationType.IDENTITY) //配置主键的生成策略

@Column(name="") //指定和表中字段的映射关系

9.编写dao层接口,需要继承 JpaRepository 

package com.chen.dao;


import com.chen.domain.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;

public interface UserDao extends JpaRepository<User,Long>, JpaSpecificationExecutor<User> {

}

说明:利用JPA规范,实现不用编写数据库代码进行简单的数据库单表操作

10.编写service业务层,调用dao层接口

package com.chen.service;

import com.chen.dao.UserDao;
import com.chen.domain.entity.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.stereotype.Service;

import javax.transaction.Transactional;
import java.util.List;

@Service
@Transactional
public class UserService {

    @Autowired
    private UserDao userDao;

    /**
     * 查询所有数据
     * @return
     */
    public List<User> findAll(){
       return userDao.findAll();
    }

}

11.实现controller接口调用层

package com.chen.controller;

import com.chen.domain.entity.User;
import com.chen.restful.RestResponse;
import com.chen.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;

@RestController
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * 查询所有用户
     * @return
     */
    @RequestMapping("findAll")
    public RestResponse findAll(){
        List<User> all = userService.findAll();
        return RestResponse.ok().msg("处理成功").item(all);
    }

}

12.测试

发布了134 篇原创文章 · 获赞 75 · 访问量 7万+

猜你喜欢

转载自blog.csdn.net/qq_42109746/article/details/104357113