SpringData JPA

 

 

SpringDataJPA 是springdata 项目下的一个模块。提供了一套基于JPA 标准操作数据库的简化方案。底层默认的是依赖 HibernateJPA 来实现的。
SpringDataJPA 的技术特点:我们只需要定义接口并集成 Spring DataJPA 中所提供的接 口就可以了。不需要编写接口实现类

spring-data-jpa接口继承关系

Repository 接口
Repository 接口是 SpringDataJPA 中为我我们提供的所有接口中的顶层接口

Repository 提供了两种查询方式的支持

1).基于方法名称命名规则查询

2).基于@Query 注解查询

1.方法名称命名规则查询

     规则:findBy(关键字)+属性名称(属性名称的首字母大写)+查询条件(首字母大写)

关键字方法命名sql where字句
AndfindByNameAndPwdwhere name= ? and pwd =?
OrfindByNameOrSexwhere name= ? or sex=?
Is,EqualfindById,findByIdEqualswhere id= ?
BetweenfindByIdBetweenwhere id between ? and ?
LessThan findByIdLessThanwhere id < ?
LessThanEqualfindByIdLessThanEqualwhere id <=?
GreaterThan findByIdGreaterThanwhere id > ?
GreaterThanEqual

findByIdGreaterThanEqual

where id > = ?
After findByIdAfterwhere id > ?
Before findByIdBeforewhere id < ?
IsNullfindByNameIsNullwhere name is null
isNotNull,NotNullfindByNameNotNull where name is not null 
Like findByNameLike where name like ?
NotLike findByNameNotLikewhere name not like ?
StartingWithfindByNameStartingWithwhere name like '?%'
EndingWith findByNameEndingWithwhere name like '%?'
Containing findByNameContainingwhere name like '%?%'
OrderBy findByIdOrderByXDesc

where id=? order by x desc

Not findByNameNotwhere name <> ?
InfindByIdIn(Collection <?> c)where id in (?)
NotInfindByIdNotIn(Collect ion<?> c)where id not in (?)
True findByAaaTue where aaa = true
False findByAaaFalsewhere aaa = false
IgnoreCase findByNameIgnoreCasewhere UPPER(name)=UPPER(?)

 

我们在dao接口中可以这样玩 (注意 dao继承 extends JpaRepository<Book,Integer>  book是具体的查询类型)

JpaRepository 接口是我们开发时使用的最多的接口。其特点是可以帮助我们将其他接口 的方法的返回值做适配处理。可以使得我们在开发时更方便的使用这些方法

Book实体类

/**
 * 类与表建立映射关系
 * book 实体
 * @author xz
 */
@Entity
@Table(name="books") //对应的哪个表
public class Book implements Serializable {
    @Id //指定为id
    @GeneratedValue(strategy=GenerationType.IDENTITY) //主键策略
    @Column(name="bid") //字段名
    private int bid;

    @Column(name="name")
    private String name;

    @Column(name="credate")
    private Date credate;

    @Column(name="note")
    private  String note;

    public Book() {
    }

    public Book(int bid, String name, Date credate, String note) {
        this.bid = bid;
        this.name = name;
        this.credate = credate;
        this.note = note;
    }

    public int getBid() {
        return bid;
    }

    public void setBid(int bid) {
        this.bid = bid;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getCredate() {
        return credate;
    }

    public void setCredate(Date credate) {
        this.credate = credate;
    }

    public String getNote() {
        return note;
    }

    public void setNote(String note) {
        this.note = note;
    }

    @Override
    public String toString() {
        return "Book{" +
                "bid=" + bid +
                ", name='" + name + '\'' +
                ", credate=" + credate +
                ", note='" + note + '\'' +
                '}';
    }
}

dao我们这样写 

public interface BookDao1 extends JpaRepository<Book,Integer> {

    //根据id查询   where bid >= bid
    List<Book> findByBidGreaterThanEqual(Integer bid);

