SpringData MongoDB etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster
SpringData MongoDB etiketine sahip kayıtlar gösteriliyor. Tüm kayıtları göster

10 Mayıs 2023 Çarşamba

SpringData MongoDB Reactive ReactiveMongoRepository Arayüzü

Giriş
Bazı metodlar şöyle
Flux<T> findAll()
Flux<T> save()
Mono<T> findById(ID id) 
Mono<Void> deleteById (ID id)
Kullanım
Örnek
Şöyle yaparız
@RestController
@RequestMapping("/employees")
public class EmployeeController {
  private final EmployeeRepository employeeRepository;
  public EmployeeController(EmployeeRepository employeeRepository) {
    this.employeeRepository = employeeRepository;
  }
  @GetMapping
  public Flux<Employee> getAllEmployees() {
    return employeeRepository.findAll();
  }
  @PostMapping
  public Mono<Employee> createEmployee(@RequestBody Employee employee) {
    return employeeRepository.save(employee);
  }
  @GetMapping("/{id}")
  public Mono<Employee> getEmployeeById(@PathVariable String id) {
    return employeeRepository.findById(id);
  }
  @PutMapping("/{id}")
  public Mono<Employee> updateEmployee(@PathVariable String id,
                                             @RequestBody Employee employee) {
      return employeeRepository.findById(id)
        .flatMap(existingEmployee -> {
          existingEmployee.setName(employee.getName());
          existingEmployee.setDepartment(employee.getDepartment());
          return employeeRepository.save(existingEmployee);
        });
    }
  @DeleteMapping("/{id}")
  public Mono<Void> deleteEmployee(@PathVariable String id) {
    return employeeRepository.deleteById(id);
  }
}
Pagination
Örnek
Şöyle yaparız
@Repository
public interface EmployeeRepository extends ReactiveMongoRepository<Employee, String> {
    Flux<Employee> findByName(String name, Pageable pageable);
}

@RestController
@RequestMapping("/employees")
public class EmployeeController {
  // existing code
  @GetMapping("/search")
  public Flux<Employee> searchEmployees(@RequestParam("name") String name,
                            @RequestParam(value = "page", defaultValue = "0") int page,
                            @RequestParam(value = "size", defaultValue = "10") int size) {
    PageRequest pageable = PageRequest.of(page, size, Sort.by("name"));
    return employeeRepository.findByName(name, pageable);
  }
}
flatMap metodu
Örnek
Şöyle yaparız. Burada update için kullanılıyor
@PutMapping("/{id}")
public Mono<Employee> updateEmployee(@PathVariable String id,
                                     @RequestBody Employee employee) {
  return employeeRepository.findById(id)
    .flatMap(existingEmployee -> {
      existingEmployee.setName(employee.getName());
      existingEmployee.setDepartment(employee.getDepartment());
      return employeeRepository.save(existingEmployee);
    });
}
Örnek
Elimizde iki tane ReactiveCrudRepository'den  kalıtan repository olsun
@Autowired
private CurrencyRepository currencyRepository;

@Autowired
private CurrencyArchiveRepository currencyArchiveRepository;
Şöyle yaparız
@Override
@Transactional
public Mono<Void> delete(final String currencyCode) {
  final CurrencyArchive currencyArchive = buildCurrencyArchive();

  return this.currencyArchiveRepository.save(currencyArchive)
      .flatMap(c -> this.currencyRepository.delete(c.getCode()))
      .then();
}
@Query İle Kullanımı
Şeklen şöyle

Açıklaması şöyle
‘?0’ indicates that the mentioned property should be equal to the zeroth parameter to the query method. Further, if there were more parameters, they could be referred to ?1, ?2, and so forth.
Örnek
Şöyle bir repository olsun
import org.springframework.data.mongodb.repository.Query;
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
import org.springframework.stereotype.Repository;
import reactor.core.publisher.Flux;

@Repository
public interface FreelancerRepository extends ReactiveMongoRepository<Freelancer, String> {

    @Query("{ 'skills': { $all: ?0 } }")
    Flux<Freelancer> findBySkillsAll(List<String> skills);

    Flux<Freelancer> findBySkillsIn(List<String> skills);

}
Şöyle yaparız
@Service
public class FreelancerService {

  @Autowired
  private FreelancerRepository repository;

  public Flux<Freelancer> findBySkillsOne(final List<String> skills){
    return this.repository.findBySkillsIn(skills);
  }

