PHP程序猿的Spring Boot之旅-Spring Boot Jpa使用

上一节,已经使用Spring Boot实现了一个restful api,但是数据的交互是通过map实现的,那么本节我们使用jpa与数据库进行交互,本节完成后,可以结合之前的demo实现一个更加复杂的demo。

添加依赖

        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>${druid.version}</version>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <scope>runtime</scope>
        </dependency>

配置

spring:
  jpa:
    hibernate:
      ddl-auto: update
  datasource:
    druid:
      url: jdbc:mysql://127.0.0.1:3306/blog?useUnicode=true&characterEncoding=UTF8&useSSL=false
      username: root
      password: root
  jpa:
    show-sql: true  

新建实体

package cn.sockstack.blog.entity;

import com.fasterxml.jackson.annotation.JsonIgnore;
import lombok.Data;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Date;
import java.util.List;

@Entity
@Data
@Table(name = "users")
public class User implements Serializable {
    @Id
    @GeneratedValue
    private Integer id;

    @Column(nullable = false, columnDefinition = "varchar(20)")
    private String account;

    @Column(nullable = false, columnDefinition = "varchar(32)")
    private String password;

    @Column(nullable = true, columnDefinition = "varchar(128) default ''")
    private String name;

    @Column(nullable = false, columnDefinition = "tinyint(1)")
    private Integer isForbidden;

    @Column(nullable = true, columnDefinition = "varchar(15) default ''")
    private String ip;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;

    @Temporal(TemporalType.TIMESTAMP)
    private Date deletedAt;

    @Column(nullable = true, columnDefinition = "int(11)")
    private Integer deletedUserId;

    @JsonIgnore
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
    private List<Article> articles;
}

新建DAO

package cn.sockstack.blog.dao;

import cn.sockstack.blog.entity.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.repository.PagingAndSortingRepository;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;


@Repository
public interface UserDao extends JpaRepository<User, Integer>, PagingAndSortingRepository<User, Integer> {
}

新建UserService接口

package cn.sockstack.blog.services;

import cn.sockstack.blog.common.exception.LoginFailException;
import cn.sockstack.blog.dto.UserDto;
import cn.sockstack.blog.entity.User;
import org.springframework.data.domain.Page;

import java.util.List;

public interface IUserService {
    /**
     * 增加用户
     * @param userDto
     * @return
     */
    User addUser(UserDto userDto);

    /**
     * 修改用户信息
     * @param userDto
     * @return
     */
    User updateUser(UserDto userDto);

    /**
     * 物理删除用户
     * @param user_id
     * @return
     */
    void deleteUser(Integer user_id);

    /**
     * 逻辑删除用户
     * @param user_id
     * @return
     */
    User removeUser(Integer user_id, Integer delete_admin_id);

    /**
     * 查询用户
     * @param userDto
     * @return
     */
    List<User> query(UserDto userDto);

    /**
     * 获取一个用户的信息
     * @param user_id
     * @return
     */
    User getOne(Integer user_id);

    /**
     * 获取所有的用户
     * @param page
     * @param pagesize
     * @return
     */
    Page<User> getAll(Integer page, Integer pagesize);

    /**
     * 登录
     * @param userDto
     * @return
     */
    User doLogin(UserDto userDto) throws LoginFailException;
}

新建UserServiceImpl服务实现

package cn.sockstack.blog.services.impl;

import cn.sockstack.blog.common.exception.LoginFailException;
import cn.sockstack.blog.common.utils.CommonUtil;
import cn.sockstack.blog.dao.UserDao;
import cn.sockstack.blog.dto.UserDto;
import cn.sockstack.blog.entity.User;
import cn.sockstack.blog.services.IUserService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.stereotype.Service;

import java.util.Date;
import java.util.List;
import java.util.Optional;

@Service
public class UserServiceImpl implements IUserService {
    @Autowired
    UserDao userDao;
    
    @Override
    public User addUser(UserDto userDto) {
        String password = CommonUtil.string2Md5(userDto.getPassword());
        userDto.setPassword(password);

        User user = new User();
        BeanUtils.copyProperties(userDto, user);
        user.setIsForbidden(0);
        user.setCreatedAt(new Date());

        user = userDao.save(user);
        user = CommonUtil.hidePassword(user);

        return user;
    }

