Spring Data操作


对数据库的操作一定要放在@Service类中,而不是放在@Controller类中;且@Controller类可以调用@Service类的方法。

  • @Service类主要用于不易变的核心业务逻辑
  • @Controller类与前端页面紧密配合,调用@Service
    服务读写数据,从而响应前端请求

一、CRUD

1. 新增数据

在 Java 中万物皆对象。所以,所谓数据就是实例对象

import org.springframework.data.mongodb.core.MongoTemplate;

  @Autowired
  private MongoTemplate mongoTemplate;

  public void test() {
    Song song = new Song();
    song.setSubjectId("s001");
    song.setLyrics("...");
    song.setName("成都");
    mongoTemplate.insert(song);
  }

使用@Autowired可以让系统自动注入MongoTemplate的实例。只需要调用mongoTemplate.isnert()方法就能把对象存入数据库。

2. 查询数据
mongoTemplate.findById(songId, Song.class)

注意:findById()方法第 1 个参数是主键 id,第 2 个参数是具体的类,写法是类名.class

@Override
  public Song get(String songId) {
    // 输入的主键 id 必须有文本,不能为空或全空格
    if (!StringUtils.hasText(songId)) {
      LOG.error("input songId is blank.");
      return null;
    }

    Song song = mongoTemplate.findById(songId, Song.class);
    return song;
  }
3. 修改数据
  1. 修改那条数据?
  2. 哪个字段改成哪个值?
import com.mongodb.client.result.UpdateResult;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

//修改 id=1 的数据
Query query = new Query(Criteria.where("id").is("1"));
//把歌名修改为 “new name”
Update updateData = new Update();
updateData.set("name", "new name");
//执行修改,修改返回的结果是一个对象
UpdateResult result = mongoTemplate.updateFirst(query, updateData, Song.class);
//修改的记录数大于 0,表示修改成功
System.out.println(result.getModifiedCount());

先使用条件对象Criteria构建条件对象Query实例,然后再调用修改对象Update的方法.set()设置需要修改的字段。最后调用mongoTemplate.updateFirst(query, updateData, Song.class)方法完成修改;第 3 个参数是具体的类

4. 删除数据

只需要精确确定需要删除哪些数据即可。
调用mongoTemplate.remove()方法即可删除数据,参数是对象,表示需要删除哪些数据

import com.mongodb.client.result.DeleteResult;

@Override
  public boolean delete(String songId) {
    // 输入的主键 id 必须有文本,不能为空或全空格
    if (!StringUtils.hasText(songId)) {
      LOG.error("input songId is blank.");
      return false;
    }

    Song song = new Song();
    song.setId(songId);
	//执行删除
    DeleteResult result = mongoTemplate.remove(song);
    //删除的记录数大于 0,表示删除成功
    return result != null && result.getDeletedCount() > 0;
  }

创建一个对象并设置好属性值,作为删除的条件,符合条件的数据都将被删除。可以设置更多的属性值来提高精确性,但通过主键来删除数据,是保证不误删的一个比较好的办法

二、Spring Data Query

上面的查询是根据主键来查询的,但这显然是不能满足的。
查询的条件复杂一些,返回的数据很多。
核心方法:

List<Song> songs = mongoTemplate.find(query, Song.class);

第一个参数是查询对象Query实例,第二个参数就表示查询什么样的对象。
查询操作的复杂性在于条件,需要用构建好的Criteria条件对象的实例,来构建Query实例:

Query query = new Query(criteria);

构建Criteria条件对象,一般有两种情况:

  • 单一条件。用Criteria criteria1 = Criteria.where("条件字段名").is("条件值")即可返回一个条件对象的实例
  • 组合条件。根据 or、and 的关系进行组合,多个子条件对象组合成一个总条件对象:

or 关系:

Criteria criteria = new Criteria();
criteria.orOperator(criteria1, criteria2);

and 关系:

Criteria criteria = new Criteria();
criteria.andOperator(criteria1, criteria2);
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Criteria;

public List<Song> list(Song songParam) {
    // 总条件
    Criteria criteria = new Criteria();
    // 可能有多个子条件
    List<Criteria> subCris = new ArrayList();
    if (StringUtils.hasText(songParam.getName())) {
      subCris.add(Criteria.where("name").is(songParam.getName()));
    }

    if (StringUtils.hasText(songParam.getLyrics())) {
      subCris.add(Criteria.where("lyrics").is(songParam.getLyrics()));
    }

    if (StringUtils.hasText(songParam.getSubjectId())) {
      subCris.add(Criteria.where("subjectId").is(songParam.getSubjectId()));
    }

    // 必须至少有一个查询条件
    if (subCris.isEmpty()) {
      LOG.error("input song query param is not correct.");
      return null;
    }

    // 三个子条件以 and 关键词连接成总条件对象,相当于 name='' and lyrics='' and subjectId=''
    criteria.andOperator(subCris.toArray(new Criteria[]{}));

    // 条件对象构建查询对象
    Query query = new Query(criteria);
    // 限定输出,以免查询数据量太大
    query.limit(10);
    List<Song> songs = mongoTemplate.find(query, Song.class);

    return songs;
}

三。Spring Data 分页

只需要调用PageRequest.of()方法构建一个分页对象,然后注入到查询对象即可。
PageRequest.of()方法第一个参数是页码,从 0 开始计数,第一页的值是 0;第二个参数是每页的数量。

import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;

Pageable pageable = PageRequest.of(0, 20);
query.with(pageable);

对于分页来说,除了要查询结果意外,还需要查询总数,才能进一步计算出总共多少页,实现完整的分页功能。所以还需要两个步骤:

  • 调用count(query, XXX.class)方法查询总数。第一个参数是查询条件,第二个参数表示查询什么样的对象。
  • 根据结果、分页条件、总数三个数据,构建分页器对象
import org.springframework.data.domain.Page;
import org.springframework.data.repository.support.PageableExecutionUtils;

//总数
long count = mongoTemplate.count(query, Song.class);
//构建分页器
Page<Song> pageResult = PageableExecutionUtils.getPage(songs, pageable, new LongSupplier() {
	@Override
	public long getAsLong() {
		return count;
	}
});

PageableExecutionUtils.getPage()方法第一个参数是查询结果;第二个参数是分页条件对象;第三个参数实现一个LongSupplier接口的匿名类,在匿名类的getAsLong()方法中返回结果总数。方法返回值是一个Page分页器对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值