  public Flux<Freelancer> findBySkillsAll(final List<String> skills){
    return this.repository.findBySkillsAll(skills);
  }

  public Mono<Freelancer> getPerson(final String id){
    return this.repository.findById(id);
  }

  public Mono<Freelancer> savePerson(final Freelancer person){
    return this.repository.save(person);
  }

  public Mono<Freelancer> updatePerson(final Freelancer person){
    return this.repository.findById(person.getId())
      .map(p -> person)
      .flatMap(this.repository::save);
  }

  public Mono<Void> deletePerson(final String id){
    return this.repository.deleteById(id);
  }
}


26 Ocak 2021 Salı

SpringData MongoDB @Indexed Anotasyonu

Giriş
Açıklaması şöyle
Adding the proper indexes is essential to achieve better performance. Spring Data MongoDB provides the @Indexed and @CompoundIndexes annotations, which can be added on field-level or class-level within a @Document annotated object. 

6 Ocak 2021 Çarşamba

SpringData MongoDB ReactiveMongoOperations

Giriş
Şu satırı dahil ederiz
import org.springframework.data.mongodb.core.ReactiveMongoOperations;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
findById metodu
Şöyle yaparız
@Service
class ReservationService {

  private final ReactiveMongoOperations reactiveMongoOperations ;

  @Autowired
  public ReservationServiceImpl(ReactiveMongoOperations reactiveMongoOperations ) {
    this.reactiveMongoOperations = reactiveMongoOperations ;
  }

  public Mono<Reservation> getReservation(String id) {
    return reactiveMongoOperations
      .findById(id, Reservation.class);
  }

  public Mono<Reservation> createReservation(Mono<Reservation> reservation) {
    return reactiveMongoOperations
      .save(reservation);
  }

  public Mono<Reservation> updateReservation(String id, Mono<Reservation> reservation) {
    return reservation
      .flatMap(res -> reactiveMongoOperations .
        findAndModify(Query.query(Criteria.where("id").is(id)),
                      Update.update("price", res.getPrice()), Reservation.class)
                      .flatMap(result -> {
                        result.setPrice(res.getPrice());
                        return Mono.just(result);
    }));
  }

  public Mono<Boolean> deleteReservation(String id) {
    return reactiveMongoOperations .remove(Query
      .query(Criteria.where("id").is(id)), Reservation.class)
      .flatMap(deleteResult -> Mono.just(deleteResult.wasAcknowledged()));
  }

  public Flux<Reservation> listAllReservations() {
    return reactiveMongoOperations .findAll(Reservation.class);
  }
}

29 Aralık 2020 Salı

SpringData MongoDB @Query Anotasyonu

Giriş
Şu satırı dahil ederiz. Bu anotasyon ile Derived Query olarak gerçekleştirilemeyen işler yapabiliriz.
import org.springframework.data.mongodb.repository.MongoRepository;
import org.springframework.data.mongodb.repository.Query;
Bazı güzel örnekler burada.

Alana Göre Arama
Örnek
Şöyle yaparız. Aslında bu örnek çok iyi değil çünkü findByTitle zaten Derived Query olarak ta yapılabilirdi.
public interface MovieRepository extends MongoRepository<Movie,String> {
  @Query("{'title':?0}")
  Optional<Movie> findByTitle(String title);
}

18 Aralık 2020 Cuma

SpringData MongoDB Reactive

Giriş
Şu satırı dahil ederiz
import org.springframework.data.mongodb.repository.ReactiveMongoRepository;
Maven
Şu satırı dahil ederiz
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-mongodb-reactive</artifactId>
</dependency>
Örnek
Elimizde şöyle bir kod olsun. Bu kod için ReactiveMongoRepository yaratılır
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document
public class Employee {
    @Id
    private String id;
    private String name;
    private String department;
    // Constructors, getters, and setters
}
Örnek
Elimizde şöyle bir kod olsun. Bu kod için ReactiveMongoRepository yaratılır
import lombok.Data;
import lombok.ToString;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Data
@Document
@ToString
public class Freelancer {

    @Id
    private String id;
    private String name;
    private int age;
    private List<String> skills;

}

7 Ağustos 2020 Cuma

SpringData MongoDB application.properties Ayarları

