MongoDB学习日记 - Spring框架集成 : spring-data-mongodb

来源:互联网 时间:1970-01-01


一直想写这部分,但是由于水平太差了,一直没敢写;今天就献丑把自己的实践写一下,自己以后实际开发也可以回头看看。这里贴的代码都是自己测试真实的代码。下载地址:百度云分享(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=mytestmongo.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()); } }}

基本都是代码,实在不知道该讲什么……代码有看不懂的地方可以问我。有大神指点更好!



相关阅读:
Top