SpringData JPA 快速入门
SpringBoot 整合 SpringData-JPA 快速入门、
一 SpringBoot配置SpringData-JPA
1 引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
2 配置
配置 application.properties
server.port=4321
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/website?useUnicode=true&characterEncoding=UTF8&useSSL=false&serverTimezone=Asia/Shanghai
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.username=root
spring.datasource.password=root
#是否自动生成实体类对应的数据库表 true为自动生成表,false不自动生成
spring.jpa.generate-ddl=false
#数据库类型
spring.jpa.database=mysql
#打印日志
spring.jpa.show-sql=true
#方言设置
spring.jpa.database-platform=org.hibernate.dialect.MySQLDialect
添加注解
@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.mt.mapper")
public class Jpa01Application {
public static void main(String[] args) {
SpringApplication.run(Jpa01Application.class, args);
}
}
二 单表增删改查
SpringData-JPA为我们提供了JpaRepository 和 JpaSpecificationExecutor接口,我们只需要编写接口去继承这两个接口即可实现增删改查操作
单表查询示例:
entity:
@NoArgsConstructor
@AllArgsConstructor
@Data
@Entity //标注该类为数据库映射类
@Table(name = "mt_product_info") //默认获取类名转下划线作为对应的表,可以通过@table标注对应的表
public class MtProductInfo {
@Id //标注为主键
@GeneratedValue(strategy = GenerationType.IDENTITY)//标注id生成策略
private Integer id;
private String name;
private String summarize;
private Integer headImg;
private Integer productId;
private Integer sort;
private Integer status;
private Date createTime;
private String indexName;
private Integer indexIcon;
private Integer indexSort;
@Column(name = "index_isshow") //标注属性对应的字段,不加默认属性名转下划线
private Integer indexIsShow;
private String indexDesc;
private Integer systemImg;
}
repository:
public interface MtProductInfoMapper extends JpaRepository<MtProductInfo,Integer>, JpaSpecificationExecutor<MtProductInfo> {
}
测试:
@SpringBootTest
class Jpa02ApplicationTests {
@Autowired
private MtProductInfoMapper infoMapper;
@Test
void contextLoads() {
List<MtProductInfo> productInfoList = infoMapper.findAll();
productInfoList.forEach( System.out::print);
}
}
添加
直接通过JPARepository 提供的save方法
@Test
public void add(){
//如果没id 为添加,否则为修改,修改会重新设置所有字段值,不会忽略null
MtProductInfo info = new MtProductInfo();
info.setName("test1");
info.setStatus(0);
infoMapper.save(info);
}
删除
方式一
@Test
public void delete(){
infoMapper.deleteById(71);
}
方式二: @query
@Transactional
@Modifying
@Query("delete from MtProductInfo where name = :name")
public void delete(String name);
修改
方式一: 通过JPARepository提供的
@Test
public void update(){
MtProductInfo info = new MtProductInfo();
info.setName("test1");
info.setStatus(0);
info.setId(1); //设置了id即为修改,这里只将name修改为test1,状态修改为0 其他字段全部为null
infoMapper.save(info);
}
方式二: 通过 @query 进行修改,在repository接口内创建修改方法,通过@Query标注
@Transactional //修改需要事务支持
@Modifying //增删改必须标注@Modifying
@Query("update MtProductInfo set name = :#{#productInfo.name} ,status=:#{#productInfo.status}")
public void update( MtProductInfo productInfo );
//也可以这样写
@Transactional
@Modifying
@Query("update MtProductInfo set name = :name ,status=:status where id = :id")
public void update( String name,Integer status,Integer id );
查询
方式一:通过JpaRepository提供的方法进行查询
@Test
public void query(){
//根据id 查询
Optional<MtProductInfo> infoOp = infoMapper.findById(1);
if(infoOp.isPresent()){
System.out.println("查询到对象===>"+infoOp.get());
}else{
System.out.println("对象不存在");
}
//如果查询为null 这返回传入的对象否则返回数据库对象
infoOp.orElse(new MtProductInfo());
List<MtProductInfo> all = infoMapper.findAll();
}
方式二: 通过自定义方法名查询
SpringData-Jpa一个强大的功能就是可以通过拼接方法的名称来创建查询条件
//where name like '' and status =1
public List<MtProductInfo> queryByNameLikeAndStatusEqualsOrderBySortDesc(String name,Integer status);
方式三:通过JpaSpecificationExecutor 提供的方法进行自定义条件查询
@Test
@Test
public void query3(){
List<MtProductInfo> infoList = infoMapper.findAll(new Specification<MtProductInfo>() {
@Override
public Predicate toPredicate(Root<MtProductInfo> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
Path<String> name = root.get("summarize"); //数据库名称
Path<String> status = root.get("status"); //数据库名称
Predicate nameLike = criteriaBuilder.like(name, "%人大%");
Predicate statusEq = criteriaBuilder.equal(status, 1);
return criteriaBuilder.and(nameLike,statusEq);
}
});
infoList.forEach(System.out::println);
}
排序
@Test
public void query3(){
//排序,注意这里出入的是属性名不是字段名
Sort sort = Sort.by(Sort.Direction.DESC, "createTime").and(Sort.by(Sort.Direction.ASC, "name"));
List<MtProductInfo> infoList = infoMapper.findAll(new Specification<MtProductInfo>() {
@Override
public Predicate toPredicate(Root<MtProductInfo> root, CriteriaQuery<?> query, CriteriaBuilder criteriaBuilder) {
Path<String> name = root.get("summarize"); //数据库名称
return criteriaBuilder.like(name, "%人大%");
}
},sort);
//排序,传入的是属性名称,不是数据库字段名
infoList.forEach(System.out::println);
}
分页
@Test
public void query4(){
//分页查询 注意页数从0开始
Page<MtProductInfo> page = infoMapper.findAll(PageRequest.of(0, 2,Sort.by(Sort.Direction.ASC,"createTime")));
System.out.println("当前总页数==>"+page.getTotalPages() );
System.out.println("当前总条数==>"+page.getTotalElements() );
System.out.println("是否有上一页==>"+page.hasPrevious());
System.out.println("是否有下一页==>"+page.hasNext());
System.out.println("========================");
page.getContent().forEach(System.out::println);
}