Giriş
AbstractMongoConfiguration sınıfı yerine application.properties dosyasında şu ayarlar yapılır.
#mongodb
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=webflux_demo
spring.data.mongodb.uri
spring.data.mongodb.host, spring.data.mongodb.port, spring.data.mongodb.database gibi değişkenleri teker teker atamak yerine, her şeyi birleştirilmiş şekilde bir uri olarak belirtebiliriz. 

Açıklaması şöyle
...when spring boot container run, it tries to connect to localhost...
Örnek
Şöyle yaparız
spring.data.mongodb.uri=mongodb://mongodb:27017/<dbname>
Örnek
Şöyle yaparız.
spring.data.mongodb.uri=mongodb://mongocontainer:27017/test
Örnek - Connection Pool Ayarları
Connection Pool Ayarları URI içinde veriliyor, çünkü bu işi MongoDB Driver hallediyor. Şöyle yaparız.
spring.data.mongodb.uri=mongodb://localhost:27017/?connectTimeoutMS=300000&minPoolSize=0
  &maxPoolSize=10&maxIdleTimeMS=900000
Örnek - Connection Pool Ayarları
Connection Pool Ayarları URI içinde veriliyor, çünkü bu işi MongoDB Driver hallediyor. Şöyle yaparız
spring.data.mongodb.uri=mongodb://localhost:27017/?connectTimeoutMS=30000
&minPoolSize=0&maxPoolSize=50
Örnek - readPreference
Okuma işleminde salt okunur secondary node'dan okuma yapar. 
Örnek
Şöyle yaparız.
spring.data.mongodb.uri=mongodb://10.9.9.71:27017,10.9.9.71:27018,10.9.9.71:27019/
?
readPreference=secondaryPreferred
Örnek - ReplicaSet
Şöyle yaparız. Burada readPreference=secondary yanında Kubernetes ortamında hangi isimli ReplicaSet'e bağlanılacağı da belirtiliyor.

spring: data: mongodb: uri: "mongodb://root:root@172.16.238.10:27017,172.16.238.11:27017,\ 172.16.238.12:27017/tutorial-db? \ authSource=admin&
replicaSet=tutorial-cluster&readPreference=secondary"

spring.data.mongodb.username
Bağlantıda kullanılacak kullanıcı ismi

spring.data.mongodb.password
Bağlantıda kullanılacak kullanıcı şifresi

spring.data.mongodb.host
Örnek
Şöyle yaparız
spring.data.mongodb.host=localhost
spring.data.mongodb.port=27017
spring.data.mongodb.database=proximityService
spring.data.mongodb.port
Bağlantıda kullanılacak port numarası

spring.data.mongodb.database
Bağlanılacak veritabanı ismi

spring.data.mongodb.authentication-database
Bunu bilmiyorum




27 Nisan 2020 Pazartesi

SpringData MongoDB MongoTemplate Sınıfı

Giriş
MongoOperations arayüzünden kalıtır. MongoOperations için şu satırı dahil ederiz.
import org.springframework.data.mongodb.core.MongoOperations;
Bu sınıf MongoDB bağlantısı için SimpleMongoDbFactory bean'ini kullanılır.

Bu sınıfı kodla yaratmak yerine AbstractMongoConfiguration sınıfının yaratmasını kullanmak daha kolay.

Bu sınıf yerine MongoRepository de kullanılabilir.

Maven
Şu satırı dahil ederiz.
<dependency>
  <groupId>org.springframework.data</groupId>
  <artifactId>spring-data-mongodb</artifactId>
  <version>1.5.0.RELEASE</version>
</dependency>
constructor - MongoDbFactory + MongoConverter
İlk parametre olan MongoDbFactory arayüzü olarak, nu arayüzden kalıtan MongoDbFactorySupport, SimpleMongoClientDbFactory, SimpleMongoDbFactory kullanılır.
Örnek
Şöyle yaparız.
@Bean
MongoDbFactory mongoDbFactory() throws Exception {
  return new SimpleMongoDbFactory(...,...);
}

MappingMongoConverter converter = new MappingMongoConverter(mongoDbFactory(),
  new MongoMappingContext());
converter.setTypeMapper(new DefaultMongoTypeMapper(null));

MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
Örnek
Şöyle yaparız. Belirtilen uri'deki mongo veritabanına bağlanır.
@Configuration
public class MongoConfig {

  @Value("${spring.data.mongodb.uri}")
  private String uri;

