本文共 9201 字,大约阅读时间需要 30 分钟。
JPA全称Java Persistence API.JPA通过JDK 5.0注解或XML描述对象-关系表的映射关系,并将运行期的实体对象持久化到数据库中。
JPA 的目标之一是制定一个可以由很多供应商实现的API,并且开发人员可以编码来实现该API,而不是使用私有供应商特有的API。
JPA是需要Provider来实现其功能的,Hibernate就是JPA Provider中很强的一个,应该说无人能出其右。从功能上来说,JPA就是Hibernate功能的一个子集。
本教程大概流程:
首先我的开发环境:
jdk1.8+maven3+IDEA4.0.0 springboot-jpa springboot-jpa 0.0.1-SNAPSHOT jar springboot-jpa Demo project for Spring Boot org.springframework.boot spring-boot-starter-parent 2.0.0.RELEASE UTF-8 UTF-8 1.8 org.springframework.boot spring-boot-starter org.springframework.boot spring-boot-starter-test org.springframework.boot spring-boot-starter-web mysql mysql-connector-java org.springframework.boot spring-boot-starter-data-jpa org.projectlombok lombok 1.16.18 org.springframework.boot spring-boot-test 1.4.5.RELEASE test com.querydsl querydsl-jpa com.querydsl querydsl-apt provided com.alibaba druid 1.0.26 com.alibaba fastjson 1.2.15 com.alibaba druid 1.1.3 org.springframework.boot spring-boot-maven-plugin com.mysema.maven apt-maven-plugin 1.1.3 target/generated-sources/java com.querydsl.apt.jpa.JPAAnnotationProcessor
spring.datasource.url=jdbc:mysql://localhost:3306/userspring.datasource.username=rootspring.datasource.password=rootspring.datasource.driver-class-name=com.mysql.jdbc.Driverspring.datasource.type: com.alibaba.druid.pool.DruidDataSourcespring.datasource.filters:statspring.datasource.maxActive: 20spring.datasource.initialSize: 1spring.datasource.maxWait: 60000spring.datasource.minIdle: 1spring.datasource.timeBetweenEvictionRunsMillis: 60000spring.datasource.minEvictableIdleTimeMillis: 300000spring.datasource.validationQuery: select 'x'spring.datasource.testWhileIdle: truespring.datasource.testOnBorrow: falsespring.datasource.testOnReturn: falsespring.datasource.poolPreparedStatements: truespring.datasource.maxOpenPreparedStatements: 20spring.jpa.properties.hibernate.hbm2ddl.auto=updatespring.jpa.show-sql=true
package com.fantj.model;import lombok.Data;import javax.persistence.*;import java.util.Date;@Data@Entity@Table(name = "user")public class User { public User(){ } @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @Column(nullable = false) private String username; @Column(nullable = false) private Date birthday; @Column(nullable = false) private String sex; @Column(nullable = false) private String address;}
@Data注解是 lombok 依赖包下的注解,它可以自动帮我们生成set/getter方法,简化代码量。有兴趣的可以详细了解,这里不做多解释。
package com.fantj.repostory;/** * Created by Fant.J. */@Repositorypublic interface UserRepository extends JpaRepository{ //自定义repository。手写sql @Query(value = "update user set name=?1 where id=?4",nativeQuery = true) //占位符传值形式 @Modifying int updateById(String name,int id); @Query("from User u where u.username=:username") //SPEL表达式 User findUser(@Param("username") String username);// 参数username 映射到数据库字段username}
注意:只有@Query 的注解下不能使用insert,我们需要在上面再添加个@Modify注解,我习惯都加,nativeQuery 是询问是否使用原生sql语句。多表查询也是在这里手写sql,不做演示。因为后面我们用更好的支持多表查询的工具框架 QueryDSL来帮助我们更简洁的实现它。
UserService .java
package com.fantj.service;/** * Created by Fant.J. */public interface UserService { /** 删除 */ public void delete(int id); /** 增加*/ public void insert(User user); /** 更新*/ public int update(User user); /** 查询单个*/ public User selectById(int id); /** 查询全部列表*/ public IteratorselectAll(int pageNum, int pageSize);}
UserServiceImpl.java
package com.fantj.service.impl;/** * Created by Fant.J. */@Servicepublic class UserServiceImpl implements UserService { @Autowired private UserRepository userRepository; /** * 删除 * * @param id */ @Override public void delete(int id) { userRepository.deleteById(id); } /** * 增加 * * @param user */ @Override public void insert(User user) { userRepository.save(user); } /** * 更新 * * @param user */ @Override public int update(User user) { userRepository.save(user); return 1; } /** * 查询单个 * * @param id */ @Override public User selectById(int id) { Optionaloptional = userRepository.findById(id); User user = optional.get(); return user; } /** * 查询全部列表,并做分页 * @param pageNum 开始页数 * @param pageSize 每页显示的数据条数 */ @Override public Iterator selectAll(int pageNum, int pageSize) { //将参数传给这个方法就可以实现物理分页了,非常简单。 Sort sort = new Sort(Sort.Direction.DESC, "id"); Pageable pageable = new PageRequest(pageNum, pageSize, sort); Page users = userRepository.findAll(pageable); Iterator userIterator = users.iterator(); return userIterator; }}
分页不止可以这样做,也可以在Controller层进行实例化和初始化然后将Pageable对象传给Service。
当然也可以对分页进行封装,封装后的展示。Pagedatas = userRepository.findAll(PageableTools.basicPage(1, 5, new SortDto("id")));
是不是很简洁。大家可以自己尝试一下。
package com.fantj.controller;/** * Created by Fant.J. */@RestController@RequestMapping("/user")public class UserController { @Autowired private UserService userService; @RequestMapping(method = RequestMethod.GET,value = "/delete/{id}") public void delete(@PathVariable("id")int id){ userService.delete(id); } @RequestMapping(method = RequestMethod.POST,value = "/insert") public void insert(User user){ userService.insert(user); } @RequestMapping(method = RequestMethod.POST,value = "/update/{id}") public void update(@RequestParam User user){ userService.update(user); } @RequestMapping(method = RequestMethod.GET,value = "/{id}/select") public User select(@PathVariable("id")int id){ return userService.selectById(id); } @RequestMapping(method = RequestMethod.GET,value = "/selectAll/{pageNum}/{pageSize}") public ListselectAll(@PathVariable("pageNum") int pageNum, @PathVariable("pageSize") int pageSize){ Iterator userIterator = userService.selectAll(pageNum, pageSize); List list = new ArrayList<>(); while(userIterator.hasNext()){ list.add(userIterator.next()); } return list; }}
可以参考恒宇少年的四篇文章:
注意一点,目前springboot2.0 版本对JPA支持有误,如果你用springboot2 来配置querydsl,application启动类会运行不起来,正确的依赖包或者是配置类我还没有找到,希望有点子的朋友可以和我联系。 本人QQ:844072586
转载地址:http://dftla.baihongyu.com/