springJPA

IDEA使用springJPA反向自动生成实体类

https://blog.csdn.net/linmengmeng_1314/article/details/101599559

 

dao层编写

需要继承两个接口

  • JpaRepository:封装了增删改查分页排序等基本操作,具体可以看JpaRepository的父类
  • JpaSpecificationExecutor:封装了标准查询
  • Interger是实体的主键类型
  • public interface UserDao extends JpaRepository, JpaSpecificationExecutor {
    }

 

操作数据库

插入/更新

  • save方法:传入的实体对象有主键则更新,没有主键则插入。

删除

  • delete系列方法

查询

  • count:统计                                                       long count = userDao.count();

  • exists系列方法:数据库中是否存在                  boolean b = userDao.existsById(2);

  • find系列方法:立即加载                                  Optional user = userDao.findById(2);
                                                                              System.out.println(user.get());

  • getOne:延迟加载,返回的是一个动态代理对象               User user = userDao.getOne(2);
                                                                                               System.out.println(user);

 

语句操作

除了调用spring data jpa内置的api,我们也可以在dao接口中定义我们自己的方法,通过@Query声明jpql或sql语句。

  • @Query
    • value:数据库操作语句
    • nativeQuery:是否是原生查询,默认false,即默认使用jpql查询
  • @Modifying:声明当前是一个更新操作,需要修改数据库数据。
    • 只能用于void或int/Integer的返回类型
    • 因为需要修改数据库数据,未防止修改失败造成未知后果,需要搭配事务管理来是使用
  • @Transactional:添加事务管理支持
    • 一般需要设置rollbackFor或者noRollbackFor,来表示什么情况下进行事务回滚
  • @Rollback:是否可以回滚,默认true

jpql查询

public interface UserDao extends JpaRepository, JpaSpecificationExecutor {

    @Query(value = "from User where name = :name and age = :age")
    public User findUserByName(@Param("name") String userName,@Param("age") int age);
}
 

jpql更新

@Query(value = "update User set name = :name where id = :id")
@Modifying
public Integer updateNameById(@Param("id") int id,@Param("name") String userName);


    @org.junit.Test
    @Transactional(rollbackFor = Exception.class)
    //@Rollback(value = false)//如果设置为fasle,即使发生异常也不会回滚
    public void testJpql(){
        User user = userDao.findUserByName("lili",18);
        System.out.println(user);

        userDao.updateNameById(user.getId(),"lili_2");
    }
 

 

原生sql语句查询

public interface UserDao extends JpaRepository, JpaSpecificationExecutor {
    @Query(value = "select * from user where name = :name and age = :age",nativeQuery = true)
    public User findUserByName(@Param("name") String userName,@Param("age") int age);
}
 

约定规则查询

spring data jpa制定了一些约定,如果按照这些约定来定义方法名,则会自动解析出sql语句。

findBy + 属性名 + 查询方式 + (And|Or) + 属性名 + 查询方式...

查询方式 方法命名 sql where字句
And findByNameAndPwd where name= ? and pwd =?
Or findByNameOrSex where name= ? or sex=?
Is,Equals findById,findByIdEquals where id= ?
Between findByIdBetween where id between ? and ?
LessThan findByIdLessThan where id < ?
LessThanEquals findByIdLessThanEquals where id <= ?
GreaterThan findByIdGreaterThan where id > ?
GreaterThanEquals findByIdGreaterThanEquals where id > = ?
After findByIdAfter where id > ?
Before findByIdBefore where id < ?
IsNull findByNameIsNull where name is null
isNotNull,NotNull findByNameNotNull where name is not null
Like findByNameLike where name like ?
NotLike findByNameNotLike where name not like ?
StartingWith findByNameStartingWith where name like '?%'
EndingWith findByNameEndingWith where name like '%?'
Containing findByNameContaining where name like '%?%'
OrderBy findByIdOrderByXDesc where id=? order by x desc
Not findByNameNot where name <> ?
In findByIdIn(Collection c) where id in (?)
NotIn findByIdNotIn(Collection c) where id not in (?)
True findByAaaTue where aaa = true
False findByAaaFalse where aaa = false
IgnoreCase findByNameIgnoreCase where UPPER(name)=UPPER(?)

简单挑几个示例:

public interface UserDao extends JpaRepository, JpaSpecificationExecutor {
    public User findByName(String name);

    public User findByNameLike(String name);

    public User findByNameLikeAndAge(String name, int age);

    public List findByIdBetween(int idMin, int idMax);
}



    @org.junit.Test
    public void testName(){
        User user1 = userDao.findByName("tom");
        System.out.println(user1);

        User user2 = userDao.findByNameLike("t%");
        System.out.println(user2);

        User user3 = userDao.findByNameLikeAndAge("tom",18);
        System.out.println(user3);

        List users = userDao.findByIdBetween(1, 3);
        users.forEach(new Consumer() {
            @Override
            public void accept(User user) {
                System.out.println(user);
            }
        });
    }

