一直想写这部分,但是由于水平太差了,一直没敢写;今天就献丑把自己的实践写一下,自己以后实际开发也可以回头看看。这里贴的代码都是自己测试真实的代码。下载地址:百度云分享(spring-mongo.rar)
配置
(注:配置大同小异,我就简单的配置了一下。)
maven 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/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.duanc</groupId>
<artifactId>spring-mongo</artifactId>
<packaging>war</packaging>
<version>0.0.1-SNAPSHOT</version>
<name>spring-mongo Maven Webapp</name>
<url>http://maven.apache.org</url>
<build>
<finalName>spring-mongo</finalName>
<plugins>
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-compiler-plugin</artifactId>
<configuration>
<source>1.7</source>
<target>1.7</target>
</configuration>
</plugin>
<plugin>
<groupId> org.apache.maven.plugins</groupId>
<artifactId> maven-war-plugin</artifactId>
<version>2.0.1</version>
</plugin>
</plugins>
</build>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<spring.version>3.2.9.RELEASE</spring.version>
<hibernate.version>4.0.5.Final</hibernate.version>
<jackson.version>2.5.0</jackson.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.5</version>
</dependency>
<!-- spring start -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</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-context</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-web</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-test</artifactId>
<version>${spring.version}</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
</dependency>
<dependency>
<groupId>org.springframework.data</groupId>
<artifactId>spring-data-mongodb</artifactId>
<version>1.2.0.RELEASE</version>
</dependency>
<!-- spring end -->
<!-- log4j -->
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<!-- jstl -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.1.2</version>
</dependency>
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.1.41</version>
</dependency>
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.2.2</version>
</dependency>
<!--io -->
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>2.4</version>
</dependency>
<!-- <dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongodb-driver</artifactId>
<version>3.0.2</version>
</dependency> -->
<dependency>
<groupId>org.mongodb</groupId>
<artifactId>mongo-java-driver</artifactId>
<version>3.0.2</version>
</dependency>
</dependencies>
</project>
spring-mvc.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:p="http://www.springframework.org/schema/p" xmlns:context="http://www.springframework.org/schema/context"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-3.0.xsd">
<!--启用注解 -->
<context:annotation-config />
<!-- 自动扫描controller包下的所有类,使其认为spring mvc的控制器 -->
<context:component-scan base-package="org.spring.mongo" />
<mvc:annotation-driven />
<!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射 -->
<bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"> </bean>
<!-- 靜態資源訪問 -->
<mvc:resources mapping="/resources/**" location="/resources/" />
<!-- 对模型视图名称的解析,即在模型视图名称添加前后缀 -->
<bean id="jspViewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="viewClass" value="org.springframework.web.servlet.view.JstlView" />
<property name="prefix" value="/jsp/" />
<property name="suffix" value=".jsp" />
</bean>
<!-- 注解式事务 -->
<tx:annotation-driven transaction-manager="transactionManager" />
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="defaultEncoding" value="utf-8"></property>
</bean>
<import resource="classpath:/conf/spring/spring-mongo.xml"/>
</beans>
spring-mongo.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:annotation-config />
<context:component-scan base-package="org.spring.mongo" />
<context:property-placeholder location="classpath:mongodb.properties" />
<!-- 定义mongo对象,对应的是mongodb官方jar包中的Mongo,replica-set设置集群副本的ip地址和端口 -->
<mongo:mongo id="mongo" replica-set="${mongo.hostport}">
<!-- 一些连接属性的设置 -->
<!-- <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}"
socket-keep-alive="${mongo.socketKeepAlive}"
socket-timeout="${mongo.socketTimeout}"
slave-ok="${mongo.slaveOk}"
write-number="1"
write-timeout="0"
write-fsync="true" /> -->
<!-- 这里我要备注下,不知道为什么 auto-connect-retry 这个属性不管我加或者不加都会报错,所以这里我干脆不设置options了 -->
</mongo:mongo>
<mongo:db-factory dbname="database" mongo-ref="mongo" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg ref="mongo" />
<constructor-arg name="databaseName" value="${mongo.db}" />
</bean>
</beans>
mongodb.properties
mongo.hostport=127.0.0.1:27017
mongo.db=mytest
mongo.connectionsPerHost=8
mongo.threadsAllowedToBlockForConnectionMultiplier=4
mongo.connectTimeout=1000
mongo.maxWaitTime=1500
mongo.autoConnectRetry=true
mongo.socketKeepAlive=true
mongo.socketTimeout=1500
mongo.slaveOk=true
web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.0" xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd">
<display-name>Archetype Created Web Application</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring/spring-mongo.xml</param-value>
</context-param>
<!-- spring 监听 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<!-- 字符集过滤 -->
<filter>
<filter-name>encodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter>
<filter-mapping>
<filter-name>encodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- springmvc -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:conf/spring/spring-mvc.xml</param-value>
</init-param>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
</web-app>
代码
Pagination
(注:时间限制简单设计了下,可以根据自己的想法改进)
import java.util.List;
public class Pagination {
private int current = 1;// 当前页
private int length = 10;// 长度
private int skip;// 忽略个数
private int count;// 总数
private List<?> dataList;// 获取的List
public int getCurrent() {
return current;
}
public void setCurrent(int current) {
if(current > 0) {
this.current = current;
this.skip = (current - 1) * 10;
}
}
public int getLength() {
return length;
}
public void setLength(int length) {
this.length = length;
}
public int getSkip() {
return skip;
}
public void setSkip(int skip) {
this.skip = skip;
}
public List<?> getDataList() {
return dataList;
}
public void setDataList(List<?> dataList) {
this.dataList = dataList;
}
public int getCount() {
return count;
}
public void setCount(int count) {
this.count = count;
}
}
BaseDao
import java.util.List;
public interface BaseDao<T, ID> {
T findById(ID id);
List<T> findMany(T example);
Pagination findMany(T example, Pagination pagination);
void insertOne(T record);
void insertMany(List<T> records);
boolean exists(T example);
void deleteById(ID id);
void deleteByExample(T example);
void updateById(T record, ID id);
void updataByExample(T record, T example);
}
BaseDaoImpl
- initQuery
- initUpdate
这连个方法我是基于java反射,写的统一方法。可以根据传入的java对象,映射属性及值,然后组装成 Query 和 Update。通过反射来做虽然方便,但是会影响速度,而且我并没有测试所有支持的数据类型,也许有些类型会有问题,需要改进。
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import org.spring.mongo.model.Student;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;
public abstract class BaseDaoImpl {
protected Query initQuery(Student example) {
Query query = new Query();
Criteria c = new Criteria();
Field [] fields = example.getClass().getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
String methodName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length());
System.out.println(fieldName + " | " + methodName);
try {
Method method = example.getClass().getDeclaredMethod("get" + methodName);
Object obj = method.invoke(example, null);
if(obj != null) {
System.out.println(obj + " type:"+ field.getGenericType());
if(field.getGenericType().equals(String.class)) {
if(fieldName.equals("id")) {
c.and(fieldName).is(obj);
} else {
System.out.println("is a string");
c.and(fieldName).regex((String)obj);
}
} else {
c.and(fieldName).is(obj);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
query.addCriteria(c);
return query;
}
protected Update initUpdate(Object record) {
Update update = new Update();
Field [] fields = record.getClass().getDeclaredFields();
for (Field field : fields) {
String fieldName = field.getName();
String methodName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1, fieldName.length());
try {
Method method = record.getClass().getDeclaredMethod("get" + methodName);
Object obj = method.invoke(record, null);
if(obj != null) {
System.out.println("obj value = " + obj);
update.set(fieldName, obj);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return update;
}
}
Student
public class Student {
private String id;
private String name;
private String stuCode;
private Integer age;
private String sex;
private String clazzCode;
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 Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public String getStuCode() {
return stuCode;
}
public void setStuCode(String stuCode) {
this.stuCode = stuCode;
}
public String getClazzCode() {
return clazzCode;
}
public void setClazzCode(String clazzCode) {
this.clazzCode = clazzCode;
}
}
StudentDao
import org.spring.mongo.core.BaseDao;
import org.spring.mongo.model.Student;
public interface StudentDao extends BaseDao<Student, String>{
}
StudentDaoImpl
import java.util.List;
import org.spring.mongo.core.BaseDaoImpl;
import org.spring.mongo.dao.StudentDao;
import org.spring.mongo.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Repository;
import com.mongodb.WriteResult;
@Repository(value = "studentDao")
public class StudentDaoImpl extends BaseDaoImpl implements StudentDao {
private Class<Student> entityClass = Student.class;
@Autowired
@Qualifier("mongoTemplate")
private MongoTemplate mongoTemplate;
@Override
public Student findById(String id) {
return mongoTemplate.findById(id, entityClass);
}
@Override
public List<Student> findMany(Student example) {
Query query = initQuery(example);
return mongoTemplate.find(query, entityClass);
}
@Override
public Pagination findMany(Student example, Pagination pagination) {
Query query = initQuery(example);
query.skip(pagination.getSkip());
query.limit(pagination.getLength());
List<Student> list = mongoTemplate.find(query, entityClass);
pagination.setDataList(list);
return pagination;
}
@Override
public void insertOne(Student record) {
mongoTemplate.insert(record);
}
@Override
public void insertMany(List<Student> records) {
mongoTemplate.insert(records, entityClass);
}
@Override
public boolean exists(Student example) {
if(findMany(example).size() > 0) {
return true;
}
return false;
}
@Override
public void deleteById(String id) {
mongoTemplate.remove(new Query(Criteria.where("id").is(id)), entityClass);
}
@Override
public void deleteByExample(Student example) {
List<Student> list = findMany(example);
for (Student student : list) {
mongoTemplate.remove(new Query(Criteria.where("id").is(student.getId())), entityClass);
}
}
@Override
public void updateById(Student record, String id) {
WriteResult wr = mongoTemplate.updateFirst(new Query(Criteria.where("id").is(id)),
initUpdate(record), entityClass);
System.out.println(wr);
}
@Override
public void updataByExample(Student record, Student example) {
WriteResult wr = mongoTemplate.updateFirst(initQuery(example), initUpdate(record), entityClass);
System.out.println(wr);
}
}
Junit Test
BaseSpringTest
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath:conf/spring/spring-mvc.xml","classpath:conf/spring/spring-mongo.xml"})
public abstract class BaseSpringTest {
}
MongoTest
import java.util.List;
import org.junit.Test;
import org.spring.mongo.dao.StudentDao;
import org.spring.mongo.model.Student;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
public class MongoTest extends BaseSpringTest {
@Autowired
private StudentDao studentDao;
@Test
public void test() {
/*Student s = new Student();
s.setName("student");
s.setAge(25);
s.setClazzCode("1106101");
s.setSex("m");
s.setStuCode("1106101-25");
studentDao.insertOne(s);*/
/*Student s = new Student();
s.setId("55fbdfdb555cf51ef80d6813");
s.setName("admin");
s.setAge(22);
s.setSex("m");
s.setClazzCode("1106101");
List<Student> list = studentDao.findMany(s);
for (Student student : list) {
System.out.println(student.getId() + " " + student.getStuCode() + " " + student.getName() + " " + student.getAge());
}
System.out.println("=================================");
System.out.println(studentDao.exists(s));
System.out.println("=================================");
Student record = new Student();
record.setName("system");
record.setAge(30);
studentDao.updateById(record, "55fbdfdb555cf51ef80d6813");*/
/*Student s = studentDao.findById("55fbdfdb555cf51ef80d6813");
System.out.println(s.getId() + " " + s.getStuCode() + " " + s.getName() + " " + s.getAge());*/
/*studentDao.deleteById("55fbdfdb555cf51ef80d6813");*/
Pagination pagination = new Pagination();
Student example = new Student();
example.setName("student");
List<Student> list = (List<Student>)studentDao.findMany(example, pagination).getDataList();
for (Student student : list) {
System.out.println(student.getId() + " " + student.getStuCode() + " " + student.getName() + " " + student.getAge());
}
}
}
基本都是代码,实在不知道该讲什么……代码有看不懂的地方可以问我。有大神指点更好!