热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

SpringData,MongoDB和JSF集成教程

示例应用程序简介(MongoShop产品目录)在学习完本教程之后,将构建具有以下功能要求的示例应用程序(MongoShop产

示例应用程序简介(MongoShop产品目录)

在学习完本教程之后,将构建具有以下功能要求的示例应用程序(MongoShop产品目录):

1.搜索具有不同条件的产品(例如,sku,产品类型,标题,stc)

2.创建具有不同类别的新产品。

3.编辑选定的产品详细信息

4.从查询屏幕删除选定的产品。

表示层:

JSF在此示例应用程序中用作表示层技术。 PrimeFaces是用于增强JSF UI的轻量级组件之一。 前端交互由该层中的JSF支持bean控制。

服务层:

使用Spring管理的单例服务对象。 业务服务和应用程序逻辑编写在此层中

数据层:

使用Spring数据MongoDB组件。 它提供了与MongoDB面向文档的数据库的集成。 它提供了MongoTemplate,以便可以轻松执行MongoDB操作。 而且,Spring存储库样式数据访问层可以使用Spring数据MongoDB轻松编写。

MongoDB模式设计和数据准备

MongoDB简介

MongoDB是一个开源可扩展的高性能NoSQL数据库。 它是一个面向文档的存储。 它可以存储具有动态模式的JSON样式的文档。 在此应用程序中,每个产品都以JSON样式的文档存储在MongoDB中。

MongoDB中的架构设计

目录中的每个产品均包含常规产品信息(例如,sku,标题和产品类型),价格详细信息(例如,零售价格和标价)和产品子详细信息(例如,音频CD的曲目/书籍的章节)。 在此应用程序中,使用MongoDB。 模式设计将更侧重于数据使用。 它与传统的RDBMS模式设计不同。 MongoDB中的架构设计应为:

样本数据:

x= {sku: '1000001',type: 'Audio Album',title: 'A Love Supreme',description: 'by John Coltrane',publisher: 'Sony Music',pricing: {list: 1200,retail: 1100},details: {title: 'A Love Supreme [Original Recording Reissued]',artist: 'John Coltrane',genre: 'Jazz' ,tracks: ['A Love Supreme Part I: Acknowledgement','A Love Supreme Part II - Resolution','A Love Supreme, Part III: Pursuance','A Love Supreme, Part IV-Psalm'],}
}y= {sku: '1000002',type: 'Audio Album',title: 'Love Song',description: 'by Khali Fong',publisher: 'Sony Music',pricing: {list: 1000,retail: 1200},details: {title: 'Long Song [Original Recording Reissued]',artist: 'Khali Fong',genre: 'R&B',tracks: ['Love Song','Spring Wind Blow','Red Bean','SingAlongSong'],}
}z= {sku: '1000003',type: 'Book',title: 'Node.js for PHP Developers',description: 'by Owen Peter',publisher: 'OReilly Media',pricing: {list: 2500,retail: 2100},details: {title: 'Node.js for PHP Developers',author: 'Mark Owen',genre: 'Technology',chapters: ['Introduction to Node','Server-side JS','PHP API','Example'],}
}

示例查询以添加数据:

db.product.save(x);
db.product.save(y);
db.product.save(z);

示例查询以测试示例数据:

db.product.find({'sku':'1000004'});
db.product.find({'type':'Audio Album'});
db.product.find({'type':'Audio Album', 'details.genre': 'Jazz'});

JSF(PrimeFaces)和Spring数据MongoDB集成

项目的pom.xml

4.0.0com.borislammongoShopwar1.0-SNAPSHOTMongoShop Webapphttp://maven.apache.orgorg.jboss.elcom.springsource.org.jboss.el2.0.0.GA org.primefaces.themes all-themes 1.0.9 org.primefaces primefaces 3.4.2 commons-beanutilscommons-beanutils1.8.3 commons-codeccommons-codec1.3 org.apache.directory.studioorg.apache.commons.lang2.6commons-digestercommons-digester1.8commons-collectionscommons-collections3.2org.apache.myfaces.coremyfaces-api2.1.9org.apache.myfaces.coremyfaces-impl2.1.9org.mongodbmongo-java-driver2.10.1junitjunit3.8.1testorg.springframework.dataspring-data-mongodb1.0.3.RELEASE org.springframeworkspring-context3.2.0.RELEASE org.springframeworkspring-web3.2.0.RELEASEjava.nethttps://maven.java.net/content/repositories/public/ prime-repo PrimeFaces Maven Repository http://repository.primefaces.org default com.springsource.repository.bundles.releaseSpringSource Enterprise Bundle Repository - SpringSource Releaseshttp://repository.springsource.com/maven/bundles/releasecom.springsource.repository.bundles.externalSpringSource Enterprise Bundle Repository - External Releaseshttp://repository.springsource.com/maven/bundles/externalfalsetrueapache.snapshotsApache Snapshot Repositoryhttps://repository.apache.org/content/repositories/snapshots jboss-deprecated-repositoryJBoss Deprecated Maven Repositoryhttps://repository.jboss.org/nexus/content/repositories/deprecated/defaulttrueneverfalsenevermongoShop

我的脸

MyFaces用作此应用程序中的JSF实现。 以下详细信息应添加到web.xml中

PrimeFaces主题

如前所述,PrimeFaces库用于增强UI。 该库几乎不需要配置。 PrimeFaces为您的Web应用程序提供了许多预先设计的主题。 在本例中,我们使用“蓝天”主题。 我们只是在web.xml中添加以下设置

primefaces.THEMEglass-x

JSF和Spring集成:

要将JSF与Spring集成,必须在Faces-config.xml中指定SpringBeanFacesELResolver

Faces-config.xml


org.springframework.web.jsf.el.SpringBeanFacesELResolverorg.primefaces.context.PrimePartialViewContextFactory

完整的web.xml


contextConfigLocationWEB-INF/spring-application-context.xmlerrorPageUrl/pages/systemError.dofacelets.DEVELOPMENTfalsefacelets.REFRESH_PERIOD2javax.faces.STATE_SAVING_METHODclientjavax.servlet.jsp.jstl.fmt.localizationContextresources.applicationorg.apache.myfaces.ALLOW_Javascripttrueorg.apache.myfaces.AUTO_SCROLLfalseorg.apache.myfaces.DETECT_Javascriptfalseorg.apache.myfaces.ERROR_HANDLINGfalseorg.apache.myfaces.EXPRESSION_FACTORYorg.jboss.el.ExpressionFactoryImplorg.apache.myfaces.PRETTY_HTMLfalseprimefaces.THEMEglass-x Faces Servletorg.apache.myfaces.webapp.MyFacesServlet1Faces Servlet*.jsforg.apache.myfaces.webapp.StartupServletContextListenerorg.springframework.web.context.ContextLoaderListener

MongoDB连接详细信息

为了连接到MongoDB,您必须以XML注册MongoDbFactory实例。 连接详细信息在spring-application-context.xml中指定

spring-application-context.xml


xmlns:context='http://www.springframework.org/schema/context'xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'xmlns:util='http://www.springframework.org/schema/util'xmlns:mongo='http://www.springframework.org/schema/data/mongo'xsi:schemaLocation='http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsdhttp://www.springframework.org/schema/data/mongohttp://www.springframework.org/schema/data/mongo/spring-mongo.xsd http://www.springframework.org/schema/data/repositoryhttp://www.springframework.org/schema/data/repository/spring-repository.xsd http://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context-3.2.xsdhttp://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-3.2.xsd'>

使用Spring Data Repository和MongoTemplate来查询数据

Spring资料储存库:

Spring数据存储库抽象减少了用于编写应用程序数据访问层的样板代码。 Repository接口的自动实现提供了对mongoDB的简单操作。 它有助于我们的产品保存和删除功能,使

MongoTemplate:

MongoTemplate提供了方便的操作来创建,更新,删除和查询MongoDB文档,并提供了域对象和MongoDB文档之间的映射。 在我们的应用程序中,由于spring数据存储库无法满足搜索功能的要求,因此我们使用MongoTemplate来归档搜索功能。

自定义Spring数据存储库:

由于无法通过Spring数据存储库抽象轻松地实现产品搜索,因此我们想使用MongoDBTemplate实现多级Criteira产品搜索。 为了使用MongoTemplate丰富Spring数据存储库,我们可以执行以下操作来定制存储库:

ProductRepository.java

package com.borislam.repository;import java.util.List;
import org.springframework.data.repository.PagingAndSortingRepository;
import com.borislam.domain.Product;public interface ProductRepository extends PagingAndSortingRepository , ProductRepostitoryCustom{List findByType(String type);List findByTypeAndTitle(String type, String title); Product findBySku(String sku);
}

ProductRepositoryCustom.java

package com.borislam.repository;import java.util.List;
import com.borislam.domain.Product;
import com.borislam.view.ProductSearchCriteria;public interface ProductRepostitoryCustom {public List searchByCriteria(ProductSearchCriteria criteria);}

ProductRepositoryImpl.java

package com.borislam.repository.impl;import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
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.util.StringUtils;
import com.borislam.domain.Product;
import com.borislam.repository.ProductRepostitoryCustom;
import com.borislam.view.ProductSearchCriteria;public class ProductRepositoryImpl implements ProductRepostitoryCustom{@Autowiredprivate MongoTemplate mongoTemplate;@Overridepublic List searchByCriteria(ProductSearchCriteria criteria) {Query query = new Query();if ( StringUtils.hasText(criteria.getSku())) { Criteria c = Criteria.where('sku').is(criteria.getSku());query.addCriteria(c);}if (StringUtils.hasText(criteria.getTitle())) {Criteria c = Criteria.where('title').regex('.*' + criteria.getTitle() + '.*', 'i');query.addCriteria(c);}if (StringUtils.hasText(criteria.getDescription())) {Criteria c = Criteria.where('description').regex('.*' + criteria.getDescription() + '.*', 'i');query.addCriteria(c);}if (StringUtils.hasText(criteria.getProductType())) {Criteria c = Criteria.where('type').is(criteria.getProductType());query.addCriteria(c);} if (StringUtils.hasText(criteria.getTrack())) {Criteria c = Criteria.where('details.tracks').regex('.*' + criteria.getTrack() + '.*', 'i');query.addCriteria(c);}if (StringUtils.hasText(criteria.getChapter())) {Criteria c = Criteria.where('details.chapters').regex('.*' + criteria.getChapter() + '.*', 'i');query.addCriteria(c);}return mongoTemplate.find(query, Product.class);}}

数据模型:Product.java

package com.borislam.domain;public class Product {private String id;private String sku ;private String type;private String title;private String description;private String publisher;private Pricing pricing;private Detail details;public String getId() {return id;}public void setId(String id) {this.id = id;}public String getSku() {return sku;}public void setSku(String sku) {this.sku = sku;}public String getType() {return type;}public void setType(String type) {this.type = type;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getPublisher() {return publisher;}public void setPublisher(String publisher) {this.publisher = publisher;}public Pricing getPricing() {return pricing;}public void setPricing(Pricing pricing) {this.pricing = pricing;}public Detail getDetails() {return details;}public void setDetails(Detail details) {this.details = details;}
}

Pricing.java

package com.borislam.domain;public class Pricing {private String id;private double list;private double retail;public String getId() {return id;}public void setId(String id) {this.id = id;}public double getList() {return list;}public void setList(double list) {this.list = list;}public double getRetail() {return retail;}public void setRetail(double retail) {this.retail = retail;}public Pricing(double list, double retail) {super();this.list = list;this.retail = retail;}}

Detail.java

package com.borislam.domain;import java.util.List;public class Detail {private String id;private String title;private String author;private String artist;private String genre;private List pic;private List chapters;private List tracks;public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getAuthor() {return author;}public void setAuthor(String author) {this.author = author;}public String getGenre() {return genre;}public void setGenre(String genre) {this.genre = genre;}public List getPic() {return pic;}public void setPic(List pic) {this.pic = pic;}public List getChapters() {return chapters;}public void setChapters(List chapters) {this.chapters = chapters;}public String getId() {return id;}public void setId(String id) {this.id = id;}public String getArtist() {return artist;}public void setArtist(String artist) {this.artist = artist;}public List getTracks() {return tracks;}public void setTracks(List tracks) {this.tracks = tracks;}}

JSF部分:common.xhtml










...




Search.xhml

Product Search



ProductSearchCriteria.java

package com.borislam.view;public class ProductSearchCriteria {private String sku;private String description;private String productType;private String track;private String chapter;private String title;public String getSku() {return sku;}public void setSku(String sku) {this.sku = sku;}public String getDescription() {return description;}public void setDescription(String description) {this.description = description;}public String getProductType() {return productType;}public void setProductType(String productType) {this.productType = productType;}public String getTrack() {return track;}public void setTrack(String track) {this.track = track;}public String getTitle() {return title;}public void setTitle(String title) {this.title = title;}public String getChapter() {return chapter;}public void setChapter(String chapter) {this.chapter = chapter;}}

ProductSearchBean.java

package com.borislam.view;import java.util.List;
import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
import com.borislam.domain.Product;
import com.borislam.service.ProductService;@Component
@Scope('session')
public class ProductSearchBean {private Product selectedProduct;private ProductSearchCriteria criteria = new ProductSearchCriteria();private List productList;public Product getSelectedProduct() {return selectedProduct;}public void setSelectedProduct(Product selectedProduct) {this.selectedProduct = selectedProduct;}public List getProductList() {return productList;}public void setProductList(List productList) {this.productList = productList;}public ProductSearchCriteria getCriteria() {return criteria;}public void setCriteria(ProductSearchCriteria criteria) {this.criteria = criteria;}@Autowiredprivate ProductService productService;public void doSearch(ActionEvent event){productList= productService.searchByCriteria(criteria);}
}

服务层:ProductService.java

package com.borislam.service;import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.borislam.domain.Product;
import com.borislam.repository.ProductRepository;
import com.borislam.view.ProductSearchCriteria;@Service
public class ProductService {@Autowiredprivate ProductRepository productRepository;public List searchByCriteria(ProductSearchCriteria criteria){return productRepository.searchByCriteria(criteria);}public Product getProduct(String sku) {return productRepository.findBySku(sku);}
}

使用Spring数据存储库创建,编辑和删除数据

在本教程的最后一部分,我们将向MongoShop产品目录应用程序添加创建,编辑和删除功能。 搜索页面已修改。 在实际删除产品之前,已添加模式确认对话框

更新了search.xhtml

Product Search



更新了ProductSearchBean.java

package com.borislam.view;import java.util.List;import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Component;
import com.borislam.domain.Product;
import com.borislam.service.ProductService;@Component
@Scope('session')
public class ProductSearchBean {private Product selectedProduct;private ProductSearchCriteria criteria = new ProductSearchCriteria();private List productList;public Product getSelectedProduct() {return selectedProduct;}public void setSelectedProduct(Product selectedProduct) {this.selectedProduct = selectedProduct;}public List getProductList() {return productList;}public void setProductList(List productList) {this.productList = productList;}public ProductSearchCriteria getCriteria() {return criteria;}public void setCriteria(ProductSearchCriteria criteria) {this.criteria = criteria;}@Autowiredprivate ProductService productService;public void doSearch(ActionEvent event){productList= productService.searchByCriteria(criteria);}public String doEditDetail() {(FacesContext.getCurrentInstance().getExternalContext().getFlash()).put('selected', selectedProduct);return 'detail.xhtml';}public void doDelete(ActionEvent event){try { productService.deleteProduct(selectedProduct);FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(null, new FacesMessage('Delete Successfully!'));}catch (DataAccessException e ) {FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,'Error when deleting product!',null));}}
}

