1. 程式人生 > >MongoDB進階(八)Spring整合MongoDB(Spring Data MongoDB)

MongoDB進階(八)Spring整合MongoDB(Spring Data MongoDB)

        最近比較忙,忙的都沒空理csdn了,今天我繼續邁著魔鬼般的步伐,摩擦摩擦……總結下最近學到的MongoDB的知識。

1.認識Spring Data MongoDB

        之前還的確不知道Spring連整合Nosql的東西都實現了,還以為自己又要手動封裝一個操作MongoDB的API呢,結果就發現了Spring Data MongoDB。不愧是Spring,真是給了我們春天,佩服的渣渣我目瞪狗呆……         廢話少說,看招。Spring Data其實是一個高級別的Spring Source專案,而Spring Data MongoDB僅僅是其中的一個子專案。Spring Data旨在為關係型資料庫、非關係型資料、Map-Reduce框架、雲資料服務等等提供統一的資料訪問API。
        無論是哪種持久化儲存, 資料訪問物件(或稱作為DAO,即Data Access Objects)通常都會提供對單一域物件的CRUD (建立、讀取、更新、刪除)操作、查詢方法、排序和分頁方法等。Spring Data則提供了基於這些層面的統一介面(CrudRepository,PagingAndSortingRepository)以及對持久化儲存的實現。

Spring Data 包含多個子專案:

  • Commons - 提供共享的基礎框架,適合各個子專案使用,支援跨資料庫持久化

  • Hadoop - 基於 Spring 的 Hadoop 作業配置和一個 POJO 程式設計模型的 MapReduce 作業

  • Key-Value  - 集成了 Redis 和 Riak ,提供多個常用場景下的簡單封裝

  • Document - 整合文件資料庫:CouchDB 和 MongoDB 並提供基本的配置對映和資料庫支援

  • Graph - 整合 Neo4j 提供強大的基於 POJO 的程式設計模型

  • Graph Roo AddOn - Roo support for Neo4j

  • JDBC Extensions - 支援 Oracle RAD、高階佇列和高階資料型別

  • JPA - 簡化建立 JPA 資料訪問層和跨儲存的持久層功能

  • Mapping - 基於 Grails 的提供物件對映框架,支援不同的資料庫

  • Examples - 示例程式、文件和圖資料庫

  • Guidance - 高階文件

2. HelloWorld

好了,說了這麼多,還是用程式碼表現最為實在,老規矩,Hello World,我這裡建立了一個Maven Java專案demo。

2.1 配置依賴

【pom.xml】
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>

	<groupId>com.jastar</groupId>
	<artifactId>demo</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>jar</packaging>

	<name>demo</name>
	<url>http://www.jastar-wang.tech</url>

	<!-- 版本配置 -->
	<properties>
		<spring.version>4.1.4.RELEASE</spring.version>
		<spring.data.version>1.7.0.RELEASE</spring.data.version>
		<log4j.version>1.2.17</log4j.version>
	</properties>

	<dependencies>
		<!-- 單元測試包 -->
		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>4.10</version>
			<scope>test</scope>
		</dependency>

		<!-- spring核心包 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-core</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-context</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-beans</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-tx</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-webmvc</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-aop</artifactId>
			<version>${spring.version}</version>
		</dependency>
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-test</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- 關係型資料庫整合時需配置 如hibernate jpa等 -->
		<dependency>
			<groupId>org.springframework</groupId>
			<artifactId>spring-orm</artifactId>
			<version>${spring.version}</version>
		</dependency>

		<!-- spring aop 關聯 -->
		<dependency>
			<groupId>org.aspectj</groupId>
			<artifactId>aspectjweaver</artifactId>
			<version>1.8.7</version>
		</dependency>

		<!-- log4j -->
		<dependency>
			<groupId>log4j</groupId>
			<artifactId>log4j</artifactId>
			<version>${log4j.version}</version>
		</dependency>

		<!-- spring整合MongoDB -->
		<dependency>
			<groupId>org.springframework.data</groupId>
			<artifactId>spring-data-mongodb</artifactId>
			<version>${spring.data.version}</version>
		</dependency>

	</dependencies>

	<repositories>
		<repository>
			<id>spring-milestone</id>
			<name>Spring Maven MILESTONE Repository</name>
			<url>http://repo.spring.io/libs-milestone</url>
		</repository>
	</repositories>

	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>1.7</source>
					<target>1.7</target>
				</configuration>
			</plugin>
		</plugins>
	</build>