  @Bean
  public MongoTemplate mongoTemplate() throws Exception {
    return new MongoTemplate(new SimpleMongoClientDbFactory(
      new ConnectionString(this.uri)));
  }
}
bulkOps metodu
Örnek - bulk insert
Şöyle yaparız
public void bulkInsertEvents(List<FoodEvent> foodEventList) {
  try {
    BulkWriteResult bulkWriteResult = mongoTemplatealo
.bulkOps(BulkOperations.BulkMode.UNORDERED, FoodEvent.class)
      .insert(foodEventList)
      .execute();
  } catch (BulkWriteException bwe) {
    List<Integer> failedEventIndexes = new ArrayList<>();
    for (BulkWriteError e : bwe.getWriteErrors()) {
      failedEventIndexes.add(e.getIndex());
      log.error("Insertion failed for index: {} with error: {}", e.getIndex(), e);
    }
  } catch (Exception e) {
    log.error("failed for {} events: {}", foodEventList.size(), foodEventList, e);
  }
}
Örnek
Şöyle yaparız
BulkOperations bulkOps = mongoTemplate.bulkOps(BulkOperations.BulkMode.UNORDERED);
bulkOps.upsert(upsertList);
bulkOps.updateMulti(deletList);
return bulkOps.execute();
find metodu
Örnek
Şöyle yaparız
@Autowired MongoTemplate template = ...; Criteria criteria = Criteria.where("mins").lte(30); Query query = new Query(); query.addCriteria(criteria); List<Recipe> recipes = template.find(query);
findAndModify metodu
updateMulti() gibi çalışır. Farklı olarak nesnenin değiştirilmeden önceki halini döndürür.

Örnek
Şöyle yaparız
Foo foo = mongoTemplate.findAndModify(
  query(where("_id").is(...)),
  new Update().inc("seq",1),
  options().returnNew(true).upsert(true),
  Foo.class);
findOne metodu
Şöyle yaparız.
@Override
public User findUserByUserName(String userName) {
  return mongoTemplate.findOne(
    new Query(Criteria.where("_id").is(userName)), User.class);
}
Örnek
Şöyle yaparız
public User getUser(String userId) {
  Query query = new Query().addCriteria(Criteria.where("userId").is(userId));
  return mongoTemplate.findOne(query,User.class,"user");
}
getCollection metodu
Şöyle yaparız.
DBCollection collection = mongoTemplate.getCollection(DbCollections.news);
insert metodu
Eğer _id zaten collection'da varsa exception fırlatır.

Örnek
Şöyle yaparız
public User saveUser(User user) {
  User insertedUser = mongoTemplate.insert(user,"user");
  return insertedUser;
}
remove metodu - Query query +  Class<?> entityClass + String collectionName
Örnek
Elimizde şöyle bir collection olsun
{
  _id
  company_id
  job_type
  name
  age
  ...
}
Elimizde şöyle bir kod olsun
val criteria = Criteria.where("company_id").isEqualTo(companyId)
.and("job_type").isEqualTo(jobType) val query = Query(criteria).limit(3)
Şöyle yaparız
mongoTemplate.remove(query, null, "collection_name")
save metodu
Eğer nesnenin id alanı boş ise yaratır, doluysa günceller. Açıklaması şöyle
If a document does not exist with the specified _id value, the save() method performs an insert with the specified fields in the document.

If a document exists with the specified _id value, the save() method performs an update, replacing all field in the existing record with the fields from the document.
Örnek
Şöyle yaparız.
@Override
public void saveUser(User user) {
  mongoTemplate.save(user);
}
updateFirst metodu
Verilen Query kriterine uyan ilk nesneyi günceller.
Örnek
Şöyle yaparız
public int updateMail(User updatedUser) {
  String newMail = updatedUser.getEmail();
  Query query = new Query().addCriteria(Criteria.where("userId").
    is(updatedUser.getUserId()));

  Update update = new Update();
  update.set("email",newMail);
  return (int)mongoTemplate.updateFirst(query,update,User.class,"user")
    .getModifiedCount();
}

updateMulti metodu
Verilen Query kriterine uyan tüm nesneleri günceller.

upsert metodu -  Query query +  Object + Class<?> entityClass
Bu metodun ismi saveOrUpdate() de olabilirdir. Eğer parametre olarak verilen nesne varsa günceller, yoksa yaratır.