Hibernate: select user0_.id as id1_0_, user0_.address as address2_0_, user0_.age as age3_0_, user0_.name as name4_0_, user0_.phone as phone5_0_, user0_.sex as sex6_0_ from user user0_ where user0_.name=?
User{id=3, name='tom', age=18, sex=1, address='null', phone='null'}
Hibernate: select user0_.id as id1_0_, user0_.address as address2_0_, user0_.age as age3_0_, user0_.name as name4_0_, user0_.phone as phone5_0_, user0_.sex as sex6_0_ from user user0_ where user0_.name like ? escape ?
User{id=3, name='tom', age=18, sex=1, address='null', phone='null'}
Hibernate: select user0_.id as id1_0_, user0_.address as address2_0_, user0_.age as age3_0_, user0_.name as name4_0_, user0_.phone as phone5_0_, user0_.sex as sex6_0_ from user user0_ where (user0_.name like ? escape ?) and user0_.age=?
User{id=3, name='tom', age=18, sex=1, address='null', phone='null'}
Hibernate: select user0_.id as id1_0_, user0_.address as address2_0_, user0_.age as age3_0_, user0_.name as name4_0_, user0_.phone as phone5_0_, user0_.sex as sex6_0_ from user user0_ where user0_.id between ? and ?
User{id=2, name='lili2', age=18, sex=1, address='null', phone='null'}
User{id=3, name='tom', age=18, sex=1, address='null', phone='null'}

 

标准查询(Specification)

我们上面提到过,springdata jpa的dao层一般继承2个接口JpaRepository和JpaSpecificationExecutor。JpaRepository封装了crud、统计、排序、分页的常见操作,而JpaSpecificationExecutor基于JPA的criteria查询封装了另一种查询方式,我们之前一直在使用JpaRepository中的方法,下面来看下JpaSpecificationExecutor接口,它里面只提供了5个方法:

public interface JpaSpecificationExecutor {
    //查询一个
    Optional findOne(@Nullable Specification spec);
    //查询全部
    List findAll(@Nullable Specification spec);
    //查询全部  提供分页功能
    Page findAll(@Nullable Specification spec, Pageable pageable);
    //查询全部,提供排序功能
    List findAll(@Nullable Specification spec, Sort sort);
    //统计
    long count(@Nullable Specification spec);
}

可以看到,这5个方法有个共同点,接收一个Specification参数。

Specification

Specification是对JPA规范中Root、CriteriaQuery、CriteriaBuilder的一层封装,用于构建过滤条件。实例化Specification需要实现它的toPerdicate方法

//参数含义在我的另一文JPA规范中有介绍,简单说来Root用于获得查询属性,CriteriaBuilder用于构建过滤条件,CriteriaQuery用于指定最终查询语句,这里一般不会使用,默认为where语句。
Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder);
 

注意这里创建出来的是where查询语句。

来个简单示例,查询表中年龄大于等于18的所有河南人:

    @Test
    public void test(){
        Specification specification = new Specification() {
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder criteriaBuilder) {
                //分别构造各个单属性的过滤条件
                Predicate namePredicate = criteriaBuilder.like(root.get("address"), "河南%");
                Predicate agePredicate = criteriaBuilder.ge(root.get("age"), 18);//大于等于

                //组合成最终的过滤条件
                Predicate predicate = criteriaBuilder.and(namePredicate, agePredicate);
                return predicate;
            }
        };
        
        //查询
        List users = userDao.findAll(specification);
        users.forEach(new Consumer() {
            @Override
            public void accept(User user) {
                System.out.println(user);
            }
        });
    }
 

如果要添加排序和分页,可以使用Sort和Pageable。

  • Sort:排序

Sort sort = new Sort(Sort.Direction.DESC,"id");//排序属性可以设置多个
List users = userDao.findAll(specification,sort);
 

  • Pageable:分页,是一个接口,可以通过PageRequest构建实例。

Sort sort = new Sort(Sort.Direction.DESC,"id");
//Pageable pageable = PageRequest.of(0,10);//pageIndex,pageSize
Pageable pageable = PageRequest.of(0,10,sort);
Page users = userDao.findAll(specification, pageable);
users.forEach(new Consumer() {
   @Override
   public void accept(User user) {
      System.out.println(user);
   }
});
 

 

spring boot中的springdata jpa配置

application.yaml

spring:
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/study?serverTimezone=GMT
    username: root
    password: crystal1024
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update

Demo源码地址

https://github.com/lunxinfeng/jpa/tree/master/springdatajpa

 


 

你可能感兴趣的:(框架)