Spring Boot使用MongoDB

For installing MongoDB on a virtual machine, please refer to "Installing MongoDB4 on CentOS7"

The IDE I use is STS4, you can choose according to your own habits.

The key is to add pom.xml:


<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-data-mongodb</artifactId>

</dependency>

Add in application.properties:

spring.data.mongodb.uri=mongodb://用户名:密码@IP:PORT/数据库

Entity class


@Document(collection  = "test_goods")

publicclass GoodsEntity implements Serializable {

    privatestaticfinallongserialVersionUID = -805486477824888750L;

    @Id

    private String id;

    private String goodsName;

    privatelongcategoryId;

    privateintgoodsStatus;

    private String labels;

//省略get、set方法

}

Nothing else is explained, you can understand it at a glance, here we should pay attention to the id field.

With the above configuration and the annotation @Id, when we create a new Document, no additional settings are required, and a primary key as shown below will be automatically generated:

Spring Boot使用MongoDB

This is a primary key of ObjectId type named "_id", a 12-byte BSON type string.

4 bytes are the UNIX timestamp, 3 bytes are the MongoDB server, 2 bytes are the process of generating the ID, and 3 bytes are the random numbers.

The advantage of this is that it is distributed-friendly. And, because id contains a timestamp, it naturally carries the creation time. We can pass


ObjectId id = new ObjectId(entity.getId());

System.out.println(id.getDate());

Get the creation time.

Of course, if we use MongoDB as a supplement to traditional DB, if we still want to store the ID in the DB in MongoDB in the system, then remove the annotation of the id field and set the ID field when processing.

Dao


@Component

publicclass GoodsDao {

    @Autowired

    private MongoTemplate mongoTemplate;

    /**

     * 新建

     *

     * @param entity

     * @return

     */

    public GoodsEntity add(GoodsEntity entity) {

        returnmongoTemplate.save(entity);

    }

    /**

     * 根据ID修改

     *

     * @param entity

     * @return

     */

    public UpdateResult upd(GoodsEntity entity) {

        Query query = new Query(Criteria.where("id").is(entity.getId()));

        Update update = new Update().set("goodsName", entity.getGoodsName()).set("categoryId", entity.getCategoryId())

                .set("goodsStatus", entity.getGoodsStatus()).set("labels", entity.getLabels());

        returnmongoTemplate.updateFirst(query, update, GoodsEntity.class);

    }

    /**

     * 根据ID删除

     *

     * @param id

     * @return

     */

    public DeleteResult delById(longid) {

        Query query = new Query(Criteria.where("id").is(id));

        returnmongoTemplate.remove(query,  GoodsEntity.class);

    }

    /**

     * 根据主键获取详情

     *

     * @param id

     * @return

     */

    public GoodsEntity getById(longid) {

        Query query = new Query(Criteria.where("id").is(id));

        GoodsEntity entity = mongoTemplate.findOne(query, GoodsEntity.class);

        returnentity;

    }

    /**

     * 列出所有记录

     *

     * @return

     */

    public List<GoodsEntity> listAll() {

        List<GoodsEntity> entities = mongoTemplate.find(new Query(), GoodsEntity.class);

        returnentities;

    }

    /**

     * 根据某字段使用正则表达式模糊查询,且分页、ID倒序

     *

     * @param label

     * @param pageNumber

     * @param pageSize

     * @return

     */

    public List<GoodsEntity>  queryPageByLabel(String label, intpageNumber, intpageSize) {

        // 完全匹配

        // Pattern pattern =  Pattern.compile("^" + label + "$",

        // Pattern.CASE_INSENSITIVE);

        // 右匹配

        // Pattern pattern =  Pattern.compile("^.*\"+label+\"$",

        // Pattern.CASE_INSENSITIVE);

        // 左匹配

        // Pattern pattern = Pattern.compile("^\"+label+\".*$",

        // Pattern.CASE_INSENSITIVE);

        // 模糊匹配

        Pattern pattern = Pattern.compile("^.*" + MongoDBUtils.escapeExprSpecialWord(label) + ".*$",

                Pattern.CASE_INSENSITIVE);

        Query query = new Query(Criteria.where("labels").regex(pattern));

        // ID倒序

        query.with(new Sort(Sort.Direction.DESC, "id"));

        // 分页

        PageRequest pageableRequest = PageRequest.of(pageNumber, pageSize);

        query.with(pageableRequest);

        returnmongoTemplate.find(query,  GoodsEntity.class);

    }

    /**

     * 多查询条件,分页,ID倒序

     *

     * @param entity

     * @param pageNumber

     * @param pageSize

     * @return

     */

    public List<GoodsEntity>  queryPage(GoodsEntity entity, intpageNumber, intpageSize) {

        Criteria criteria = new Criteria();

        if (!StringUtils.isEmpty(entity.getGoodsName())) {

            Pattern pattern = Pattern.compile("^.*" + entity.getGoodsName() + ".*$", Pattern.CASE_INSENSITIVE);

            criteria.and("goodsName").regex(pattern);

        }

        if (!StringUtils.isEmpty(entity.getLabels())) {

            Pattern pattern = Pattern.compile("^.*" + entity.getLabels() + ".*$", Pattern.CASE_INSENSITIVE);

            criteria.and("labels").regex(pattern);

        }

        if (entity.getCategoryId() > 0) {

            criteria.and("categoryId").is(entity.getCategoryId());

        }

        if (entity.getGoodsStatus() > 0) {

            criteria.and("goodsStatus").is(entity.getGoodsStatus());

        }

        Query query = new Query(criteria);

        // 分页&ID倒序

        PageRequest pageableRequest = PageRequest.of(pageNumber, pageSize, Sort.Direction.DESC, "id");

        query.with(pageableRequest);

        returnmongoTemplate.find(query,  GoodsEntity.class);

    }

}

