java jpa总结

时间:2025-08-29 13:12:01来源:互联网

下面小编就为大家分享一篇java jpa总结,具有很好的参考价值,希望对大家有所帮助。

简介

JPA是ORM框架(对象关系映射,面向对象的思想来处理数据库操作)的一套规范,它只提供接口,实现过程要其他框架进行实现。

JPA(JAVA Persistence API)是Sun官方提出的Java持久化规范,用来方便大家操作数据库,真正干活的是Hibernate,TopLink等实现了JPA规范的框架,默认是Hibernate。

springboot的jpa

添加依赖:

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-jpa</artifactId>

</dependency>

配置

application.properties文件中添加配置

spring.data.jpa.repositories.enabled=true

spring.jpa.show-sql设置为true表示控制台显示sql

常用注解

@Entity //告诉JPA这是一个实体类(和数据表映射的类)

@Table来指定和哪个数据表对应;

@Id //这是一个主键

@GeneratedValue(strategy = GenerationType.IDENTITY)//自增主键

@Column(name = "last_name",length = 50) //这是和数据表对应的一个列,括号不写默认和属性名一样

@Query(value=" 这里就是查询语句")

 

@Query支持hql和原生sql两种方式,默认是hql ,hql就是语句中用的是实体名字和实体属性,原生sql用的表名字和表字段

@Query("select u from User u where u.emailAddress = ?1")

  User findByEmailAddress(String emailAddress);

@Modifying

    @Transactional

    @Query("update CardConfig  set cardStatus=?1 where  id in ?2")

    void updateCardStatus( Integer status,List<Integer> listIds);

/ @Param 代替参数占位符,  hql或者sql里就用  :firstname替换方法里的参数顺序可以打乱

 @Query("select u from User u where u.firstname = :firstname or u.lastname = :lastname")

  User findByLastnameOrFirstname(@Param("lastname") String lastname,

                                 @Param("firstname") String firstname);

//返回字段 组成新的entity返回 类名必须是全写的

@Query(value="select new com.hikvision.metro.modules.repository.entity.CameraIndexs(c.preOneCameraIndexcode, c.preTwoCameraIndexcode, c.backOneCameraIndexcode) from StationDeviceConfig c")

    List<CameraIndexs> getAllCameraIndexs();

 

语句可以直接放到数据库中执行 nativeQuery=true

Modifying

    @Query(value="select status from  t_station_device_config where pre_one_camera_indexcode=?1",nativeQuery = true)

    List<Integer> findStatusByPreOneCameraIndexcode(String index);

 

@EnableJpaRepositories

在Springboot应用开发中使用JPA时,通常在主应用程序所在包或者其子包的某个位置定义我们的Entity和Repository,这样基于Springboot的自动配置,无需额外配置,我们定义的Entity和Repository即可被发现和使用。但有时候我们需要定义Entity和Repository不在应用程序所在包及其子包,那么这时候就需要使用@EntityScan和@EnableJpaRepositories了。

@EntityScan用来扫描和发现指定包及其子包中的Entity定义。其用法如下:

@EntityScan(basePackages = {"com.department.entities","come.employee.entities"})

如果多处使用@EntityScan,它们的basePackages集合能覆盖所有被Repository使用的Entity即可,集合有交集也没有关系。但是如果不能覆盖被Repository使用的Entity,应用程序启动是会出错,比如:

 

Not a managed type: com.customer.entities.Customer

@EnableJpaRepositories

@EnableJpaRepositories用来扫描和发现指定包及其子包中的Repository定义。其用法如下:

 

@EnableJpaRepositories(basePackages = {"com.department.repositories","come.employee.repositories"})

如果多处使用@EnableJpaRepositories,它们的basePackages集合不能有交集,并且要能覆盖所有需要的Repository定义。

 

如果有交集,相应的Repository会被尝试反复注册,从而遇到如下错误:

 

The bean ‘OrderRepository’, defined in xxx, could not be registered. A bean with that name has already been defined in xxx and overriding is disabled.

 

如果不能覆盖所有需要的Repository定义,会遇到启动错误:

 

Parameter 0 of method setCustomerRepository in com.service.CustomerService required a bean of type ‘come.repo.OrderRepository’ that could not be found.

 

关键字

 

实例

 

实体类

import javax.persistence.*;

 

@Entity

@Table(name="t_users")