</project>

注意:這裡我使用的是Spring Data MongoDB 1.7.0版本,截止當前發文時間最新穩定版本應該是1.10.1

2.2 對映實體類

【UserInfo.java】
package com.jastar.demo.entity;

import java.io.Serializable;
import java.sql.Timestamp;

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

/**
 * 使用者實體類
 * <p>
 * ClassName: UserInfo
 * </p>
 * <p>
 * Description:本類用來展示MongoDB實體類對映的使用
 * </p>
 * <p>
 * Copyright: (c)2017 Jastar·Wang,All rights reserved.
 * </p>
 * 
 * @author Jastar·Wang
 * @date 2017年4月12日
 */
@Document(collection = "coll_user")
public class UserInfo implements Serializable {

	/** serialVersionUID */
	private static final long serialVersionUID = 1L;

	// 主鍵使用此註解
	@Id
	private String id;

	// 欄位使用此註解
	@Field
	private String name;

	// 欄位還可以用自定義名稱
	@Field("myage")
	private int age;

	// 還可以生成索引
	@Indexed(name = "index_birth", direction = IndexDirection.DESCENDING)
	@Field
	private Timestamp birth;

	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 Timestamp getBirth() {
		return birth;
	}

	public void setBirth(Timestamp birth) {
		this.birth = birth;
	}

}
附錄:
  • @Id - 用於欄位級別,標記這個欄位是一個主鍵,預設生成的名稱是“_id”

  • @Document - 用於類,以表示這個類需要對映到資料庫,您也可以指定對映到資料庫的集合名稱

  • @DBRef - 用於欄位,以表示它將使用com.mongodb.DBRef進行儲存。

  • @Indexed - 用於欄位,表示該欄位需要如何建立索引

  • @CompoundIndex - 用於類,以聲明覆合索引

  • @GeoSpatialIndexed - 用於欄位,進行地理位置索引

  • @TextIndexed - 用於欄位,標記該欄位要包含在文字索引中

  • @Language - 用於欄位,以設定文字索引的語言覆蓋屬性。

  • @Transient - 預設情況下,所有私有欄位都對映到文件,此註解將會去除此欄位的對映

  • @PersistenceConstructor - 標記一個給定的建構函式,即使是一個protected修飾的,在從資料庫例項化物件時使用。建構函式引數通過名稱對映到檢索的DBObject中的鍵值。

  • @Value - 這個註解是Spring框架的一部分。在對映框架內,它可以應用於建構函式引數。這允許您使用Spring表示式語言語句來轉換在資料庫中檢索的鍵值,然後再用它來構造一個域物件。為了引用給定文件的屬性,必須使用以下表達式:@Value("#root.myProperty"),root要指向給定文件的根。

  • @Field - 用於欄位,並描述欄位的名稱,因為它將在MongoDB BSON文件中表示,允許名稱與該類的欄位名不同。

  • @Version - 用於欄位鎖定,儲存操作時檢查修改。初始值是0,每次更新時自動觸發。

2.3 整合配置

