JPA的使用--接口的介绍

Repository<T, ID>接口

Repository<T, ID>接口的作用:自定义JPQL语句

JPQL:通过 Hibernate 的HQL演变过来的。他和 HQL 语法及其相似。
HQL:Hibernate Query Language(Hibernate查询语言)
SQL:Structure Query Language(结构化查询语言)

区别:
SQL操作的是数据库中的表和字段
HQL:操作是实体对象和属性

我们编写的JPQL最终还是会转换成SQL语句进行执行的

编写新的接口继承Repository<T, ID>接口,T是操作的实体类,ID是实体对应数据库主键的java类型

/**
 * 使用@Query注解,自定义JPQL语句
 * JPQL语句中,使用的不是表名,而是实体类名,不是列名,而是属性名,
 * 例如SQL语句:select * from user  JPQL语句是:select User from User
 * 如果是条件查询,之前语句中的占位符?可以使用(:xxx)进行表示
 * 此时xxx会根据方法中同名的形参自动绑定值
 */
public interface UsersRepositoryByQuery extends Repository<User, Integer> {
    //如果是查询所有列,可以省略select ....,从from开始写
    @Query("from User where name=:name")
    List<User> selectByName(String name); //select * from user where name=?

    @Query("select u from User u where name=:name and age=:age")
    List<User> selectByNameAndAge(String name, Integer age); //select * from user where name=? and age=?

    @Query("from User where name=:name and age=:age")
    List<User> selectByNameLike(String name);//select * from user  where name like ?

    //除了使用JPQL语句,也是可以使用sql原生语句,在注解中设置参数nativeQuery = true,不推荐!
    @Query(value = "select * from user where name=:name",nativeQuery = true)
    List<User> selectByNameSQl(String name);//select * from user where name=?
}
CrudRepository接口

编写新的接口继承CrudRepository接口<T, ID> T是操作的实体类,ID是实体对应数据库主键的java类型,
CrudRepository就继承了Repository接口,内置类增删改的方法
简单的使用演示:

新建接口继承CrudRepository接口:

/**
 * 继承CrudRepository接口的使用
 */
public interface UsersRepositoryExCrud extends CrudRepository<User, Integer> {
}

测试代码:

    @Autowired
    private UsersRepositoryExCrud crud;

    @Test
    void testCrud(){
        Optional<User> optional = crud.findById(3);
        User user = optional.get();
        System.out.println(user);
    }

运行效果


运行效果

PagingAndSortingRepository接口

PagingAndSortingRepository接口继承了CrudRepository接口
PagingAndSortingRepository接口主要增加了分页和排序方法

简单的使用演示:

新建接口,继承PagingAndSortingRepository:

public interface UserRepositoryPage extends PagingAndSortingRepository<User,Integer> {
}

测试代码:

 @Autowired
    private UserRepositoryPage userRepositoryPage;
    /**
     * 分页
     */
    @Test
    void testPage(){
        //第一个参数是页码数,0表示第一页;第二参数是分页单位;
        Pageable Pageable = PageRequest.of(0, 2);
        Page<User> page = userRepositoryPage.findAll(Pageable);
        System.out.println("总数据量"+page.getTotalElements());
        System.out.println("总页数"+page.getTotalPages());
        List<User> content = page.getContent();
        for (User user : content) {
            System.out.println(user);
        }
    }
    /**
     * 排序
     */
    @Test
    void testSort(){
        //根据id排序
        Sort sort = Sort.by(Sort.Order.desc("id"));
        Iterable<User> all = userRepositoryPage.findAll(sort);
        for (User user : all) {
            System.out.println(user);
        }
    }

测试结果:

分页查询结果
Hibernate: select user0_.id as id1_7_, user0_.address as address2_7_, user0_.age as age3_7_, user0_.name as name4_7_, user0_.sex as sex5_7_ from user user0_ limit ?
Hibernate: select count(user0_.id) as col_0_0_ from user user0_
总数据量7
总页数4
User{id=3, name='赵六', sex='男', age=33}
User{id=4, name='李四', sex='男', age=22}
排序查询结果
Hibernate: select user0_.id as id1_7_, user0_.address as address2_7_, user0_.age as age3_7_, user0_.name as name4_7_, user0_.sex as sex5_7_ from user user0_ order by user0_.id desc
User{id=10, name='张无忌', sex='男', age=24}
User{id=9, name='张三丰', sex='男', age=108}
User{id=8, name='张三三', sex='女', age=21}
User{id=7, name='张三', sex='男', age=22}
User{id=5, name='王五', sex='男', age=33}
User{id=4, name='李四', sex='男', age=22}
User{id=3, name='赵六', sex='男', age=33}

JpaRepository接口

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

简单的使用演示:

创建接口,继承JpaRepository接口

public interface UserRepositoryExJPA extends JpaRepository<User,Integer> {
}

测试代码:

    @Autowired
    private UserRepositoryExJPA userRepositoryExJPA;

    @Test
    public void testJpaRepositorySort() {
        //Order 定义排序规则
        Sort.Order order = Sort.Order.asc("age");
        //Sort对象封装了排序规则
        Sort sort = Sort.by(order);
        List<User> list = userRepositoryExJPA.findAll(sort);
        for (User user : list) {
            System.out.println(user);
        }
    }

测试结果
测试结果

JpaSpecificationExecutor 接口

该接口主要提供了多条件查询的支持,并且可以在查询中添加分页与排序
注意:
JpaSpecificationExecutor接口与以上接口没有关系,完全独立。
不能单独使用,需要配合着JPA 中的其他接口一起使用。

简单使用演示:
创建接口,继承JpaSpecificationExecutor接口和其他JPA接口

public interface UserRepositoryExJPA extends JpaRepository<User,Integer>,JpaSpecificationExecutor<User> {
}

测试代码:

@Autowired
    private UserRepositoryExJPA userRepositoryExJPA;

    /**
     * 自定义规则,可以多条件查询
     */
    @Test
    void testExJPA2() {
        Specification<User> specification = new Specification<User>() {
            @Override
            public Predicate toPredicate(Root<User> root, CriteriaQuery<?> criteriaQuery, CriteriaBuilder criteriaBuilder) {
                //模糊查询
                Predicate predicate = criteriaBuilder.like(root.get("name"), "张%");
                //模糊查询+性别筛选+年龄筛选
                Predicate predicate2 = criteriaBuilder.and(criteriaBuilder.like(root.get("name"), "张%"),
                        criteriaBuilder.equal(root.get("sex"), "男"), criteriaBuilder.gt(root.get("age"), 24));
                return predicate2;
            }
        };
        //进行排序年龄进行倒序排列
        Sort sort = Sort.by(Sort.Order.desc("age"));
        //分页+追加排序
        Pageable pageable = PageRequest.of(0, 2, sort);
        Page<User> page = userRepositoryExJPA.findAll(specification, pageable);
        System.out.println("根据条件查询到" + page.getTotalElements() + "条数据");
        System.out.println("根据条件查询到" + page.getTotalPages() + "页数据");
        System.out.println("当页数据");
        for (User user : page) {
            System.out.println(user);
        }
    }

测试结果
测试结果
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 220,492评论 6 513
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 94,048评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,927评论 0 358
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,293评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,309评论 6 397
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 52,024评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,638评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,546评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 46,073评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,188评论 3 340
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,321评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,998评论 5 347
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,678评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,186评论 0 23
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,303评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,663评论 3 375
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,330评论 2 358

推荐阅读更多精彩内容