近日学习了Spring Data系列,自己记录一下。
一、Spring Data JPA介绍
Spring Data JPA 是 Spring 基于 ORM 框架、JPA 规范的基础上封装的一套JPA应用框架,可使开发者用极简的代码即可实现对数据的访问和操作。它提供了包括增删改查等在内的常用功能,且易于扩展!学习并使用 Spring Data JPA 可以极大提高开发效率!
官方文档:https://docs.spring.io/spring-data/jpa/docs/2.1.4.RELEASE/reference/html/
二、Spring Boot 整合使用
1、创建Spring Boot 项目 添加依赖:需要web支持,jpa和mysql
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.46</version>
</dependency>
</dependencies>
2、application.yml文件:
spring:
datasource:
username: root
password: 123
url: jdbc:mysql://127.0.0.1:3306/shop?characterEncoding=UTF-8
driverClassName: com.mysql.jdbc.Driver
jpa:
show-sql: true
database: mysql
hibernate:
naming:
physical-strategy: org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
#spring.japa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
#解决实体类变量驼峰命名报错问题
3.User实体类:
package com.wdg.springdatajpademo.pojo;
import javax.persistence.*;
import java.util.Date;
/**
* @author WDG
* @date 2019-2-4
*/
@Table(name="user")
@Entity
public class User {
@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="userId")
private Integer userId;
private String username;
private String password;
@Column(name="regTime")
private Date regTime;
private Integer age;
private String telephone;
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
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;
}
public Date getRegTime() {
return regTime;
}
public void setRegTime(Date regTime) {
this.regTime = regTime;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getTelephone() {
return telephone;
}
public void setTelephone(String telephone) {
this.telephone = telephone;
}
}
4、UserRepository代码:简单的CRUD操作和分页以及条件的动态查询,和自定义SQL以及遵循JPQL规范进行操作数据库,下面贴入代码:
package com.wdg.springdatajpademo.repository;
import com.wdg.springdatajpademo.pojo.User;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;
import java.util.List;
/**
* @author WDG
* @date 2019-2-4
*/
public interface UserRepository extends JpaRepository<User,Integer>, JpaSpecificationExecutor<User> {
/**
* 根据username修改用户信息
* 加上nativeQuery = true 属性 表示自定义SQL
* 传入参数对象类型 使用SPEL表达式
* 官方文档 5.3.7. Using SpEL Expressions
* 增删改操作 必须加上@Modifying 注解 5.3.8. Modifying Queries
* @param user
*/
@Query(value = "update user set userId =:#{#obj.userId},age=:#{#obj.age},password =:#{#obj.password}, regTime =:#{#obj.regTime}, telephone=:#{#obj.telephone} where username=:#{#obj.username} ",nativeQuery = true)
@Modifying
void updateUserByName(@Param("obj") User user);
/**
* 根据年龄查询
* 遵循JPQL规则 5.3.2. Query Creation
* @param age
* @return
*/
List<User> findUserByAge(int age);
}
5.UserService:
package com.wdg.springdatajpademo.service;
import com.wdg.springdatajpademo.pojo.User;
import com.wdg.springdatajpademo.repository.UserRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Optional;
/**
* @author WDG
* @date 2019-2-4
*/
@Service
@Transactional
public class UserService {
@Autowired
private UserRepository userRepository;
/**
* 分页查询
* @param page
* @param size
* @return
*/
public Page<User> findByPage(int page,int size){
PageRequest pageRequest = PageRequest.of(page - 1, size);
return userRepository.findAll(pageRequest);
}
/**
* 根据主键查询
* @param userId
* @return
*/
public User findById(int userId){
return userRepository.findById(userId).get();
}
/**
* 条件查询+分页
* @param page
* @param size
* @param user
* @return
*/
public Page<User> findByPageAndSelect(int page,int size,User user){
return userRepository.findAll(new Specification<User>() {
/**
*
* @param root 根对象,也就是要把条件封装到哪个对象中, where
* @param criteriaQuery 封装的都是查询关键字,比如group by order by等
* @param criteriaBuilder 用来封装条件对象的,直接返回null,则为无条件查询
* @return
*/
@Override
public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
//创建Predicate集合,封装多个查询条件
List<Predicate> list = new ArrayList<Predicate>();
//假设查询用户年龄大于参数年龄,注册时间(regTime)在参数注册时间之前的,
if(user !=null){
if(user.getAge()!=null){
list.add(criteriaBuilder.greaterThan(root.get("age").as(Integer.class), user.getAge()));
}
if(user.getRegTime()!=null){
list.add(criteriaBuilder.lessThan(root.get("regTime").as(Date.class), user.getRegTime()));
}
}
//集合转Predicate数组
Predicate[] predicates = new Predicate[list.size()];
return criteriaBuilder.and( list.toArray(predicates));
}
},PageRequest.of(page-1,size));
}
/**
* 添加用户
* @param user
*/
public void addUser(User user){
//设置注册时间
user.setRegTime(new Date());
userRepository.save(user);
}
/**
* 修改
* @param user
*/
public void updateUser(User user){
//更新注册时间
user.setRegTime(new Date());
userRepository.save(user);
}
/**
* 删除用户
* @param userId
*/
public void deleteUser(int userId){
userRepository.deleteById(userId);
}
/**
* 根据用户名修改
* @param user
*/
public void updateUserByName(User user){
userRepository.updateUserByName(user);
}
/**
* 根据年龄查询
* @param age
* @return
*/
public List<User> findUserByAge(int age){
return userRepository.findUserByAge(age);
}
}
6.UserController 代码:
package com.wdg.springdatajpademo.controller;
import com.wdg.springdatajpademo.pojo.User;
import com.wdg.springdatajpademo.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author WDG
* @date 2019-2-4
*/
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 分页查询
* @param page
* @param size
* @return
*/
@GetMapping("/page/{page}/{size}")
public List<User> findByPage(@PathVariable Integer page,@PathVariable Integer size){
return userService.findByPage(page,size).getContent();
}
/**
* id查询用户
* @param userId
* @return
*/
@GetMapping("/{userId}")
public User findByUserId(@PathVariable Integer userId){
return userService.findById(userId);
}
/**
* 注册用户
* @param user
* @return
*/
@PostMapping("/addUser")
public Map<String,Object> addUser(@RequestBody User user){
Map map = new HashMap();
try{
userService.addUser(user);
}catch (Exception e){
e.printStackTrace();
map.put("result",false);
map.put("message","添加失败");
return map;
}
map.put("result",true);
map.put("message","添加成功");
return map;
}
/**
* 分页+条件查询
* @param page
* @param size
* @param user
* @return
*/
@PostMapping("/pageandselect/{page}/{size}")
public Map<String,Object> findByPageAndSelect(@PathVariable Integer page,
@PathVariable Integer size,
@RequestBody User user){
Map<String,Object> map = new HashMap<String,Object>();
Page<User> result = userService.findByPageAndSelect(page, size, user);
map.put("total",result.getTotalElements());
map.put("totalPages",result.getTotalPages());
map.put("data",result.getContent());
return map;
}
/**
* 修改用户
* @param user
* @return
*/
@PutMapping("/updateUser")
public Map<String,Object> updateUser(@RequestBody User user){
Map map = new HashMap();
try{
userService.updateUser(user);
}catch (Exception e){
e.printStackTrace();
map.put("result",false);
map.put("message","修改失败");
return map;
}
map.put("result",true);
map.put("message","修改成功");
return map;
}
/**
* 删除用户
* @param userId
* @return
*/
@DeleteMapping("/deleteUser/{userId}")
public Map<String,Object> deleteUser(@PathVariable Integer userId){
Map map = new HashMap();
try{
userService.deleteUser(userId);
}catch (Exception e){
e.printStackTrace();
map.put("result",false);
map.put("message","删除失败");
return map;
}
map.put("result",true);
map.put("message","删除成功");
return map;
}
/**
* 根据用户名修改用户
* @param user
* @return
*/
@PutMapping("/updateUserByName")
public Map<String,Object> updateUserByName(@RequestBody User user){
Map map = new HashMap();
try{
userService.updateUserByName(user);
}catch (Exception e){
e.printStackTrace();
map.put("result",false);
map.put("message","修改失败");
return map;
}
map.put("result",true);
map.put("message","修改成功");
return map;
}
/**
* 根据年龄查询用户信息
* @param age
* @return
*/
@GetMapping("/findUserByAge/{age}")
public List<User> findUserByAge(@PathVariable Integer age){
return userService.findUserByAge(age);
}
}
7、用postman进行测试即可,亲测可用。controller层对于异常处理代码不够简洁,下节总结SpringBoot 中使用全局异常处理器返回处理结果