【db.properties】
###---The mongodb settings---
mongo.dbname=demo
mongo.host=localhost
mongo.port=27017
mongo.connectionsPerHost=8
mongo.threadsAllowedToBlockForConnectionMultiplier=4
mongo.connectTimeout=1000
mongo.maxWaitTime=1500
mongo.autoConnectRetry=true
mongo.socketKeepAlive=true
mongo.socketTimeout=1500
mongo.slaveOk=true
mongo.writeNumber=1
mongo.writeTimeout=0
mongo.writeFsync=true
【spring-mgo.xml】
<?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-3.0.xsd
          http://www.springframework.org/schema/data/mongo 
          http://www.springframework.org/schema/data/mongo/spring-mongo-1.0.xsd
          http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

	<!-- 讀取屬性檔案 -->
	<context:property-placeholder location="classpath:db.properties" />

	<!-- 啟用註解支援 -->
	<context:annotation-config />

	<!-- 掃描元件包 -->
	<context:component-scan base-package="com.jastar.demo" />

	<!-- SpringData型別轉換器 -->
	<mongo:mapping-converter id="mongoConverter">
		<mongo:custom-converters>
			<mongo:converter>
				<bean class="com.jastar.demo.converter.TimestampConverter" />
			</mongo:converter>
		</mongo:custom-converters>
	</mongo:mapping-converter>

	<!-- 
		MongoDB配置部分 
		1.mongo:連線配置 
		2.db-factory:相當於sessionFactory 
		3.mongoTemplate:與資料庫介面互動的主要實現類 
	-->
	<mongo:mongo host="${mongo.host}" port="${mongo.port}">
		<mongo:options 
			connections-per-host="${mongo.connectionsPerHost}"
			threads-allowed-to-block-for-connection-multiplier="${mongo.threadsAllowedToBlockForConnectionMultiplier}"
			connect-timeout="${mongo.connectTimeout}" 
			max-wait-time="${mongo.maxWaitTime}"
			auto-connect-retry="${mongo.autoConnectRetry}" 
			socket-keep-alive="${mongo.socketKeepAlive}"
			socket-timeout="${mongo.socketTimeout}" 
			slave-ok="${mongo.slaveOk}"
			write-number="${mongo.writeNumber}" 
			write-timeout="${mongo.writeTimeout}"
			write-fsync="${mongo.writeFsync}" />
	</mongo:mongo>

	<mongo:db-factory id="mongoDbFactory" dbname="${mongo.dbname}" mongo-ref="mongo" />

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

</beans>
說明: mongo:options - 用於配置一些資料庫連線設定資訊 mongo:db-factory - 相當於Hibernate中的SessionFactory mongoTemplate - 非常重要,整個與資料庫的互動操作全是靠他,相當於Hibernate的HibernateTemplate         另外,以上配置中有一個型別轉換器,因為Spring Data MongoDB本身預設時間型別是java.util.Date,如果實體欄位含有java.sql.Timestamp型別,需要自定義轉換器進行轉換,否則後續操作會報錯(深有感觸)!什麼?不把轉換器程式碼貼出來?彆著急,文章最後有整個專案地址,去裡面找吧……偷笑.GIF

2.4 Dao層參考實現

【BaseDaoImpl.java】

package com.jastar.demo.dao.impl;

import static org.springframework.data.mongodb.core.query.Criteria.where;

import java.io.Serializable;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.annotation.Id;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.data.domain.Sort.Order;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;

import com.jastar.demo.dao.IBaseDao;
import com.jastar.demo.util.EmptyUtil;
import com.jastar.demo.util.PageModel;

/**
 * 基本操作介面MongoDB資料庫實現類
 * <p>
 * ClassName: BaseDaoImpl
 * </p>
 * <p>
 * Description:本實現類適用於MongoDB資料庫,以下程式碼僅供參考,本人水平有限,可能會存在些許問題(如有更好方案可告知我,一定虛心學習),
 * 再次提醒,僅供參考!!
 * </p>
 * <p>
 * Copyright: (c)2017 Jastar·Wang,All rights reserved.
 * </p>
 * 
 * @author Jastar·Wang
 * @date 2017年4月12日
 */
public abstract class BaseDaoImpl<T> implements IBaseDao<T> {

	protected abstract Class<T> getEntityClass();

	@Autowired
	protected MongoTemplate mgt;

	@Override
	public void save(T entity) {
		mgt.save(entity);
	}

	@Override
	public void update(T entity) {

		// 反向解析物件
		Map<String, Object> map = null;
		try {
			map = parseEntity(entity);
		} catch (Exception e) {
			e.printStackTrace();
		}

		// ID欄位
		String idName = null;
		Object idValue = null;

		// 生成引數
		Update update = new Update();
		if (EmptyUtil.isNotEmpty(map)) {
			for (String key : map.keySet()) {
				if (key.indexOf("{") != -1) {
					// 設定ID
					idName = key.substring(key.indexOf("{") + 1, key.indexOf("}"));
					idValue = map.get(key);
				} else {
					update.set(key, map.get(key));
				}
			}
		}
		mgt.updateFirst(new Query().addCriteria(where(idName).is(idValue)), update, getEntityClass());
	}