    //根据id查询   where bid > bid
    List<Book> findByBidLessThanEqual(Integer bid);

    //根据名字模糊查询  where name like "%name"
    List<Book> findByNoteStartingWith(String name);

    //根据名字模糊查询  where name like "name%"
    List<Book> findByNoteEndingWith(String name);
}

2.基于@Query 注解的查询

通过 JPQL 语句查询
JPQL:通过 Hibernate 的 HQL 演变过来的。他和 HQL 语法及其相似

在dao中可以这样实现

@Query(value = "from Book where name like ?")
Book queryBookByNameUseJPQL(String name);

@Query(value="select * from books where name like ?",nativeQuery = true)
List<Book> queryBooksByNameUseJPQL(String name);

需要注意的是,nativeQuery默认的是 false.表示不开启 sql 查询。是否对 value 中的语句做转义

还能通过 @Query 做update操作   使用@Modifying表示 当前语句是一个更新语句 

@Query(value="update Book set name =? where bid = ?")
@Modifying
void updateBook(String name,Integer bid);

CrudRepository 接口

/**
* 继承CrudRepository接口
*/
public interface BookDao extends CrudRepository<Book,Integer> {

}

测试类

@RunWith(SpringRunner.class)
@SpringBootTest
public class SsmbootApplicationTests {
    @Resource
    private BookDao bookDao;

    /**
     * 插入数据
     */
    @Test
    public void test1() {
        Book book = new Book();
        book.setName("java 入门到精通");
        book.setCredate(new Date());
        book.setNote("java指导大全");
        bookDao.save(book);
    }

    /**
     * 批量添加
     */
    @Test
    public void test2(){
        Book book = new Book();
        book.setName("oracle 入门到精通");
        book.setCredate(new Date());
        book.setNote("oracle 指导大全");

        Book book2 = new Book();
        book2.setName("spring 入门到精通");
        book2.setCredate(new Date());
        book2.setNote("spring 指导大全");

        List<Book> list = new ArrayList<>();
        list.add(book);
        list.add(book2);
        bookDao.save(list);
    }

    /**
     * 根据id查找
     */
    @Test
    public void test3(){
        Book booke = bookDao.findOne(3);
        System.out.println(booke);
    }

    /**
     * 查询全部
     */
    @Test
    public void test4(){
        System.out.println(bookDao.findAll());
    }

    /**
     * 删除数据
     */
    @Test
    public void test5(){
        bookDao.delete(9);
    }

    /**
     * 更改数据
     */
    @Test
    public void test6(){
        Book book = bookDao.findOne(10);
        book.setCredate(new Date());
        //bookDao.save(book);
    }
}

PagingAndSortingRepository 接口
1.分页处理

dao接口

/**
 * 支持分页 和  排序操作
 * Spring Data JPA操作
 */
public interface BookDao extends PagingAndSortingRepository<Book,Integer> {

}

测试类

    @Test
    public void test1(){
        int page = 2; //page:当前页的索引。注意索引都是从 0 开始的。
        int size = 3;// size:每页显示 3 条数据
        Pageable pageable = new PageRequest(page,size);
        Page<Book> pages = bookDao.findAll(pageable);
        System.out.println( "总条数:"+pages.getTotalElements());//总条数
        System.out.println("总页数:"+pages.getTotalPages());//总页数
        List<Book> list =  pages.getContent();
        for (Book b: list) {
            System.out.println(b);
        }
    }

2.排序处理

测试类

单列排序

    /**
     * 单列排序
     */
    @Test
    public void test2(){
        // Sort:该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
        // direction:排序规则   asc 升序  desc 降序
        // properties:指定做排序的属性
        Sort sort = new Sort(Sort.Direction.DESC,"bid");
        List<Book> list=(List<Book>)bookDao.findAll(sort);
        for (Book book:list) {
            System.out.println(book);
        }
    }

多列排序