public class Users {

 

@Id //主键id

@GeneratedValue(strategy=GenerationType.IDENTITY)//主键生成策略

@Column(name="id")//数据库字段名

private Integer id;

 

@Column(name="name")

private String name;

 

@Column(name="age")

private Integer age;

 

@Column(name="address")

private String address;

 

@ManyToOne(cascade = CascadeType.PERSIST) //表示多方

@JoinColumn(name ="role_id") //维护一个外键,外键在Users一侧

private Roles roles;

 

public Roles getRoles() {

return roles;

}

 

public void setRoles(Roles roles) {

this.roles = roles;

}

 

public Integer getId() {

return id;

}

 

public void setId(Integer id) {

this.id = id;

}

 

public String getName() {

return name;

}

 

public void setName(String name) {

this.name = name;

}

 

public Integer getAge() {

return age;

}

public void setAge(Integer age) {

this.age = age;

}

public String getAddress() {

return address;

}

public void setAddress(String address) {

this.address = address;

}

}

 

 

DAO接口

import org.springframework.data.jpa.repository.JpaRepository;

 

import com.bjsxt.pojo.Users;

/**

 * 参数一 T :当前需要映射的实体

 * 参数二 ID :当前映射的实体中的OID的类型

 *

 */

public interface UsersRepository extends JpaRepository<Users,Integer> {

 

}

 

JpaRepository 这个父接口,提供了CRUD, 分页等等一系列的查询,在项目中直接拿来用,不需要二次开发。在开发中我们并不需要写SQL语句

 

接口说明:

SpringBoot JPA提供的核心接口

 

 1、Repository接口

 2、CrudRepository接口

 3、PagingAndSortingRepository接口

 4、JpaRepository接口

 5、JPASpecificationExecutor接口

 

Repository接口的使用

 

 提供了方法名称命名查询方式

 提供了基于@Query注解查询与更新

 

  • dao层接口(方法名称命名查询方式)

public interface UsersRepositoryByName extends Repository<Users,Integer> {

    //方法名称必须要遵循驼峰式命名规则,findBy(关键字)+属性名称(首字母大写)+查询条件(首字母大写)

    List<Users> findByName(String name);

 

    List<Users> findByNameAndAge(String name,Integer age);

 

    List<Users> findByNameLike(String name);

 

}

 

于@Query注解查询与更新

public interface UsersRepositoryQueryAnnotation extends JpaRepository<Users,Integer> {

    @Query("from Users where name = ?")

    List<Users> queryByNameUseHQL(String name);

 

    @Query(value = "select * from t_user where name=?",nativeQuery = true)

    List<Users> queryByNameUseSQL(String name);

 

    @Query("update Users set name=? where id=?")

    @Modifying  //需要执行一个更新操作

    void updateUsersNameById(String name,Integer id);

 

}

CrudRepository接口的使用

CrudRepository接口,主要是完成一些增删改查的操作。注意:CrudRepository接口继承了Repository接口

public interface UsersRepositoryCrudRepository extends CrudRepository<Users,Integer> {

}

@Test

public void testCrudRepositorySave() {

Users users=new Users();

users.setName("青衫");

users.setAge(30);

users.setAddress("湖南怀化");

this.usersRepositoryCrudRepository.save(users);

}

 

@Test

public void testCrudRepositoryUpdate() {

Users users=new Users();

users.setId(4);

users.setName("青");

users.setAge(18);

users.setAddress("怀化");

this.usersRepositoryCrudRepository.save(users);

}

 

@Test

public void testCrudRepositoryFindOne() {

 

Users users=this.usersRepositoryCrudRepository.findOne(4);

System.out.println(users);

}

 

@Test

public void testCrudRepositoryFindAll() {

List<Users> list= (List<Users>) this.usersRepositoryCrudRepository.findAll();

for (Users user:list){

System.out.println(user);

}

}

 

@Test

public void testCrudRepositoryDeleteById() {

this.usersRepositoryCrudRepository.delete(4);

 

}

PagingAndSortingRepository接口的使用

该接口提供了分页与排序的操作,注意:该接口继承了CrudRepository接口

public interface UsersRepositoryPagingAndSorting extends PagingAndSortingRepository<Users,Integer> {

}

//Order 定义了排序规则

Sort.Order order=new Sort.Order(Sort.Direction.DESC,"id");

//Sort对象封装了排序规则

Sort sort=new Sort(order);

