公司对于mongodb的使用

来源:互联网 发布:星辰劫java内购破解版 编辑:程序博客网 时间:2024/06/05 10:35

1.pom文件添加对mongodb的倚赖

复制代码
<dependency>        <groupId>org.mongodb</groupId>        <artifactId>mongo-java-driver</artifactId>        <version>3.2.2</version>    </dependency>    <dependency>        <groupId>org.springframework.data</groupId>        <artifactId>spring-data-mongodb</artifactId>        <version>${data.mongodb}</version>    </dependency>        <dependency>        <groupId>org.springframework.data</groupId>        <artifactId>spring-data-mongodb-cross-store</artifactId>        <version>${data.mongodb}</version>    </dependency>    <dependency>       <groupId>org.springframework.data</groupId>       <artifactId>spring-data-mongodb-log4j</artifactId>       <version>${data.mongodb}</version>    </dependency>
复制代码

2.applicationContext.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"    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">        <!-- 扫描 -->    <context:component-scan base-package="cn.com.xxx.mongodb"/>        <!-- 引入mongodb的相关配置 -->    <import resource="classpath:spring-mongodb.xml"/>    </beans>
复制代码

4.mongodb.properties

复制代码
#数据库名称mongo.dbname = test#用户名mongo.username = rootmongo.credentials=root:000000@test#密码mongo.password = 000000#主机mongo.host = 127.0.0.1#端口号mongo.port= 27017#一个线程变为可用的最大阻塞数mongo.connectionsPerHost= 8#线程队列数,它以上面connectionsPerHost值相乘的结果就是线程队列最大值mongo.threadsAllowedToBlockForConnectionMultiplier= 4#连接超时时间(毫秒)mongo.connectTimeout= 1500#最大等待时间mongo.maxWaitTime= 1500#自动重连mongo.autoConnectRetry= true#scoket保持活动mongo.socketKeepAlive= true#scoket超时时间mongo.socketTimeout=1500#读写分离mongo.slaveOk=true
复制代码

 

3.spring-mongodb.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"       xmlns:aop="http://www.springframework.org/schema/aop"       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.xsd          http://www.springframework.org/schema/aop           http://www.springframework.org/schema/aop/spring-aop-3.0.xsd            http://www.springframework.org/schema/beans             http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">    <!-- 加载mongodb的属性配置文件 -->    <context:property-placeholder location="classpath:mongodb.properties" />    <!-- 定义mongo对象,对应的是mongodb官方jar包中的Mongo,replica-set设置集群副本的ip地址和端口 --><!--         <mongo:mongo id="mongo" host="${mongo.host}" port="${mongo.port}" >        <mongo:client-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="1"         write-timeout="0"         write-fsync="true"/>     </mongo:mongo>     -->  <!-- 我们使用的mongodb的版本是3.X,所以在构造这段话的时候要根据 Mongo  类的构造函数来构造,不同版本可能会造成构造函数的不同-->    <mongo:mongo-client id="mongo" host="${mongo.host}" port="${mongo.port}" credentials="${mongo.credentials}">            <mongo:client-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}"               />     </mongo:mongo-client>    <!-- 用户验证 -->    <bean id="userCredentials" class="org.springframework.data.authentication.UserCredentials">        <constructor-arg name="username" value="${mongo.username}" />        <constructor-arg name="password" value="${mongo.password}" />    </bean>    <!-- mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 -->    <bean id="mongoDbFactory"        class="org.springframework.data.mongodb.core.SimpleMongoDbFactory">        <constructor-arg ref="mongo" />        <constructor-arg value="${mongo.dbname}" />        <!-- <constructor-arg ref="userCredentials" /> -->    </bean>    <bean id="mappingContext"        class="org.springframework.data.mongodb.core.mapping.MongoMappingContext" />    <bean id="defaultMongoTypeMapper"        class="org.springframework.data.mongodb.core.convert.DefaultMongoTypeMapper">        <constructor-arg name="typeKey">            <null />        </constructor-arg>    </bean>    <!-- collection的映射 -->    <bean id="mappingMongoConverter"        class="org.springframework.data.mongodb.core.convert.MappingMongoConverter">        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />        <constructor-arg name="mappingContext" ref="mappingContext" />        <property name="typeMapper" ref="defaultMongoTypeMapper" />    </bean>    <!-- mongodb的主要操作对象,所有对mongodb的增删改查的操作都是通过它完成 -->    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">        <constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />        <constructor-arg name="mongoConverter" ref="mappingMongoConverter" />    </bean>    <bean id="audience" class="cn.com.xxx.mongodb.aop.Audience"/>    <aop:config proxy-target-class="true">        <aop:aspect ref="audience">            <aop:pointcut id="performance" expression="execution(* cn.com.mongodb.service.impl.*.*(..))"/>                        <aop:before pointcut-ref="performance" method="takeSeats"/>            <aop:before pointcut-ref="performance" method="turnOffCellPhones"/>            <aop:around pointcut-ref="performance" method="around"/>            <aop:after-returning pointcut-ref="performance" method="applaud"/>            <aop:after-throwing pointcut-ref="performance" method="demandRefund"/>            <aop:after pointcut-ref="performance" method="after"/>        </aop:aspect>    </aop:config></beans>
复制代码

