Spring Boot UsingMongoDB

仮想マシンへのMongoDBのインストールについては、「CentOS7へのMongoDB4のインストール」を参照してください。

私が使用しているIDEはSTS4で、自分の習慣に合わせて選択できます。

重要なのは、pom.xmlを追加することです。


<dependency>

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

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

</dependency>

application.propertiesを追加します。

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

エンティティクラス


@Document(collection  = "test_goods")

publicclass GoodsEntity implements Serializable {

    privatestaticfinallongserialVersionUID = -805486477824888750L;

    @Id

    private String id;

    private String goodsName;

    privatelongcategoryId;

    privateintgoodsStatus;

    private String labels;

//省略get、set方法

}

他に何も説明されていません。一目で理解できます。ここでは、idフィールドに注意する必要があります。

上記の構成と注釈@Idを使用すると、新しいドキュメントを作成するときに追加の設定は不要であり、以下に示すような主キーが自動的に生成されます。

Spring Boot UsingMongoDB

これは、12バイトのBSONタイプの文字列である「_id」という名前のObjectIdタイプの主キーです。

4バイトはUNIXタイムスタンプ、3バイトはMongoDBサーバー、2バイトはIDを生成するプロセス、3バイトは乱数です。

これの利点は、配布に適していることです。また、idにはタイムスタンプが含まれているため、当然、作成時刻が含まれます。合格できます


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

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

作成時間を取得します。

もちろん、従来のDBの補足としてMongoDBを使用する場合でも、システム内のMongoDBのDBにIDを保存する場合は、idフィールドの注釈を削除し、処理時にIDフィールドを設定します。

ダオ


@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);

    }

}

個人的には、ほとんどの要件は基本的にカバーされていると感じており、コードについては詳しく説明しません。

ここで重要なのは、今回はObjectIdを使用しなかったが、DBのIDを使用したため、ここでのエンティティのIDは長いことです。

テスト


@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));

    }

}

言うことは何もありません。

ログ構成
私は個人的にコンソールでDB操作のステートメントを印刷するのが好きなので、ログ構成が変更されました。

SpringBootはlogbackを使用します。resourcesディレクトリに次の内容のlogback.xmlファイルを作成します。


<?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>

重要な点は、MongoDBログ出力を構成することです。ここで、nameはログ出力クラスであり、レベルは、次のように、実行されたステートメントを出力するようにデバッグするように設定されます。


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

また、additivity = "false"は、追加しないと、上記のログがコンソールに2回出力されるためです。


正規表現を通じて照会し、いくつかの特殊文字の必要性をエスケープするためにどの、遭遇されるコードは以下の通りである(*、など?)。:


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;

    }

}

インデックス:


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

categoryIdのインデックスを作成します。ここで、{"categoryId":1}の1は昇順の作成を表し、-1は降順を表します。

次のように複合インデックスを作成します。


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

一意のインデックスを次のように設定します。


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

おすすめ

転載: blog.51cto.com/15067227/2603603