	@Override
	public void delete(Serializable... ids) {
		if (EmptyUtil.isNotEmpty(ids)) {
			for (Serializable id : ids) {
				mgt.remove(mgt.findById(id, getEntityClass()));
			}
		}

	}

	@Override
	public T find(Serializable id) {
		return mgt.findById(id, getEntityClass());
	}

	@Override
	public List<T> findAll() {
		return mgt.findAll(getEntityClass());
	}

	@Override
	public List<T> findAll(String order) {
		List<Order> orderList = parseOrder(order);
		if (EmptyUtil.isEmpty(orderList)) {
			return findAll();
		}
		return mgt.find(new Query().with(new Sort(orderList)), getEntityClass());
	}

	@Override
	public List<T> findByProp(String propName, Object propValue) {
		return findByProp(propName, propValue, null);
	}

	@Override
	public List<T> findByProp(String propName, Object propValue, String order) {
		Query query = new Query();
		// 引數
		query.addCriteria(where(propName).is(propValue));
		// 排序
		List<Order> orderList = parseOrder(order);
		if (EmptyUtil.isNotEmpty(orderList)) {
			query.with(new Sort(orderList));
		}
		return mgt.find(query, getEntityClass());
	}

	@Override
	public List<T> findByProps(String[] propName, Object[] propValue) {
		return findByProps(propName, propValue, null);
	}

	@Override
	public List<T> findByProps(String[] propName, Object[] propValue, String order) {
		Query query = createQuery(propName, propValue, order);
		return mgt.find(query, getEntityClass());
	}

	@Override
	public T uniqueByProp(String propName, Object propValue) {
		return mgt.findOne(new Query(where(propName).is(propValue)), getEntityClass());
	}

	@Override
	public T uniqueByProps(String[] propName, Object[] propValue) {
		Query query = createQuery(propName, propValue, null);
		return mgt.findOne(query, getEntityClass());
	}

	@Override
	public PageModel<T> pageAll(int pageNo, int pageSize) {
		return pageAll(pageNo, pageSize, null);
	}

	@Override
	public PageModel<T> pageAll(int pageNo, int pageSize, String order) {
		return pageByProp(pageNo, pageSize, null, null, order);
	}

	@Override
	public PageModel<T> pageByProp(int pageNo, int pageSize, String param, Object value) {
		return pageByProp(pageNo, pageSize, param, value, null);
	}

	@Override
	public PageModel<T> pageByProp(int pageNo, int pageSize, String param, Object value, String order) {
		String[] params = null;
		Object[] values = null;
		if (EmptyUtil.isNotEmpty(param)) {
			params = new String[] { param };
			values = new Object[] { value };
		}
		return pageByProps(pageNo, pageSize, params, values, order);
	}

	@Override
	public PageModel<T> pageByProps(int pageNo, int pageSize, String[] params, Object[] values) {
		return pageByProps(pageNo, pageSize, params, values, null);
	}

	@Override
	public PageModel<T> pageByProps(int pageNo, int pageSize, String[] params, Object[] values, String order) {
		// 建立分頁模型物件
		PageModel<T> page = new PageModel<>(pageNo, pageSize);

		// 查詢總記錄數
		int count = countByCondition(params, values);
		page.setTotalCount(count);

		// 查詢資料列表
		Query query = createQuery(params, values, order);

		// 設定分頁資訊
		query.skip(page.getFirstResult());
		query.limit(page.getPageSize());

		// 封裝結果資料
		page.setList(mgt.find(query, getEntityClass()));

		return page;
	}

	@Override
	public int countByCondition(String[] params, Object[] values) {
		Query query = createQuery(params, values, null);
		Long count = mgt.count(query, getEntityClass());
		return count.intValue();
	}