添加了产品详细信息页面以查看产品详细信息。 产品的创建和版本在产品详细信息页面中完成。

detail.xhtml

Product Details 0}'> #{track} 0}'> #{chapter}

ProductDetailsBean.java

package com.borislam.view;import java.util.ArrayList;
import java.util.List;import javax.faces.application.FacesMessage;
import javax.faces.context.FacesContext;
import javax.faces.event.ActionEvent;
import javax.faces.event.ValueChangeEvent;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import org.springframework.dao.DataAccessException;import com.borislam.domain.Detail;
import com.borislam.domain.Pricing;
import com.borislam.domain.Product;
import com.borislam.service.ProductService;@Component
@Scope('session')
public class ProductDetailBean {@Autowiredprivate ProductService productService;private boolean newProduct;private Product product;private String newTrack;private String newChapter;public boolean isNewProduct() {return newProduct;}public void setNewProduct(boolean newProduct) {this.newProduct = newProduct;}public Product getProduct() {return product;}public void setProduct(Product product) {this.product = product;}public String getNewTrack() {return newTrack;}public void setNewTrack(String newTrack) {this.newTrack = newTrack;}public String getNewChapter() {return newChapter;}public void setNewChapter(String newChapter) {this.newChapter = newChapter;}public void initProduct(){Object selectedProduct = (FacesContext.getCurrentInstance().getExternalContext().getFlash()).get('selected');if (selectedProduct==null && !FacesContext.getCurrentInstance().isPostback()) {product = new Product();product.setDetails(new Detail());product.setPricing(new Pricing(0,0));setNewProduct(true);}if (selectedProduct!=null) {product = (Product)selectedProduct;setNewProduct(false);}}public void doSave(ActionEvent event) {try {productService.saveProduct(product);FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(null, new FacesMessage('Save Successfully!'));}catch (DataAccessException e){ e.printStackTrace();FacesContext context = FacesContext.getCurrentInstance(); context.addMessage(null, new FacesMessage(FacesMessage.SEVERITY_ERROR,'Error when saving product!',null));}}public void doAddTracks(ActionEvent event) {List tracks = product.getDetails().getTracks();if (CollectionUtils.isEmpty(tracks)) {product.getDetails().setTracks(new ArrayList());}product.getDetails().getTracks().add(this.newTrack);}public void doAddChapters(ActionEvent event) {List tracks = product.getDetails().getChapters();if (CollectionUtils.isEmpty(tracks)) {product.getDetails().setChapters(new ArrayList() );}product.getDetails().getChapters().add(this.newChapter);}public void clearDetails(ValueChangeEvent event) {if ('Audio Album'.equalsIgnoreCase(event.getNewValue().toString()) ) {product.getDetails().setChapters(null);}if ('Book'.equalsIgnoreCase( event.getNewValue().toString())) {product.getDetails().setTracks(null);}}
}

