Spring Data MongoDB:Repository

前言:

使用Spring Data可以帮助我们快速构建项目,非常方便,Spring Data在数据持久层已经写好了常用功能,我们只需要定义一个接口去继承Spring Data提供的接口,就可以实现对数据库的操作,也可以自定义接口方法,甚至这些自定义方法都不需要我们手动去实现,Reposity会自动完成实现。

Reposity是Spring Data的核心接口,泛型中的T表示实体类型,ID表示实体类的标识符id。

/*
 * Copyright 20011-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository;

import org.springframework.stereotype.Indexed;

/**
 * Central repository marker interface. Captures the domain type to manage as well as the domain type's id type. General
 * purpose is to hold type information as well as being able to discover interfaces that extend this one during
 * classpath scanning for easy Spring bean creation.
 * <p>
 * Domain repositories extending this interface can selectively expose CRUD methods by simply declaring methods of the
 * same signature as those declared in {@link CrudRepository}.
 * 
 * @see CrudRepository
 * @param <T> the domain type the repository manages
 * @param <ID> the type of the id of the entity the repository manages
 * @author Oliver Gierke
 */
@Indexed
public interface Repository<T, ID> {

}

Reposity作为父接口,我们在开发中不会直接使用,最常用的是它的一个子接口CrudReposity。

/*
 * Copyright 2008-2017 the original author or authors.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package org.springframework.data.repository;

import java.util.Optional;

/**
 * Interface for generic CRUD operations on a repository for a specific type.
 * 
 * @author Oliver Gierke
 * @author Eberhard Wolff
 */
@NoRepositoryBean
public interface CrudRepository<T, ID> extends Repository<T, ID> {

    /**
     * Saves a given entity. Use the returned instance for further operations as the save operation might have changed the
     * entity instance completely.
     * 
     * @param entity must not be {@literal null}.
     * @return the saved entity will never be {@literal null}.
     */
    <S extends T> S save(S entity);

    /**
     * Saves all given entities.
     * 
     * @param entities must not be {@literal null}.
     * @return the saved entities will never be {@literal null}.
     * @throws IllegalArgumentException in case the given entity is {@literal null}.
     */
    <S extends T> Iterable<S> saveAll(Iterable<S> entities);

    /**
     * Retrieves an entity by its id.
     * 
     * @param id must not be {@literal null}.
     * @return the entity with the given id or {@literal Optional#empty()} if none found
     * @throws IllegalArgumentException if {@code id} is {@literal null}.
     */
    Optional<T> findById(ID id);

    /**
     * Returns whether an entity with the given id exists.
     * 
     * @param id must not be {@literal null}.
     * @return {@literal true} if an entity with the given id exists, {@literal false} otherwise.
     * @throws IllegalArgumentException if {@code id} is {@literal null}.
     */
    boolean existsById(ID id);

    /**
     * Returns all instances of the type.
     * 
     * @return all entities
     */
    Iterable<T> findAll();

    /**
     * Returns all instances of the type with the given IDs.
     * 
     * @param ids
     * @return
     */
    Iterable<T> findAllById(Iterable<ID> ids);

    /**
     * Returns the number of entities available.
     * 
     * @return the number of entities
     */
    long count();

    /**
     * Deletes the entity with the given id.
     * 
     * @param id must not be {@literal null}.
     * @throws IllegalArgumentException in case the given {@code id} is {@literal null}
     */
    void deleteById(ID id);

    /**
     * Deletes a given entity.
     * 
     * @param entity
     * @throws IllegalArgumentException in case the given entity is {@literal null}.
     */
    void delete(T entity);

    /**
     * Deletes the given entities.
     * 
     * @param entities
     * @throws IllegalArgumentException in case the given {@link Iterable} is {@literal null}.
     */
    void deleteAll(Iterable<? extends T> entities);

    /**
     * Deletes all entities managed by the repository.
     */
    void deleteAll();
}

该接口中定义了操作数据库的常用方法,我们只需要自定义接口继承CurdReposity就可以使用了,不需要自己完成接口的实现。

下面通过代码来教会大家如何使用Reposity快速开发程序。

1.搭建Spring Data MongoDB环境。

2.创建Student实体类。

package com.southwind.entity;

import java.util.Date;

import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;

@Document(collection="student_info")
public class Student {
    @Id
    private String id;
    @Field
    private String name;
    @Field
    private int age;
    @Field(value="a_time")
    private Date addTime;
    public String getId() {
        return id;
    }
    public void setId(String 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;
    }
    public Date getAddTime() {
        return addTime;
    }
    public void setAddTime(Date addTime) {
        this.addTime = addTime;
    }

}

3.自定义StudentReposity接口,继承CrudReposity,添加@Reposity注解。

package com.southwind.repository;

import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.southwind.entity.Student;

@Repository
public interface StudentReposity extends CrudRepository<Student, String>{

}

