springboot集成spring-data-JPA

Spring Data是Spring的一个子项目。用于简化数据库访问,支持NoSQL和关系数据存储。其主要目标是使用数据库的访问变得方便快捷。
SpringData 项目所支持NoSQL存储:
MongoDB(文档数据库)
Neo4j(图形数据库)
Redis(键/值存储)
Hbase(列族数据库)
SpringData 项目所支持的关系数据存储技术:
JDBC
JPA
Spring Data : 致力于减少数据访问层 (DAO) 的开发量. 开发者唯一要做的,就只是声明持久层的接口,其他都交给 Spring Data JPA 来帮你完成!
在这里插入图片描述
SpringData JPA只是SpringData框架下的一个基于JPA标准操作数据的模块。
Spring Data JPA 通过提供基于JPA的Repository极大地减少了JPA作为数据访问方案的代码量,开发者可以省略持久层业务逻辑的工作,唯一要做的就是声明持久层借口,其他的都交给Spring Data JPA 完成.

Repository接口
1、Repository是一个空接口,即:是一个标记接口,表示任何继承它的接口都是仓库接口类
2、若我们继承了Repository,则该接口会被Ioc容器表示为一个Repository Bean,放入到IOC容器中,进而可以在该接口中定义满足一定规范的方法
3、实际上也可以通过@RepositoryDefinition(domainClass = Person.class, idClass = Long.class)来替代继承Repository接口
子接口
CrudRepository:继承Repository,实现一组CURD相关的方法

T save(T entity);//保存单个实体   
Iterable<T> save(Iterable<? extends T> entities);//保存集合         
T findOne(ID id);//根据id查找实体          
boolean exists(ID id);//根据id判断实体是否存在          
Iterable<T> findAll();//查询所有实体,不用或慎用!          
long count();//查询实体数量          
void delete(ID id);//根据Id删除实体          
void delete(T entity);//删除一个实体   
void delete(Iterable<? extends T> entities);//删除一个实体的集合          
void deleteAll();//删除所有实体,不用或慎用!

PagingAndSortingRespository:继承CrudRepository,实现了一组分页排序相关的方法

/该接口提供了分页与排序功能   
Iterable<T> findAll(Sort sort); //排序    
Page<T> findAll(Pageable pageable); //分页查询(含排序功能) 

JpaRepository:继承PagingAndSortingRespository,实现了一组JPA规范相关的方法

<S extends T> List<S> saveAll(Iterable<S> var1):批量保存
void flush():刷新。同步Jpa缓存和数据库
<S extends T> S saveAndFlush(S var1):相当于JPA的merge方法
void deleteInBatch(Iterable<T> var1):批量删除
void deleteAllInBatch():批量删除所有

自定义的XxxRepository:需要继承JpaRepository,这样该接口就具备了通用的数据访问控制层的能力
JpaSpecificationExecutor:不属于Repository体系,实现一组 JPA Criteria 查询相关的方法

开发步骤:

1、引入依赖

<!-- springdata 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>

2、配置mysql配置及其JPA配置

######################################数据库配置###################################
spring.datasource.url=jdbc:mysql://135.*.*.4:3306/xxl_job?autoReconnect=true&useUnicode=true&characterEncoding=utf8&useSSL=false
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.username=**
spring.datasource.password=**
 
#######################################SpringData配置##################################
spring.jpa.database=MYSQL
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
#通过方法名解析sql的策略,具体说明可以看README,这里就不配置了
#第一:org.hibernate.cfg.DefaultNamingStrategy  这个直接映射,不会做过多的处理(前提没有设置@Table@Column等属性的时候)。如果有@Column则以@Column为准 
#第二:org.hibernate.cfg.ImprovedNamingStrategy  表名,字段为小写,当有大写字母的时候会转换为分隔符号“_”。
spring.jpa.hibernate.naming-strategy=org.hibernate.cfg.ImprovedNamingStrategy

#编码格式
spring.http.encoding.force=true
spring.http.encoding.charset=UTF-8
spring.http.encoding.enabled=true
server.tomcat.uri-encoding=UTF-8

3、创建实体类

package qingxia.tang.jpa.bean;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

import org.hibernate.annotations.GenericGenerator;


/**
 * 使用@Entity进行实体类的持久化操作,当JPA检测到我们的实体类中有@Entity注解时,会在数据库生成相应的表结构信息
 * 如何指定主键和主键的生成策略@Id
 * @author tangqingxia
 *
 */
@Entity
public class Cat {
	/**
	 * @GeneratedValue(strategy=GenerationType.AUTO)指定主键生成规则,mysql默认的是自增长
	 */
	@Id@GeneratedValue(strategy=GenerationType.AUTO)
	private int id;
	private String name;
	private int age;
	/**
	 * @Column注解定义数据库表中字段名称
	 */
	@Column(name="address_id")
	private Long addressId;
	