	/**
	 * 建立帶有where條件(只支援等值)和排序的Query物件
	 * 
	 * @param params
	 *            引數陣列
	 * @param values
	 *            引數值陣列
	 * @param order
	 *            排序
	 * @return Query物件
	 */
	protected Query createQuery(String[] params, Object[] values, String order) {
		Query query = new Query();

		// where 條件
		if (EmptyUtil.isNotEmpty(params) && EmptyUtil.isNotEmpty(values)) {
			for (int i = 0; i < params.length; i++) {
				query.addCriteria(where(params[i]).is(values[i]));
			}
		}

		// 排序
		List<Order> orderList = parseOrder(order);
		if (EmptyUtil.isNotEmpty(orderList)) {
			query.with(new Sort(orderList));
		}

		return query;
	}

	/**
	 * 解析Order字串為所需引數
	 * 
	 * @param order
	 *            排序引數,如[id]、[id asc]、[id asc,name desc]
	 * @return Order物件集合
	 */
	protected List<Order> parseOrder(String order) {
		List<Order> list = null;
		if (EmptyUtil.isNotEmpty(order)) {
			list = new ArrayList<Order>();
			// 共有幾組排序欄位
			String[] fields = order.split(",");
			Order o = null;
			String[] item = null;
			for (int i = 0; i < fields.length; i++) {
				if (EmptyUtil.isEmpty(fields[i])) {
					continue;
				}
				item = fields[i].split(" ");
				if (item.length == 1) {
					o = new Order(Direction.ASC, item[0]);
				} else if (item.length == 2) {
					o = new Order("desc".equalsIgnoreCase(item[1]) ? Direction.DESC : Direction.ASC, item[0]);
				} else {
					throw new RuntimeException("排序欄位引數解析出錯");
				}
				list.add(o);
			}
		}
		return list;
	}

	/**
	 * 將物件的欄位及值反射解析為Map物件<br>
	 * 這裡使用Java反射機制手動解析,並且可以識別註解為主鍵的欄位,以達到根據id進行更新實體的目的<br>
	 * key:欄位名稱,value:欄位對應的值
	 * 
	 * @param t
	 *            要修改的物件
	 * @return Map物件,注意:id欄位的key封裝為“{id欄位名稱}”,以供後續識別
	 * @throws Exception
	 */
	protected Map<String, Object> parseEntity(T t) throws Exception {
		Map<String, Object> map = new HashMap<String, Object>();
		/*
		 * 解析ID
		 */
		String idName = "";
		Field[] declaredFields = getEntityClass().getDeclaredFields();
		for (Field field : declaredFields) {
			if (field.isAnnotationPresent(Id.class)) {
				field.setAccessible(true);
				map.put("{" + field.getName() + "}", field.get(t));
				idName = field.getName();
				break;
			}
		}
		/*
		 * 解析其他屬性
		 */
		Method[] methods = getEntityClass().getDeclaredMethods();
		if (EmptyUtil.isNotEmpty(methods)) {
			for (Method method : methods) {
				if (method.getName().startsWith("get") && method.getModifiers() == Modifier.PUBLIC) {
					String fieldName = parse2FieldName(method.getName());
					if (!fieldName.equals(idName)) {
						map.put(fieldName, method.invoke(t));
					}
				}
			}
		}

		return map;
	}

	/**
	 * 將get方法名轉換為對應的欄位名稱
	 * 
	 * @param methodName
	 *            如:getName
	 * @return 如:name
	 */
	private String parse2FieldName(String methodName) {
		String name = methodName.replace("get", "");
		name = name.substring(0, 1).toLowerCase() + name.substring(1);
		return name;
	}

}

說明:

        以上實現僅供參考某些實現點,mongoTemplate如何使用還要自己去詳細的摸索,我也沒辦法,畢竟我也這樣過來的,大多數方法都已經提供了,只是update方法不像關係型資料庫那樣,給個實體類就能更新,需要自己去想辦法搞定。

【TestUseService.java】

package com.jastar.test;

import java.sql.Timestamp;
import java.util.List;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;

import com.jastar.demo.entity.UserInfo;
import com.jastar.demo.service.UserService;
import com.jastar.demo.util.PageModel;

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = "classpath:spring-mgo.xml")
public class TestUserService {

	@Autowired
	private UserService service;

	@Test
	public void save() {
		UserInfo user = new UserInfo();
		user.setName("張三");
		user.setAge(25);
		user.setBirth(Timestamp.valueOf("2017-4-12 16:52:00"));
		service.save(user);
		System.out.println("已生成ID:" + user.getId());
	}