    @Override
    public User updateUser(UserDto userDto) {
        return null;
    }

    @Override
    public void deleteUser(Integer user_id) {
         userDao.deleteById(user_id);;
    }

    @Override
    public User removeUser(Integer user_id, Integer delete_admin_id) {
        Optional<User> userOpt = userDao.findById(user_id);

        User user = userOpt.get();
        user.setDeletedAt(new Date());
        user = userDao.save(user);

        user = CommonUtil.hidePassword(user);

        return user;
    }

    @Override
    public List<User> query(UserDto userDto) {
        return null;
    }

    @Override
    public User getOne(Integer user_id) {
        User user = userDao.findByIdAndDeletedUserIdIsNull(user_id);

        user = CommonUtil.hidePassword(user);

        return user;
    }

    @Override
    public Page<User> getAll(Integer page, Integer pagesize) {
        PageRequest pageRequest = PageRequest.of(page, pagesize);
        return userDao.findAll(pageRequest);
    }

    @Override
    public User doLogin(UserDto userDto) throws LoginFailException {
        String password = CommonUtil.string2Md5(userDto.getPassword());
        String account = userDto.getAccount();
        User user = userDao.findByAccountAndPassword(account, password);

        if (user == null) {
            throw new LoginFailException("账号或者密码错误");
        }

        user = CommonUtil.hidePassword(user);
        user.setIp(CommonUtil.getClientIp());

        return user;
    }
}

新建UserController

package cn.sockstack.blog.web;

import cn.sockstack.blog.common.RestResponseBody;
import cn.sockstack.blog.common.enums.HttpStatus;
import cn.sockstack.blog.common.exception.LoginFailException;
import cn.sockstack.blog.common.utils.JwtUtil;
import cn.sockstack.blog.dto.UserDto;
import cn.sockstack.blog.entity.User;
import cn.sockstack.blog.form.AddUserForm;
import cn.sockstack.blog.form.LoginForm;
import cn.sockstack.blog.services.IUserService;
import cn.sockstack.blog.vo.UserVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.validation.Valid;

@RestController
@RequestMapping("/users")
public class UsersController {
    @Autowired
    IUserService userService;

    @GetMapping("")
    public Page<User> getOne(@RequestParam(name = "page", defaultValue = "1", required = false) Integer page,
                             @RequestParam(name = "pagesize", defaultValue = "20", required = false) Integer pagesize) {
        if ((page = page - 1) < 0){
            page = 0;
        }

        return userService.getAll(page, pagesize);
    }

    @PostMapping("")
    public User addUser(@Valid AddUserForm addUserForm, UserDto userDto) {
        BeanUtils.copyProperties(addUserForm, userDto);

        return userService.addUser(userDto);
    }

    @GetMapping("/{id}")
    public RestResponseBody<User> getOne(@PathVariable(name = "id", required = true) Integer id) {
        User user = userService.getOne(id);

        return new RestResponseBody<>(HttpStatus.REQUEST_SUCCESS.Status(),
                HttpStatus.REQUEST_SUCCESS.Message(), user);
    }

    @DeleteMapping("/{id}")
    public RestResponseBody<User> removeUser(@PathVariable(name = "id", required = true) Integer id) {
        User user = userService.removeUser(id, 1);

        return new RestResponseBody<>(HttpStatus.REQUEST_SUCCESS.Status(),
                HttpStatus.REQUEST_SUCCESS.Message(), user);
    }

    @PostMapping("/login")
    public RestResponseBody<UserVo> doLogin(@Valid LoginForm loginForm, UserDto userDto, UserVo userVo,
                                            HttpServletRequest request) {
        BeanUtils.copyProperties(loginForm, userDto);
        User user = userService.doLogin(userDto);

        BeanUtils.copyProperties(user, userVo);
        String token = JwtUtil.crypt(3600, user);

        userVo.setToken(token);

        return new RestResponseBody<>(HttpStatus.REQUEST_SUCCESS.Status(), HttpStatus.REQUEST_SUCCESS.Message(), userVo);
    }

    @PostMapping("/register")
    public RestResponseBody<String> doRegister() {
        return null;
    }
}

测试

通过postman进行测试即可。

说明

有部分的内容没有贴出来,但是不影响代码的阅读。