	public Long getAddressId() {
		return addressId;
	}
	public void setAddressId(Long addressId) {
		this.addressId = addressId;
	}
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}

}

4、创建repository接口类

package qingxia.tang.jpa.repository;

import org.springframework.data.repository.CrudRepository;

import qingxia.tang.jpa.bean.Cat;

public interface CatRepository extends CrudRepository<Cat, Integer>{

}

package qingxia.tang.jpa.repository;

import java.util.List;





import javax.transaction.Transactional;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Modifying;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import qingxia.tang.jpa.bean.Cat;
/**
* 此类全部是自定义接口类
**/
public interface CatDefineRepository extends JpaRepository<Cat, Integer>{
	
	/**
	 * Repository 查询方法定义规范
	 * 一、方法必须以find|read|get开头
	 * 二、涉及查询条件时,条件的实行用条件关键字连接,注意:条件属性需要首字母大写
	 * 三、支持属性的级联查询,
	 * 1、若当前类有符合条件的属性,会优先使用属性,而不是使用级联属性
	 * 2、若要使用级联属性,则属性之间用 _ 连接。而为了避免歧义,推荐使用 _ 分隔的写法。
	 * 四、缺点
	 * 方法名很长、不能用于子查询
	 */
	
	
	/**
	 * 自定义根据name查询cat对象
	 * @param name
	 * @return
	 */
	public Cat getCatByName(String name);
	
    public Cat getByAddressId(Long id);
    /**
     * @Query注解sql表的首字母要大写如Cat而不能是cat
     * 1、自定义的JPQL语句以更灵活的查询
     * @return
     */
    @Query("from Cat t")
    public List<Cat> getCatAll();
    
    /**
     * 使用占位符:参数顺序必须和JPQL中的顺序一致
     * addressId要与Cat实体类的属性名保持一致,而非表中字段名
     * 参数类型要与Cat实体类中对应的属性类型保持一致
     * @param id
     * @param age
     * @return
     */
    @Query("from Cat t where t.addressId=?1 and t.age=?2")
    public List<Cat> getCatByaddressIdAndByAge(Long id,int age);
    
    /**
     * 使用命名参数:这种写法可以随便设置参数顺序
     * @param age
     * @param id
     * @return
     */
    @Query("from Cat t where t.addressId=:id and t.age=:age")
    public List<Cat> getCatByaddressIdAndByAge1(@Param("age")int age,@Param("id")Long id);
    
    /**
     * spring data允许在占位符上添加%(适用于模糊查询like:%占位符%)
     * @param name
     * @return
     */
    @Query("from Cat t where t.name like %?1%")
    public Cat getCatByNa(String name);
    
    
    /**
     * @Query支持原生sql查询
     * @return
     */
    @Query(value="select count(1) from Cat t",nativeQuery=true)
    public int getAllCatCount();
    
    /**
     * @Modifying:可以使用该注解来实现通过JPQL修改和删除(JPQL不支持添加)
     * 注意:更新和删除操作需要事务支持
     * 在@Query中编写JPQL语句,但是必须添加@Modifying进行修饰来告诉JPA这是修改的操作
     * @param name
     * @param age
     * @param id
     */
    @Modifying
    @Query(value="update Cat t set t.name=?1 where t.age=?2 and t.id=?3")
    @Transactional
    public void updateName(String name,int age,int id);
}


5、编写service层

package qingxia.tang.jpa.service;

import java.util.List;

import javax.annotation.Resource;

import org.springframework.stereotype.Service;

import qingxia.tang.jpa.bean.Cat;
import qingxia.tang.jpa.repository.CatDefineRepository;
import qingxia.tang.jpa.repository.CatRepository;



@Service
public class CatService {
	@Resource
	CatRepository catRepository;
	
	@Resource
	CatDefineRepository catDefineRepository;
	  
	public void save(Cat cat){
		catRepository.save(cat);
	}
	
	public void delete(int id){
		catRepository.delete(id);
	}
	
	public Iterable<Cat> findAll(){
		Iterable<Cat> findAll = catRepository.findAll();
		return findAll;
	}
	
	public Cat getCatByName(String name){
		Cat cat = catDefineRepository.getCatByName(name);
		return cat;
	}
	
	public Cat getByAddressId(Long id){
		Cat byAddress_Id = catDefineRepository.getByAddressId(id);
		return byAddress_Id;
	}
	
	public List<Cat> getCatAll(){
		List<Cat> catAll = catDefineRepository.getCatAll();
		return catAll;
	}
	
	public List<Cat> getCatByaddressIdAndByAge(Long id,int age){
		List<Cat> catByaddressIdAndByAge = catDefineRepository.getCatByaddressIdAndByAge(id, age);
		return catByaddressIdAndByAge;
	}
	