4.spring.xml中进行配置自动扫描,ioC容器管理Reposity接口。

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xmlns:mongo="http://www.springframework.org/schema/data/mongo"
          xsi:schemaLocation=
          "http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context.xsd
          http://www.springframework.org/schema/data/mongo http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans.xsd">

    <!-- Spring连接MongoDB客户端配置 -->
    <mongo:mongo-client host="127.0.0.1" port="12345" id="mongo"/>

    <!-- 配置MongoDB目标数据库 -->
    <mongo:db-factory dbname="testdb" mongo-ref="mongo" />

    <!-- 配置MongoTemplate -->
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
      <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>
    </bean>

    <!-- 扫描Reposity接口 -->
    <mongo:repositories base-package="com.southwind.repository"></mongo:repositories>

</beans>

5.从ioC容器中获取StudentRepostiy实例,调用其方法完成对数据库的操作。

查询总记录数

long count = studentReposity.count();
System.out.println(count);

根据id查询数据

Student student = studentReposity.findById("5b62c6f55a41f60d93ffe6c2").get();
System.out.println(student);

查询全部数据

Iterator<Student> iterator = studentReposity.findAll().iterator();
while(iterator.hasNext()) {
    Student Student = iterator.next();
    System.out.println(Student);
}

查询id集合对应的数据

List<String> ids = new ArrayList<String>();
ids.add("5b62c6f55a41f60d93ffe6c2");
ids.add("5b62c6f55a41f60d93ffe6c3");
ids.add("5b62c6f55a41f60d93ffe6c4");
Iterator<Student> iterator = studentReposity.findAllById(ids).iterator();
while(iterator.hasNext()) {
    Student Student = iterator.next();
    System.out.println(Student);
}

根据id查询数据是否存在

boolean flag = studentReposity.existsById("5b62c6f55a41f60d93ffe6c2");
System.out.println(flag);

根据id删除数据

studentReposity.deleteById("5b62c6f55a41f60d93ffe6c2");

记录张三1删除成功。

删除一组数据

Student Student = studentReposity.findById("5b62c6f55a41f60d93ffe6c1").get();
Student Student2 = studentReposity.findById("5b62c6f55a41f60d93ffe6c3").get();
Student Student3 = studentReposity.findById("5b62c6f55a41f60d93ffe6c4").get();
List<Student> list = new ArrayList<Student>();
list.add(Student);
list.add(Student2);
list.add(Student3);
studentReposity.deleteAll(list);

删除之前:

删除之后:

删除全部数据

studentReposity.deleteAll();

使用CrudReposity接口定义好的方法操作数据库非常方便,同时我们也可以根据需求自定义方法,并且不需要实现,Reposity会自动实现这些自定义方法,但是使用时需要注意命名规范。

根据name查询数据

自定义方法。

package com.southwind.repository;

import java.util.List;

import org.springframework.data.domain.Sort;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.southwind.entity.Student;

@Repository
public interface StudentReposity extends CrudRepository<Student, String>{
    public List<Student> findByName(String name);
}

直接调用。

List<Student> list = studentReposity.findByName("张三1");
for (Student Student : list) {
    System.out.println(Student);
}

数据库记录如下。

查询结果。

根据name和age查询数据

自定义方法。

package com.southwind.repository;

import java.util.List;

import org.springframework.data.domain.Sort;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.southwind.entity.Student;

@Repository
public interface StudentReposity extends CrudRepository<Student, String>{
    public List<Student> findByNameAndAge(String name,int age);
}

直接调用。

List<Student> list = studentReposity.findByNameAndAge("张三1",16);
for (Student Student : list) {
    System.out.println(Student);
}

数据库记录如下。

查询结果。

查询全部数据并排序

自定义方法。

package com.southwind.repository;

import java.util.List;

import org.springframework.data.domain.Sort;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.southwind.entity.Student;

@Repository
public interface StudentReposity extends CrudRepository<Student, String>{
    public List<Student> findAll(Sort sort);
}

直接调用,Direction.DESC表示降序排列。

List<Student> list = studentReposity.findAll(
              Sort.by(Direction.DESC,"age"));
for (Student Student : list) {
    System.out.println(Student);
}

查询结果。

若要升序排列,将Direction.DESC替换为Direction.ASC即可。

附上StudentReposity的完整代码。

StudentReposity

package com.southwind.repository;

import java.util.List;

import org.springframework.data.domain.Sort;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Repository;

import com.southwind.entity.Student;

@Repository
public interface StudentReposity extends CrudRepository<Student, String>{
    public List<Student> findByName(String name);
    public List<Student> findByNameAndAge(String name,int age);
    public List<Student> findAll(Sort sort);
}

StudentReposityTest

package com.southwind.test;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;

import com.southwind.entity.Student;
import com.southwind.repository.StudentReposity;

public class StudentReposityTest {
    private static StudentReposity studentReposity;
    static {
        studentReposity = (StudentReposity) new ClassPathXmlApplicationContext("classpath:spring.xml").getBean("studentReposity");
    }