更新了ProductService.java

package com.borislam.service;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import com.borislam.domain.Product;
import com.borislam.repository.ProductRepository;
import com.borislam.view.ProductSearchCriteria;@Service
public class ProductService {@Autowiredprivate ProductRepository productRepository;public List searchByCriteria(ProductSearchCriteria criteria){return productRepository.searchByCriteria(criteria);}public Product getProduct(String sku) {return productRepository.findBySku(sku);}public void saveProduct(Product p){ productRepository.save(p);}public void deleteProduct(Product p){ productRepository.delete(p);}}

结论:

1. Spring Data Mongo DB提供了MongoTemplate,可让您轻松执行MongoDB操作。

2.借助Spring Data MongoDB,可以轻松将MongoDB JSON样式的文档映射到POJO

3. Spring数据的存储库抽象减少了访问MongoDB的样板代码。

4.您将自定义行为添加到spring数据存储库。

  • 获取源代码

参考: 示例应用程序简介(MongoShop产品目录) , MongoDB模式设计和数据准备 , JSF(PrimeFaces)和Spring数据MongoDB集成 , 带有Spring数据存储库和mongotemplate的Enquriy数据 , 创建,编辑和删除数据 (来自我们的JCG合作伙伴 Boris)在“ Programming Peaceally和平”博客上,Lam表示。

翻译自: https://www.javacodegeeks.com/2013/02/spring-data-mongodb-and-jsf-integration-tutorial.html



推荐阅读
author-avatar
小小小小修领_233
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有