	public List<Cat> getCatByaddressIdAndByAge1(Long id,int age){
		List<Cat> catByaddressIdAndByAge1 = catDefineRepository.getCatByaddressIdAndByAge1(age, id);
		return catByaddressIdAndByAge1;
	}
	
	public Cat getCatByNa(String name){
		Cat catByNa = catDefineRepository.getCatByNa(name);
		return catByNa;
	}
	
	public int getAllCatCount(){
		int allCatCount = catDefineRepository.getAllCatCount();
		return allCatCount;
	}
	
	public void updateName(String name,int age,int id){
		catDefineRepository.updateName(name, age, id);
	}

}

6、编写controller层

package qingxia.tang.jpa.controller;

import java.util.List;

import javax.annotation.Resource;
import javax.transaction.Transactional;

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import qingxia.tang.jpa.bean.Cat;
import qingxia.tang.jpa.service.CatService;

@RestController
public class CatController {
	
	@Resource
	CatService catService;
	
	@RequestMapping("/save")
	@Transactional
	public String save(Cat cat){
		cat.setAge((int)((Math.random())*100));
		cat.setName("理科");
		cat.setAddressId(16l);
		catService.save(cat);
		return "save is ok";
	}
	
	@RequestMapping("/delete")
	@Transactional
	public String delete(int id){
		catService.delete(id);
		return "delete is OK";
	}
	
	@RequestMapping(value="/findAll",produces={"application/json;charset=UTF-8"})
	public Iterable<Cat> findAll(){
		Iterable<Cat> findAll = catService.findAll();
		return findAll;
	}
	
	/**
	 * http://localhost:8080/getCatByName?name=理科
	 * @param name
	 * @return
	 */
	@RequestMapping(value="/getCatByName",produces={"application/json;charset=UTF-8"})
	public Cat getCatByName(String name){
		Cat cat = catService.getCatByName(name);
		return cat;
	}
	
	/**
	 * http://localhost:8080/getByAddress_Id?id=450
	 * @param id
	 * @return
	 */
	@RequestMapping(value="/getByAddress_Id",produces={"application/json;charset=UTF-8"})
	public Cat getByAddressId(Long id){
		Cat byAddress_Id = catService.getByAddressId(id);
		return byAddress_Id;
	}
	
	@RequestMapping(value="/getCatAll",produces={"application/json;charset=UTF-8"})
	public List<Cat> getCatAll(){
		List<Cat> catAll = catService.getCatAll();
		return catAll;
	}
	
	/**
	 * http://localhost:8080/getCatByaddressIdAndByAge?id=16&age=17
	 * @param id
	 * @param age
	 * @return
	 */
	@RequestMapping(value="/getCatByaddressIdAndByAge",produces={"application/json;charset=UTF-8"})
	public List<Cat> getCatByaddressIdAndByAge(Long id,int age){
		List<Cat> catByaddressIdAndByAge = catService.getCatByaddressIdAndByAge(id, age);
		return catByaddressIdAndByAge;
	}
	
	/**
	 * http://localhost:8080/getCatByaddressIdAndByAge1?id=16&age=67
	 * @param id
	 * @param age
	 * @return
	 */
	@RequestMapping(value="/getCatByaddressIdAndByAge1",produces={"application/json;charset=UTF-8"})
	public List<Cat> getCatByaddressIdAndByAge1(Long id,int age){
		List<Cat> catByaddressIdAndByAge1 = catService.getCatByaddressIdAndByAge1(id, age);
		return catByaddressIdAndByAge1;
	}
	
	/**
	 * http://localhost:8080/getCatByNa?name=3
	 * @param name
	 * @return
	 */
	@RequestMapping(value="/getCatByNa",produces={"application/json"})
	public Cat getCatByNa(String name){
		Cat catByNa = catService.getCatByNa(name);
		return catByNa;
	}
	
	/**
	 * http://localhost:8080/getAllCatCount
	 * @return
	 */
	@RequestMapping(value="/getAllCatCount",produces={"application/json"})
	public int getAllCatCount(){
		int allCatCount = catService.getAllCatCount();
		return allCatCount;
	}
	
	/**
	 * http://localhost:8080/updateName?name=%E6%96%87%E7%A7%91&age=16&id=3
	 * @param name
	 * @param age
	 * @param id
	 * @return
	 */
	@RequestMapping("/updateName")
	public String updateName(String name,int age,int id){
		catService.updateName(name, age, id);
		return "update is ok";
	}

}

总结:springboot集成springdata Jpa,需要访问数据库进行业务逻辑处理时,首先将自己定义的repositoty集成JpaRepository即可使用repository提供的所有接口能力,如repository自带接口能力不满足实际的业务需求,需自己重新定义接口时,建议用Query注解的形式开发新的接口进行mysql数据库交互。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值