    public static void main(String[] args) {
        findBySort();
    }

    public static void getCount() {
        long count = studentReposity.count();
        System.out.println(count);
    }

    public static void findById() {
        Student student = studentReposity.findById("5b62c6f55a41f60d93ffe6c2").get();
        System.out.println(student);
    }

    public static void findAll() {
        Iterator<Student> iterator = studentReposity.findAll().iterator();
        while(iterator.hasNext()) {
            Student Student = iterator.next();
            System.out.println(Student);
        }
    }

    public static void findAllById() {
        List<String> ids = new ArrayList<String>();
        ids.add("5b62c6f55a41f60d93ffe6c2");
        ids.add("5b62c6f55a41f60d93ffe6c3");
        ids.add("5b62c6f55a41f60d93ffe6c4");
        Iterator<Student> iterator = studentReposity.findAllById(ids).iterator();
        while(iterator.hasNext()) {
            Student Student = iterator.next();
            System.out.println(Student);
        }
    }

    public static void existsById() {
        boolean flag = studentReposity.existsById("5b62c6f55a41f60d93ffe6c2");
        System.out.println(flag);
    }

    public static void delete() {
        Student Student = studentReposity.findById("5b5193c5f872cb041d1caa4d").get();
        studentReposity.delete(Student);
    }

    public static void deleteById() {
        studentReposity.deleteById("5b62c6f55a41f60d93ffe6c2");
    }

    public static void deleteAllByIterable() {
        Student Student = studentReposity.findById("5b62c6f55a41f60d93ffe6c1").get();
        Student Student2 = studentReposity.findById("5b62c6f55a41f60d93ffe6c3").get();
        Student Student3 = studentReposity.findById("5b62c6f55a41f60d93ffe6c4").get();
        List<Student> list = new ArrayList<Student>();
        list.add(Student);
        list.add(Student2);
        list.add(Student3);
        studentReposity.deleteAll(list);
    }

    public static void deletAll() {
        studentReposity.deleteAll();
    }

    public static void findByName() {
        List<Student> list = studentReposity.findByName("张三1");
        for (Student Student : list) {
            System.out.println(Student);
        }
    }

    public static void findByNameAndAge() {
        List<Student> list = studentReposity.findByNameAndAge("张三1",16);
        for (Student Student : list) {
            System.out.println(Student);
        }
    }

    public static void findBySort() {
        List<Student> list = studentReposity.findAll(Sort.by(Direction.ASC,"age"));
        for (Student Student : list) {
            System.out.println(Student);
        }
    }
}

原文发布于微信公众号 - Java大联盟(javaunion)

原文发表时间:2018-08-06

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏写代码的海盗

scala与java之间的那些事

  scala与java之间的关系,我认为可以用一句话来开头:scala来源于java,但又高于java。   scala的设计者Martin Odersky就...

3675
来自专栏大内老A

WCF技术剖析之十三:序列化过程中的已知类型(Known Type)

DataContractSerializer承载着所有数据契约对象的序列化和反序列化操作。在上面一篇文章(《数据契约(Data Contract)和数据契约序列...

27410
来自专栏林德熙的博客

C# 很少人知道的科技

本文来告诉大家在C#很少有人会发现的科技。即使是工作了好多年的老司机也不一定会知道,如果觉得我在骗你,那么请看看下面。

1272
来自专栏Java Web

Java 面试知识点解析(四)——版本特性篇(2)

在遨游了一番 Java Web 的世界之后,发现了自己的一些缺失,所以就着一篇深度好文:知名互联网公司校招 Java 开发岗面试知识点解析 ,来好好的对 Jav...

3858
来自专栏分布式系统和大数据处理

基于业务对象(列表)的排序

在上一篇文章 基于业务对象的筛选 中,我们讨论了如何实现Predicate<T>(T object)委托,自定义DateFilter 类来对业务对象进行筛选。与...

1042
来自专栏数据结构与算法

POJ 3694 Network(Tarjan求割边+LCA)

Description A network administrator manages a large network. The network consist...

3936
来自专栏Code_iOS

数据结构:栈与队列

工程代码 Github: Data_Structures_C_Implemention -- Stack & Queue

1273
来自专栏蘑菇先生的技术笔记

探索c#之不可变数据类型

2064
来自专栏一个会写诗的程序员的博客

从 JavaScript 到 TypeScript

TypeScript 并不是一个完全新的语言, 它是 JavaScript 的超集,为 JavaScript 的生态增加了类型机制,并最终将代码编译为纯粹的 J...

1243
来自专栏jessetalks

背后的故事之 - 快乐的Lambda表达式(二)

快乐的Lambda表达式   上一篇 背后的故事之 - 快乐的Lambda表达式(一)我们由浅入深的分析了一下Lambda表达式。知道了它和委托以及普通方法的区...

2764

扫码关注云+社区

领取腾讯云代金券