List<Users> list= (List<Users>) this.usersRepositoryPagingAndSorting.findAll(sort);

//Pageable:封装了分页的参数,当前页,煤业显示的条数。注意:它的当前页是从0开始

//PageRequest(page,size):page表示当前页,size表示每页显示多少条

Pageable pageable=new PageRequest(1,2);

Page<Users> page=this.usersRepositoryPagingAndSorting.findAll(pageable);

 

Sort sort=new Sort(new Sort.Order(Sort.Direction.DESC,"id"));

Pageable pageable=new PageRequest(0,2,sort);

Page<Users> page=this.usersRepositoryPagingAndSorting.findAll(pageable);

 

 

JpaRepository接口

 

 该接口继承了PagingAndSortingRepository。对继承的父接口中方法的返回值进行适配。

public interface UsersRepository extends JpaRepository<Users,Integer> {

 

}

JPASpecificationExecutor接口

 

 该接口主要是提供了多条件查询的支持,并且可以在查询中添加排序与分页。注意JPASpecificationExecutor是单独存在的。完全独立

public interface UserRepositorySpecification extends JpaRepository<Users,Integer>,JpaSpecificationExecutor<Users> {

}

@Test

public void testJpaSpecificationExecutor1() {

/**

 * Specification:用于封装查查询条件

 */

Specification<Users> spec=new Specification<Users>() {

//Predicate:封装了单个查询条件

 

/**

 * @param root 对查询对象属性的封装

 * @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order

 * @param criteriaBuilder 查询条件的构造器

 * @return

 */

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

//where name="张三"

/**

 * 参数一:查询的属性

 * 参数二:条件的值

 */

Predicate predicate=criteriaBuilder.equal(root.get("name"),"张三");

return predicate;

}

};

List<Users> list=this.userRepositorySpecification.findAll(spec);

for (Users users:list){

System.out.println(users);

}

}

 

/**

 * JpaSpecificationExecutor 多条件查询方式一

 */

@Test

public void testJpaSpecificationExecutor2() {

/**

 * Specification:用于封装查查询条件

 */

Specification<Users> spec=new Specification<Users>() {

//Predicate:封装了单个查询条件

 

/**

 * @param root 对查询对象属性的封装

 * @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order

 * @param criteriaBuilder 查询条件的构造器

 * @return

 */

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

//where name="张三" and age=20

/**

 * 参数一:查询的属性

 * 参数二:条件的值

 */

List<Predicate> list=new ArrayList<>();

list.add(criteriaBuilder.equal(root.get("name"),"张三"));

list.add(criteriaBuilder.equal(root.get("age"),20));

Predicate[] arr=new Predicate[list.size()];

return criteriaBuilder.and(list.toArray(arr));

}

};

List<Users> list=this.userRepositorySpecification.findAll(spec);

for (Users users:list){

System.out.println(users);

}

}

 

/**

 * JpaSpecificationExecutor 多条件查询方式二

 */

@Test

public void testJpaSpecificationExecutor3() {

/**

 * Specification:用于封装查查询条件

 */

Specification<Users> spec=new Specification<Users>() {

//Predicate:封装了单个查询条件

 

/**

 * @param root 对查询对象属性的封装

 * @param criteriaQuery 封装了我们要执行的查询中的各个部分的信息,select from order

 * @param criteriaBuilder 查询条件的构造器

 * @return

 */

@Override

public Predicate toPredicate(Root<Users> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {

//where name="张三" and age=20

/**

 * 参数一:查询的属性

 * 参数二:条件的值

 */

/*List<Predicate> list=new ArrayList<>();

list.add(criteriaBuilder.equal(root.get("name"),"张三"));

list.add(criteriaBuilder.equal(root.get("age"),20));

Predicate[] arr=new Predicate[list.size()];*/

//(name='张三' and age=20) or id=2

return criteriaBuilder.or(criteriaBuilder.and(criteriaBuilder.equal(root.get("name"),"张三"),criteriaBuilder.equal(root.get("age"),20)),criteriaBuilder.equal(root.get("id"),1));

}

};

 

Sort sort=new Sort(new Sort.Order(Sort.Direction.DESC,"id"));

List<Users> list=this.userRepositorySpecification.findAll(spec,sort);

for (Users users:list){

System.out.println(users);

}

}

 

其他总结

Specification

 

本站部分内容转载自互联网,如果有网站内容侵犯了您的权益,可直接联系我们删除,感谢支持!