5.为了使javabean对象与mongodb对象相互转化,本人借鉴别人的例子,稍加改动, 主要是应对数据库表字段的命名是含 _ 的这种方式,首先需要约定在生成java pojo的时候,每个字段上面要加上@Field注解(方便利用反射来让两者之间相互转换)

复制代码
@Document(collection="item_info")public class ItemInfo implements Serializable {    private static final long serialVersionUID = 1L;    private Oid _id;    @Field(value="item_id")    private String itemId;    @Field(value="item_name")    private String itemName;    @Field(value="price")    private Double price;    @Field(value="desc")    private String desc;    public Oid get_id() {        return _id;    }    public void set_id(Oid _id) {        this._id = _id;    }    public String getItemId() {        return itemId;    }    public void setItemId(String itemId) {        this.itemId = itemId;    }    public String getItemName() {        return itemName;    }    public void setItemName(String itemName) {        this.itemName = itemName;    }    public Double getPrice() {        return price;    }    public void setPrice(Double price) {        this.price = price;    }    public String getDesc() {        return desc;    }    public void setDesc(String desc) {        this.desc = desc;    }    @Override    public String toString() {        return "ItemInfo [_id=" + _id + ", itemId=" + itemId + ", itemName="                + itemName + ", price=" + price + ", desc=" + desc + "]";    }
复制代码

实现java对象与DBObject对象之间的相互转化

复制代码
public class BeanUtil {      /**       * 把实体bean对象转换成DBObject       * @param bean       * @return       * @throws IllegalArgumentException       * @throws IllegalAccessException       */      public static <T> DBObject bean2DBObject(T bean) throws IllegalArgumentException,          IllegalAccessException {        if (bean == null) {          return null;        }        DBObject dbObject = new BasicDBObject();        // 获取对象对应类中的所有属性域        Field[] fields = bean.getClass().getDeclaredFields();                // 获取所有注解        for (Field field : fields) {            org.springframework.data.mongodb.core.mapping.Field anno = field.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);          // 获取属性名          String varName = field.getName();                    if("serialVersionUID".equals(varName) || "_id".equals(varName)){              continue;          }                    // 获取注解的值          varName = anno.value();          // 修改访问控制权限          boolean accessFlag = field.isAccessible();          if (!accessFlag) {            field.setAccessible(true);          }          Object param = field.get(bean);          if (param == null) {            continue;          } else if (param instanceof Integer) {//判断变量的类型            int value = ((Integer) param).intValue();            dbObject.put(varName, value);          } else if (param instanceof String) {            String value = (String) param;            dbObject.put(varName, value);          } else if (param instanceof Double) {            double value = ((Double) param).doubleValue();            dbObject.put(varName, value);          } else if (param instanceof Float) {            float value = ((Float) param).floatValue();            dbObject.put(varName, value);          } else if (param instanceof Long) {            long value = ((Long) param).longValue();            dbObject.put(varName, value);          } else if (param instanceof Boolean) {            boolean value = ((Boolean) param).booleanValue();            dbObject.put(varName, value);          } else if (param instanceof Date) {            Date value = (Date) param;            dbObject.put(varName, value);          }          // 恢复访问控制权限          field.setAccessible(accessFlag);        }                return dbObject;      }      /**       * 把DBObject转换成bean对象       * @param dbObject       * @param bean       * @return       * @throws IllegalAccessException       * @throws InvocationTargetException       * @throws NoSuchMethodException       */      public static <T> T dbObject2Bean(DBObject dbObject, T bean) throws IllegalAccessException,          InvocationTargetException, NoSuchMethodException {        if (bean == null) {          return null;        }        Field[] fields = bean.getClass().getDeclaredFields();        for (Field field : fields) {          String varName = field.getName();          org.springframework.data.mongodb.core.mapping.Field anno = field.getAnnotation(org.springframework.data.mongodb.core.mapping.Field.class);          if("serialVersionUID".equals(varName) || "_id".equals(varName)){              continue;          }                    String fieldName = anno.value();          Object object = dbObject.get(fieldName);          if (object != null) {            BeanUtils.setProperty(bean, varName, object);          }        }        return bean;      }}
复制代码

好了,准备工作就做好了

相应的Service与实现方法

复制代码
public interface ItemInfoService {    // 查询    public List<ItemInfo> getItemInfo(JSONObject json) throws Exception;        // 保存    public int save(ItemInfo itemInfo) throws Exception;        // 更新    public void update(ItemInfo intemInfo) throws Exception;}
复制代码
复制代码
@Service(value="itemInfoService")public class ItemInfoServiceImpl implements ItemInfoService {    @Autowired    private MongoTemplate mongoTemplate;    private final static String COLLECTION_NAME = "item_info";         @Override    @SuppressWarnings("static-access")    public List<ItemInfo> getItemInfo(JSONObject json) throws Exception{        List<ItemInfo> list = new ArrayList<ItemInfo>();        // 判断查询的json中传递过来的参数        DBObject query = new BasicDBObject();        // item_id,item_name,price,desc        if(json.has("item_id")){                        query.put("item_id", json.getString("item_id"));        }else if(json.has("item_name")){            query.put("item_name", json.getString("item_name"));        }                DBCursor results = mongoTemplate.getCollection("item_info").find(query);        if(null != results){            Iterator<DBObject> iterator = results.iterator();            while(iterator.hasNext()){                //Document doc = (Document) iterator.next();                BasicDBObject obj = (BasicDBObject) iterator.next();                //System.out.println(obj.toJson());                // json 字符串                String objStr = obj.toString();                //JSONObject itemInfoJson = new JSONObject().fromObject(objStr);                //itemInfoJson.put("_id", itemInfoJson.getJSONObject("_id").getString("$oid"));                ItemInfo itemInfo = new ItemInfo();                itemInfo = BeanUtil.dbObject2Bean(obj, itemInfo);                list.add(itemInfo);            }        }                        return list;    }    @Override    public int save(ItemInfo itemInfo) throws Exception {        itemInfo.setDesc("1111");        itemInfo.setItemId("i1234567890123");        itemInfo.setItemName("item_name_xx");        itemInfo.setPrice(110.0);                DBCollection collection = this.mongoTemplate.getCollection("item_info");        int result = 0;        DBObject iteminfoObj = BeanUtil.bean2DBObject(itemInfo);                //iteminfoObj.removeField("serialVersionUID");        //result = collection.insert(iteminfoObj).getN();        WriteResult writeResult = collection.save(iteminfoObj);        result = writeResult.getN();        return result;    }    @Override    public void update(ItemInfo intemInfo) throws Exception {                DBCollection collection = this.mongoTemplate.getCollection(COLLECTION_NAME);        ItemInfo queryItemInfo = new ItemInfo();        queryItemInfo.setItemId(intemInfo.getItemId());        DBObject itemInfoObj = BeanUtil.bean2DBObject(intemInfo);        DBObject query =  BeanUtil.bean2DBObject(queryItemInfo);        collection.update(query, itemInfoObj);    }    }
复制代码

junit test

复制代码
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations="classpath:applicationContext.xml")public class ItemInfoServiceTest {    @Autowired    private ItemInfoService itemInfoService;        @Ignore    @Test    public void testSave(){        ItemInfo itemInfo = new ItemInfo();        try {            this.itemInfoService.save(itemInfo);        } catch (Exception e) {            e.printStackTrace();        }    }        @Ignore    @Test    public void testGetItemInfo(){        List<ItemInfo> list = new ArrayList<ItemInfo>();        JSONObject json = new JSONObject();        //json.put("item_id", "47a09d51-bf24-442b-9076-4701dcb614b9");        json.put("item_id", "i1234567890123");        try {            list = this.itemInfoService.getItemInfo(json);            if(null != list && list.size() > 0){                //System.out.println(list.get(0).toString());                for (ItemInfo itemInfo : list) {                    //itemInfo.setItemName("======");                    this.itemInfoService.getItemInfo(json);                }            }            System.out.println(1 / 0);        } catch (Exception e) {            e.printStackTrace();        }    }        @Test    public void testUpdate(){        JSONObject json = new JSONObject();        //json.put("item_id", "47a09d51-bf24-442b-9076-4701dcb614b9");        json.put("item_id", "i1234567890123");        List<ItemInfo> list = new ArrayList<ItemInfo>();        try {            list = this.itemInfoService.getItemInfo(json);                        if(null != list && list.size() > 0){                for (ItemInfo itemInfo : list) {                                    }            }        } catch (Exception e) {            e.printStackTrace();        }    }}
三:附加说明(具体的一些配置的值)
spring中配置MongoDB有两种方式:注解方式和配置文件方式

1、注解方式

配置类要继承AbstractMongoConfiguration类,重写mongo()和mongoTemplate()方法

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
import org.springframework.data.document.mongodb.MongoTemplate;  
import org.springframework.data.document.mongodb.config.AbstractMongoConfiguration;  
import com.mongodb.Mongo;  
/** 
* Spring MongoDB configuration file 
*/  
@Configuration  
public class SpringMongoConfig extends AbstractMongoConfiguration {  
    @Override  
    public @Bean Mongo mongo() throws Exception {  
        return new Mongo("localhost");  
    }  
    @Override  
    public @Bean MongoTemplate mongoTemplate() throws Exception {  
        return new MongoTemplate(mongo(),"mydbname","myCollection");  
    }  
}  
调用Spring Mongo配置,只需要在需要使用的类中调用AnnotationConfigApplicationContext,传入刚才配置好的SpringMongoConfig类即可。


ApplicationContext ac = new AnnotationConfigApplicationContext(SpringMongoConfig.class);  
MongoOperations mo = (MongoOperations)ac.getBean("mongoTemplate");  
至此便可对MongoDB进行操作了


2、配置文件的方式

<?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:mongo="http://www.springframework.org/schema/data/mongo"  
    xsi:schemaLocation=
        "http://www.springframework.org/schema/data/mongo  
        http://www.springframework.org/schema/data/mongo/spring-mongo.xsd  
        http://www.springframework.org/schema/beans  
        http://www.springframework.org/schema/beans/spring-beans.xsd">  
      
    <!-- 定义mongo对象,对应的是mongodb官方jar包中的Mongo,replica-set设置集群副本的ip地址和端口 -->  
    <mongo:mongo id="mongo" replica-set="IP:端口号">  
        <!-- 一些连接属性的设置 -->      
        <mongo:options  
             connections-per-host="最大连接数"  
             threads-allowed-to-block-for-connection-multiplier="最大阻塞线程数"  
             max-wait-time="最大等待时间"  
             connect-timeout="连接超时时间"
             socket-keep-alive="是否保持长连接" 
         />          
    </mongo:mongo>  
  
    <!-- mongo的工厂,通过它来取得mongo实例,dbname为mongodb的数据库名,没有的话会自动创建 -->  
    <mongo:db-factory dbname="mongo中数据名称" mongo-ref="mongo"/>  
  
    <!-- mongodb的主要操作对象,所有对mongodb的增删改查的操作都是通过它完成 -->  
    <bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">  
      <constructor-arg name="mongoDbFactory" ref="mongoDbFactory"/>  
    </bean>  
      
    <!-- 映射转换器,扫描base-package目录下的文件,根据注释,把它们作为mongodb的一个collection的映射 -->  
    <mongo:mapping-converter base-package="collection映射所在包名" />  
      
    <!-- mongodb bean的仓库目录,会自动扫描扩展了MongoRepository接口的接口进行注入 -->  
    <mongo:repositories base-package="Repository所在包名"/>  
  
</beans>  


补充各个参数说明:

#对mongo实例来说,每个host允许链接的最大链接数,这些链接空闲时会放入池中,如果链接被耗尽,任何请求链接的操作会被阻塞等待链接可用,推荐配置10
connectionsPerHost=10
#当链接空闲时,空闲线程池中最大链接数
minPoolsSize=5
#此参数跟connectionsPerHost的乘机为一个线程变为可用的最大阻塞数,超过此乘机数之后的所有线程将及时获取一个异常.eg.connectionsPerHost=10 and threadsAllowedToBlockForConnectionMultiplier=5,最多50个线程等级一个链接,推荐配置为5
threadsAllowedToBlockForConnectionMultiplier=5
#一个线程等待链接可用的最大等待毫秒数,0表示不等待,负数表示等待时间不确定,推荐配置120000
maxWaitTime=120000
#链接超时的毫秒数,0表示不超时,此参数只用在新建一个新链接时,推荐配置10,000.
connectTimeout=10000
#此参数表示socket I/O读写超时时间,推荐为不超时,即 0    Socket.setSoTimeout(int)
socketTimeout=0
#该标志用于控制socket保持活动的功能,通过防火墙保持连接活着
socketKeepAlive=false
#true:假如链接不能建立时,驱动将重试相同的server,有最大的重试次数,默认为15次,这样可以避免一些server因为一些阻塞操作零时down而驱动抛出异常,这个对平滑过度到一个新的master,也是很有用的,注意:当集群为复制集时,驱动将在这段时间里,尝试链接到旧的master上,而不会马上链接到新master上
#false 当在进行socket读写时,不会阻止异常抛出,驱动已经有自动重建破坏链接和重试读操作. 推荐配置false
autoConnectRetry=false
#重新打开链接到相同server的最大毫秒数,推荐配置为0,如果 autoConnectRetry=true,表示时间为15s
#com.jd.mongodbclient2.mongo.JDClientMongo.maxAutoConnectRetryTime=false
#表示当没有手动关闭游标时,是否有一个自动释放游标对象的方法,如果你总是很小心的关闭游标,则可以将其设为false 推荐配置true

#com.jd.mongodbclient2.mongo.JDClientMongo.cursorFinalizerEnabled=true

#安全模式

com.jd.mongodbclient2.driver.MongoDBDriver.safe=true

#为true表示读写分离

com.jd.mongodbclient2.driver.MongoDBDriver.slaveOk=false

原创粉丝点击