	@Test
	public void find() {
		UserInfo user = service.find("58edf1b26f033406394a8a61");
		System.out.println(user.getName());
	}

	@Test
	public void update() {
		UserInfo user = service.find("58edf1b26f033406394a8a61");
		user.setAge(18);
		service.update(user);
	}

	@Test
	public void delete() {
		service.delete("58edef886f03c7b0fdba51b9");
	}

	@Test
	public void findAll() {
		List<UserInfo> list = service.findAll("age desc");
		for (UserInfo u : list) {
			System.out.println(u.getName());
		}
	}

	@Test
	public void findByProp() {
		List<UserInfo> list = service.findByProp("name", "張三");
		for (UserInfo u : list) {
			System.out.println(u.getName());
		}
	}

	@Test
	public void findByProps() {
		List<UserInfo> list = service.findByProps(new String[] { "name", "age" }, new Object[] { "張三", 18 });
		for (UserInfo u : list) {
			System.out.println(u.getName());
		}
	}

	@Test
	public void pageAll() {
		PageModel<UserInfo> page = service.pageAll(1, 10);
		System.out.println("總記錄:" + page.getTotalCount() + ",總頁數:" + page.getTotalPage());
		for (UserInfo u : page.getList()) {
			System.out.println(u.getName());
		}
	}

	@Test
	public void pageByProp() {
		PageModel<UserInfo> page = service.pageByProp(1, 10, "name", "張三");
		System.out.println("總記錄:" + page.getTotalCount() + ",總頁數:" + page.getTotalPage());
		for (UserInfo u : page.getList()) {
			System.out.println(u.getName());
		}
	}

}


更多知識,請參考官方文件:戳我戳我

更多程式碼,請參考本專案Git 地址:戳我戳我

相關推薦

MongoDBSpring整合MongoDBSpring Data MongoDB

        最近比較忙,忙的都沒空理csdn了,今天我繼續邁著魔鬼般的步伐,摩擦摩擦……總結下最近學到的MongoDB的知識。 1.認識Spring Data MongoDB         之前還的確不知道Spring連整合Nosql的東西都實現了,還以為自己又要

學習筆記之MongoDB

MongoDB的條件操作符 MongoDB中條件操作符有: (>) 大於 - $gt (<) 小於 - $lt (>=) 大於等於 - $gte (<= ) 小於等於 - $lte $gt -------- greater than

Java高階架構師系統之路全套視訊免費獲取Dubbo、Redis、Netty、zookeeper Spring cloud、分散式、高併發等架構技術

效能調優 03 Spring原始碼分析 04 Spring MVC原始碼分析 05 Mybatis原始碼解析 06 網際網路分散式架構思維 07 架構開發基礎之

C#系列——WebApi 異常處理解決方案

機制 輸出 ges 如果 但是 rom lba slist 解決 出處:http://www.cnblogs.com/landeanfen/p/5363846.html 閱讀目錄 一、使用異常篩選器捕獲所有異常 二、HttpResponseException自

Python---面向對象第三彈

python對象 one iss pri each super left connect ext  Python對象中一些方法 一、__str__ class Teacher: def __init__(self,name,age): self.name

Linux入門第二天——軟件安裝管理

軟件包 軟件安裝 alt dpkg 代碼包 mage 進階 部分 images 一、大綱介紹    二、簡介   軟件包分類:   源碼包:        二進制包:(源碼包編譯後的包,將不能再看到源代碼)   MySQL PhP等開發環境的搭