Personally I feel that most of the requirements are basically covered, and I will not explain the code in detail.

The main thing to note is that I did not use ObjectId this time, but the ID of the DB, so the ID of the Entity here is long.

test


@RunWith(SpringRunner.class)

@SpringBootTest

publicclass GoodsDaoTest {

    @Autowired

    private GoodsDao goodsDao;

    @Test

    publicvoid add() {

        GoodsEntity entity = new GoodsEntity();

        entity.setId(3); // 如果使用ObjectId,就不需要额外处理ID字段了。

        entity.setCategoryId(5);

        entity.setGoodsName("测试商品E");

        entity.setGoodsStatus(1);

        entity.setLabels("a,b,c,*,d");

        GoodsEntity newEntity = goodsDao.add(entity);

        JsonFormaterUtil.printFromObj(newEntity);

    }

    @Test

    publicvoid upd() {

        GoodsEntity entity = goodsDao.getById(1);

        entity.setLabels("a,b,c,d");

        JsonFormaterUtil.printFromObj(goodsDao.upd(entity));

    }

    @Test

    publicvoid del() {

        JsonFormaterUtil.printFromObj(goodsDao.delById(3));

    }

    @Test

    publicvoid getById() {

        JsonFormaterUtil.printFromObj(goodsDao.getById(1));

    }

    @Test

    publicvoid listAll() {

        JsonFormaterUtil.printFromObj(goodsDao.listAll());

    }

    @Test

    publicvoid queryByLabel() {

        JsonFormaterUtil.printFromObj(goodsDao.queryPageByLabel("*", 0, 2));

    }

    @Test

    publicvoid queryPage() {

        GoodsEntity entity = new GoodsEntity();

        // entity.setCategoryId(5);

        entity.setGoodsName("测试商品");

        // entity.setGoodsStatus(1);

        // entity.setLabels("a,b,c");

        JsonFormaterUtil.printFromObj(goodsDao.queryPage(entity, 0, 10));

    }

}

have nothing to say.

Log configuration
Because I personally like to print out the statements of DB operations on the console, the log configuration has been modified.

Spring Boot uses logback. Create a logback.xml file in the resources directory with the following content:


<?xml version="1.0"  encoding="UTF-8"?>

<configuration debug="false">

    <!--定义日志文件的存储绝对路径-->

    <property name="LOG_HOME"  value="d:/" />

    <!-- 控制台输出 -->

    <appender name="STDOUT"

        class="ch.qos.logback.core.ConsoleAppender">

        <encoder

            class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">

            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level  %logger{50} : %n%msg%n

            </pattern>

        </encoder>

    </appender>

    <!-- 按照每天生成日志文件 -->

    <appender name="FILE"

        class="ch.qos.logback.core.rolling.RollingFileAppender">

        <rollingPolicy

            class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">

            <!--日志文件输出的文件名 -->

            <FileNamePattern>${LOG_HOME}/mongodbdemo.log.%d{yyyy-MM-dd}.log

            </FileNamePattern>

            <!--日志文件保留天数 -->

            <MaxHistory>30</MaxHistory>

        </rollingPolicy>

        <encoder

            class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">

            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread]  %-5level %logger{50} :

                %msg%n

            </pattern>

        </encoder>

        <!--日志文件最大的大小 -->

        <triggeringPolicy

            class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">

            <MaxFileSize>10MB</MaxFileSize>

        </triggeringPolicy>

    </appender>

    <!-- 日志输出级别 -->

    <root level="ERROR">

        <appender-ref ref="STDOUT"  />

        <appender-ref ref="FILE"  />

    </root>

    <!-- MongoDB日志输出 -->

    <logger

        name="org.springframework.data.mongodb.core.MongoTemplate"

        level="DEBUG"  additivity="false">

        <appender-ref ref="STDOUT"  />

    </logger>

</configuration>

The key point is to configure MongoDB log output, where name is the log output class, and the level is set to debug to output the executed statements, similar to:


find using query: { "goodsName"  : { "$regex" : "^.*测试商品.*$",  "$options" : "i" } } fields: Document{{}} for class:  class org.leo.mongodb.demo.entity.GoodsEntity in collection: test_goods

And additivity="false" is because if you don't add it, the above log will be printed twice on the console.

When
querying through regular expressions, some special characters (*,?, etc.) will be encountered, which need to be escaped. The code is as follows:


publicclass MongoDBUtils {

    privatestaticfinal String[] fbsArr = { "\\", "$", "(", ")", "*", "+", ".", "[", "]", "?", "^", "{", "}", "|" };

    /**

     * regex对输入特殊字符转义

     *

     * @param keyword

     * @return

     */

    publicstatic String escapeExprSpecialWord(String keyword) {

        if (!StringUtils.isEmpty(keyword)) {

            for (String key : fbsArr) {

                if (keyword.contains(key)) {

                    keyword = keyword.replace(key, "\\" + key);

                }

            }

        }

        returnkeyword;

    }

}

index:


db.getCollection("test_goods").createIndex({  "categoryId": 1 }, { "name":  "idx_goods_categoryid" })

Create an index for categoryId, where 1 of {"categoryId": 1} represents creation in ascending order, and -1 represents descending order.

Create a composite index as follows:


db.getCollection("test_goods").createIndex({ "categoryId": 1,  "goodsStatus": -1 })

Set the unique index as follows:


db.getCollection("test_goods").createIndex({  "categoryId": 1}, {  "unique": true })

Guess you like

Origin blog.51cto.com/15067227/2603603