    /**
     * 多列排序
     */
    @Test
    public void test3(){
        // Sort:该对象封装了排序规则以及指定的排序字段(对象的属性来表示)
        // direction:排序规则   asc 升序  desc 降序
        // properties:指定做排序的属性
        Sort.Order order = new Sort.Order(Sort.Direction.DESC,"name");
        Sort.Order order1 = new Sort.Order(Sort.Direction.DESC,"bid");
        Sort sort = new Sort(order,order1);
        List<Book> list=(List<Book>)bookDao.findAll(sort);
        for (Book book:list) {
            System.out.println(book);
        }
    }

JpaSpecificationExecutor 接口
完成多条件查询,并且支持分页与排序

需要注意的是这个接口不能单独使用,需要配合着 jpa 中的 其他接口一起使用

dao类

/**
 * 完成多条件查询,并且支持分页与排序
 * Spring Data JPA操作
 */
public interface BookDao extends JpaRepository<Book,Integer>, JpaSpecificationExecutor<Book> {

}

测试代码

单条件查询

     /**
     * 根据书名模糊查询
     */
    @Test
    public void test1(){
        Specification<Book> spec = new Specification<Book>() {

            /**
             * @param Root<Users> root:根对象。封装了查询条件的对象
             * @param CriteriaQuery<?> query:定义了一个基本的查询.一般不使用
             * @param CriteriaBuilder cb:创建一个查询条件
             * @return Predicate:定义了查询条件 * @param Root<Book> root:根对象。封装了查询条件的对象
             * */
            @Override
            public Predicate toPredicate(Root<Book> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                Predicate pre = cb.like(root.get("name"),"%入门到精通%");
                return pre;
            }
        };

        List<Book> list = bookDao.findAll(spec);
        for (Book book:list) {
            System.out.println(book);
        }
    }

 

多条件查询 

    /**
     * 使用编号或书名查询
     */
    @Test
    public void test2(){
        Specification spec = new Specification() {
            /**
             * @param Root<Users> root:根对象。封装了查询条件的对象
             * @param CriteriaQuery<?> query:定义了一个基本的查询.一般不使用
             * @param CriteriaBuilder cb:创建一个查询条件
             * @return Predicate:定义了查询条件 * @param Root<Book> root:根对象。封装了查询条件的对象
             * */
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery query, CriteriaBuilder cb) {
                return cb.or(cb.like(root.get("name"),"%入门到精通%"),cb.equal(root.get("bid"),"8"));
            }
        };
        List<Book> list = bookDao.findAll(spec);
        for (Book book:list) {
            System.out.println(book);
        }
    }

模糊查询,分页,并排序

     /**
     * 根据书名模糊查询,并且分页 按照 bid 进行排序
     */
    @Test
    public void test3() {
        //排序定义
        Sort sort = new Sort(Sort.Direction.DESC, "bid");

        //分页定义  并且给定排序规则
        Pageable pageable = new PageRequest(2, 2, sort);

        //查询条件
        Specification spec = new Specification() {
            /**
             * @param Root<Users> root:根对象。封装了查询条件的对象
             * @param CriteriaQuery<?> query:定义了一个基本的查询.一般不使用
             * @param CriteriaBuilder cb:创建一个查询条件
             * @return Predicate:定义了查询条件 * @param Root<Book> root:根对象。封装了查询条件的对象
             * */
            @Override
            public Predicate toPredicate(Root root, CriteriaQuery criteriaQuery, CriteriaBuilder criteriaBuilder) {
                return criteriaBuilder.like(root.get("note"), "%呀%");
            }
        };

        //获取查询结果封装到page
        Page<Book> page = bookDao.findAll(spec, pageable);
        System.out.println("总条数:" + page.getTotalElements());
        System.out.println("总页数:" + page.getTotalPages());
        List<Book> list = page.getContent();
        for (Book book : list) {
            System.out.println(book);
        }


    }

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值