Ruby操作MongoDB(--文本搜索text search

text search mongodb MongoDB數據庫對於文本內容之上搜索查詢操作上提供了文本索引,文本索引可以應用於所有的字符串或者字符數組的字段。為了在Ruby驅動上使用文本搜索,首先使用indexes.create_one()方法創建一個文本索引。下面的實例中,在test數據庫中的re

Python---python strip() split()函數實戰

ogl alt rate syn str1 valid blog xxxxxxxx www 先看一個例子: >>> ipaddr = 10.122.19.10 File "", line 1 ipaddr = 10.122.19.10

樹莓派之路 (032) -字符問題2 - 用c語言怎樣得到一個漢字的GB2312編碼(轉)

十六進制 字符串 c++ gb2 十進制 轉換 tails 表示 blog C/C++支持的是ASCII,不過漢字編碼中,GB2312與ASCII是兼容的,所以可以在C中獲得漢字的GB2312編碼 GB2312是兩個字節的,第一字節是高八位,第二字節是低八位,比如下面的程序

老王Python-篇4-異常處理1.3周末習題

調用 page eve sage urn put not name bject 一 編寫with操作類Fileinfo(),定義__enter__和__exit__方法。完成功能: 1.1 在__enter__方法裏打開Fileinfo(filename),並且返回file

python3之推導式4之集合set推導式comprehensions

列表推導 pre AS com highlight 不可 except exce tput 1.前言 跟列表推導式也是類似的, 區別在於它使用大括號{}。 2.實例 示例1 s = {x**2 for x in [1, 1, 2]} print(s)

Spring整合MyBatis 使用掃描包配置mapper代理

4.0 ike 生日 exce ini idl XML lis address Spring整合MyBatis (使用掃描包配置mapper代理) pojo是根據表生成的實體類,屬性名要跟字段名相同,不相同sql語句查詢時用別名。 首先導jar包 實體類 public cl

Spring整合MyBatissqlSessionFactory創建

ger tab var 其他 結合 mit 註入 處理 sources 摘要: 本文結合《Spring源碼深度解析》來分析Spring 5.0.6版本的源代碼。若有描述錯誤之處,歡迎指正。 目錄 一、SqlSessionFactoryBean的初始化 二、獲取 Sq

Linux:自動化運維之ANSIBLE

運維自動化發展歷程 1、本地部署(On-Premiss) 部署硬體+軟體+作業系統+環境+服務 2、基礎設施即服務(Iaas) 相當於只准備硬體 3、平臺即服務(Paas) 相當於只准備服務 4、軟體即服務(SaaS) 直接使用 企業實際應用場景分析 1、Dev開發環境 使用者:程式

學習資料庫Mysql/Oracle/SQL從入門到書籍pdf版吐血整理推薦珍藏版

轉載自某大佬部落格:https://pymlovelyq.github.io/2018/10/12/database/ 前言:技術書閱讀方法論 一.速讀一遍(最好在1~2天內完成) 人的大腦記憶力有限,在一天內快速看完一本書會在大腦裡留下深刻印象,對於之後複習以及總結

安卓從入門到推薦學習方法與書籍整理pdf

前言:技術書閱讀方法論   一.速讀一遍(最好在1~2天內完成)   人的大腦記憶力有限,在一天內快速看完一本書會在大腦裡留下深刻印象,對於之後複習以及總結都會有特別好的作用。   對於每一章的知識,先閱讀標題,弄懂大概講的是什麼主題,再去快速看

【演算法競賽指南】CH1301鄰值查詢set

給定一個長度為 n 的序列 A,A 中的數各不相同。對於 A 中的每一個數 \(A_{i}\),求:\(min(1\leq j<i)\left | A_{i}-A_{j} \right |\) 以及令上式取到最小值的 j(記為 \(P_{i}\))。若最小值點不唯一,則選擇使 \(A_{j}\)

學習資料庫從入門到書籍pdf版吐血整理推薦珍藏版

前言: 技術書閱讀方法論 一.速讀一遍(最好在1~2天內完成) 人的大腦記憶力有限,在一天內快速看完一本書會在大腦裡留下深刻印象,對於之後複習以及總結都會有特別好的作用。 對於每一章的知識,先閱讀標題,弄懂大概講的是什麼主題,再去快速看一遍,不懂也沒有關係,但是一定

【vue 指南 一】多語言國際化中英文切換

vue + element-ui + vue-i18n 多語言國際化 1.element-ui 並不支援最新版的vue-i8n 外掛,開發時注意i18n的版本,當然本示例成功解決版本不相容的問題,詳細說明請看element官方文件:http://eleme

Python:函數語言程式設計例項附程式碼

上篇文章“幾個小例子告訴你, 一行Python程式碼能幹哪些事 -- 知乎專欄”中用到了一些列表解析、生成器、map、filter、lambda、zip等表達形式,這就涉及到了Python中關於函數語言程式設計(functional programming)的語法、函式等