【SSH项目实战02】基本增删查改、Service和Action的抽取以及使用注解替换xml

上一节我们搭建好了Struts2、Hibernate和Spring的开发环境,并成功将它们整合在一起。这节主要完成一些基本的增删改查以及Service、Dao和Action的抽取。

1. Service层的抽取

上一节中,我们在service层简单写了save和update方法,这里我们开始完善该部分的代码,然后对service层的代码进行抽取。

1.1 完善CategoryService层

对数据库的操作无非是增删改查,首先我们来完善CategoryService层的接口和实现:

//CategoryService接口
public interface CategoryService extends BaseService<Category> {

	public void save(Category category); //插入

	public void update(Category category);//更新

	public void delete(int id); //删除

	public Category get(int id); //获取一个Category

	public List<Category> query(); //获取全部Category

}

对CategoryService接口的具体实现:

public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService {

	private SessionFactory sessionFactory;

	//Spring会注进来
	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	protected Session getSession() {
		//从当前线程获取session,如果没有则创建一个新的session
		return sessionFactory.getCurrentSession();
	}

	@Override
	public void save(Category category) {
		getSession().save(category);
	}

	@Override
	public void update(Category category) {
		getSession().update(category);
	}

	@Override
	public void delete(int id) {
		/*第一种方法有个弊端,就是没删除一次得先查询一次
		Object obj = getSession().get(Category.class, id);
		if(obj != null) {
			getSession().delete(obj);
		}*/
		String hql = "delete Category while id=:id";
		getSession().createQuery(hql) //
				.setInteger("id", id) //
				.executeUpdate();
	}

	@Override
	public Category get(int id) {
		return (Category) getSession().get(Category.class, id);
	}

	@Override
	public List<Category> query() {
		String hql = "from Category";
		return getSession().createQuery(hql).list();
	}
}

1.2 Service层抽取实现

完成了CategoryService后,我们来抽取Service层的基础实现。思路是这样的:我们抽取一个基础接口BaseService以及基础接口的实现BaseServiceImpl,后面开发的时候,如果需要新的Service,只需要做两步即可:首先定义一个新的接口xxxService继承BaseService接口,这个接口可以增加新的抽象方法;然后定义一个新的实现类xxxServiceImpl继承BaseServiceImpl并实现xxxService接口即可。这样更加便于项目的维护。

我们先根据上面的CategoryService接口来创建BaseService接口:

//基础接口BaseService,使用泛型
public interface BaseService<T> {
	public void save(T t);

	public void update(T t);

	public void delete(int id);

	public T get(int id);

	public List<T> query();
}

然后再根据CategoryServiceImpl实现类创建BaseService接口的实现类BaseServiceImpl:

/**
 * @Description TODO(公共模块的抽取)
 * @author eson_15
 *
 */
@SuppressWarnings("unchecked")
public class BaseServiceImpl<T> implements BaseService<T> {

	private Class clazz; //clazz中存储了当前操作的类型,即泛型T
	private SessionFactory sessionFactory;

	public BaseServiceImpl() {
                //下面三个打印信息可以去掉,这里是给自己看的
                System.out.println("this代表的是当前调用构造方法的对象" + this);
		System.out.println("获取当前this对象的父类信息" + this.getClass().getSuperclass());
		System.out.println("获取当前this对象的父类信息(包括泛型信息)" + this.getClass().getGenericSuperclass());
		//拿到泛型的参数类型
		ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
		clazz = (Class)type.getActualTypeArguments()[0];
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
		this.sessionFactory = sessionFactory;
	}

	protected Session getSession() {
		//从当前线程获取session,如果没有则创建一个新的session
		return sessionFactory.getCurrentSession();
	}

	@Override
	public void save(T t) {
		getSession().save(t);
	}

	@Override
	public void update(T t) {
		getSession().update(t);
	}

	@Override
	public void delete(int id) {
		System.out.println(clazz.getSimpleName());
		String hql = "delete " + clazz.getSimpleName() + " as c where c.id=:id";
		getSession().createQuery(hql) //
				  .setInteger("id", id) //
				  .executeUpdate();
	}

	@Override
	public T get(int id) {
		return (T) getSession().get(clazz, id);
	}

	@Override
	public List<T> query() {
		String hql = "from " + clazz.getSimpleName();
		return getSession().createQuery(hql).list();
	}

}

抽取完了后,我们就可以改写CategoryService接口和CategoryServiceImpl实现类了。如下:

//CategoryService接口继承BaseService接口
public interface CategoryService extends BaseService<Category> {
	/*
        * 只要添加CategoryService本身需要的新的方法即可,公共方法已经在BaseService中了
        */
}

/**
 * @Description TODO(模块自身的业务逻辑)
 * @author eson_15
 *
 */
public class CategoryServiceImpl extends BaseServiceImpl<Category> implements CategoryService {

    /*
     * 只需实现CategoryService接口中新增的方法即可,公共方法已经在BaseServiceImpl中实现了
     */
}

从代码中可以看出,新增的Service只需要继承BaseService接口,然后在接口中新增本Service所需要的业务逻辑即可。新增的ServiceImpl只需要继承BaseServiceImpl并实现新增的业务逻辑即可。

但是别忘了很重要的一点:就是修改Spring的配置文件beans.xml中的bean

<!-- 泛型类是不能实例化的,所以要加lazy-init属性 -->
<bean id="baseService" class="cn.it.shop.service.impl.BaseServiceImpl" lazy-init="true">
	 <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="categoryService" class="cn.it.shop.service.impl.CategoryServiceImpl" parent="baseService"/>

将原来categoryService中的property干掉,然后增加parent属性,指明继承baseService;然后配置一下baseService,将sessionFactory配到baseService中去,另外要注意一点:设置lazy-init属性为true,因为baseService是泛型类,泛型类是不能实例化的。至此,Service层的抽取就搞定了。

2. Service层添加一个Account

刚刚抽取好了Service层,那么现在我们想写一个Account(管理员)的service就很简单了:

首先写一个AccountService接口继承BaseService:

public interface AccountService extends BaseService<Account> { //注意BaseService里的泛型现在是Account
	/*
	 * 只要添加AccountService本身需要的新的方法即可,公共方法已经在BaseService中了
	 */
}

然后写一个AccountServiceImpl实现类继承BaseServiceImpl实现类,并实现AccountService接口即可:

public class AccountServiceImpl extends BaseServiceImpl<Account> implements AccountService {

	/*
	 * 只需实现AccountService接口中新增的方法即可,公共方法已经在BaseServiceImpl中实现了
	 */

	//管理登陆功能,后期再完善
}

最后在beans.xml文件里加上如下配置:

<bean id="accountService" class="cn.it.shop.service.impl.AccountServiceImpl" parent="baseService" />

这样就写好了一个新的service了,以后需要添加service就遵循这个流程,非常方便。

3. Action的抽取

3.1 Action中往域(request,session,application等)中存数据

我们知道,在Action中可以直接通过ActionContext.getContext()去获取一个ActionContext对象,然后通过该对象再去获得相应的域对象;也可以通过实现xxxAware接口来注入相应的域对象。我们先来看一下这两种方法:

public class CategoryAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware{

	private Category category;

        private CategoryService categoryService;
    
        public void setCategoryService(CategoryService categoryService) {
            this.categoryService = categoryService;
        }

	public String update() {
		System.out.println("----update----");
		categoryService.update(category);
 		return "index";
 	}

	public String save() {
		System.out.println("----save----");
		return "index";
 	}

 	public String query() {
		 //解决方案一,采用相应的map取代原来的内置对象,这样与jsp没有依赖,但是代码量比较大
 //		ActionContext.getContext().put("categoryList", categoryService.query()); //放到request域中
 //		ActionContext.getContext().getSession().put("categoryList", categoryService.query()); //放到session域中
 //		ActionContext.getContext().getApplication().put("categoryList", categoryService.query()); //放到application域中

		//解决方案二,实现相应的接口(RequestAware,SessionAware,ApplicationAware),让相应的map注入
		request.put("categoryList", categoryService.query());
		session.put("categoryList", categoryService.query());
		application.put("categoryList", categoryService.query());
		return "index";
	}

	public Category getCategory() {
		return category;
	}

	public void setCategory(Category category) {
		this.category = category;
	}

	private Map<String, Object> request;
	private Map<String, Object> session;
	private Map<String, Object> application;

	@Override
	public void setApplication(Map<String, Object> application) {
		this.application = application;
	}

	@Override
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	@Override
	public void setRequest(Map<String, Object> request) {
		this.request = request;
	}
}

还是上一节整合三大框架时的CategoryAction类,我们在里面加了一个query方法,在该方法中,我们通过向request域、session域和application域中存入查询的结果。第一种方法是直接使用ActionContext来实现,不需要实现任何接口,但是代码量较大;第二种方法通过实现RequestAware、SessionAware和ApplicationAware接口,实现该接口的三个抽象方法把request、session和application注入进来,然后赋给相应的成员变量中,这样就可以在query方法中向域中存放查询结果了。这代码量貌似比第一种方法更大……但是我们可以抽取,先往下看。

我们在index.jsp中新加一个查询连接来测试能否将查询结果显示出来:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>

  <body>
    <a href="${pageContext.request.contextPath }/category_update.action?category.id=2&category.type=gga&category.hot=false">访问update</a>
    <a href="category_save.action">访问save</a>
    <a href="category_query.action">查询所有类别</a><br/>
    <c:forEach items="${requestScope.categoryList }" var="category">
    	${category.id } | ${category.type } | ${category.hot } <br/>
    </c:forEach>

    <c:forEach items="${sessionScope.categoryList }" var="category">
    	${category.id } | ${category.type } | ${category.hot } <br/>
    </c:forEach>

    <c:forEach items="${applicationScope.categoryList }" var="category">
    	${category.id } | ${category.type } | ${category.hot } <br/>
    </c:forEach>
  </body>
</html>

3.2 抽取BaseAction

刚刚提到了,第二种方法的代码量更大,但是我们可以抽取一个BaseAction,专门处理这些域相关的操作。

public class BaseAction extends ActionSupport implements RequestAware,SessionAware,ApplicationAware {

	protected Map<String, Object> request;
	protected Map<String, Object> session;
	protected Map<String, Object> application;

	@Override
	public void setApplication(Map<String, Object> application) {
		this.application = application;
	}

	@Override
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	@Override
	public void setRequest(Map<String, Object> request) {
		this.request = request;
	}
}

然后我们自己的Action如果需要用到这些域对象来存储数据时,直接继承BaseAction即可,就能直接使用request、session和application对象了。所以修改后的CategoryAction如下:

public class CategoryAction extends BaseAction {

	private Category category;
<pre name="code" class="java">
        private CategoryService categoryService;
    
        public void setCategoryService(CategoryService categoryService) {
            this.categoryService = categoryService;
        }

public String update() {System.out.println("----update----");categoryService.update(category); return "index"; }public String save() {System.out.println("----save----");return "index"; } public String query() {request.put("categoryList", categoryService.query());
session.put("categoryList", categoryService.query()); application.put("categoryList", categoryService.query()); return "index"; } public Category getCategory() { return category; } public void setCategory(Category category) {this.category = category; }}


后面所有要使用request、session和application域的Action,只要直接继承BaseAction即可,非常方便。

3.3 获取参数(ModelDriven)

我们继续看上面的CategoryAction类,里面有个成员变量category,这是个POJO,定义这个变量并写好set和get方法是为了JSP页面可以通过url后面附带参数传进来,参数是category对象中的属性,比如id,type等,但是url中的参数必须写成category.id、category.type等。这样struts会自动将这写参数注入到category对象中,然后我们就可以直接使用这个category对象了,但是这样有点繁琐。我们可以使用ModelDriven来更方便的解决。

public class CategoryAction extends BaseAction implements ModelDriven<Category>{

	private Category category;

	//使用ModelDriven接口必须要实现getModel()方法,此方法会把返回的项压到栈顶
	@Override
	public Category getModel() {
		category = new Category();
		return category;
	}
<pre name="code" class="java">        private CategoryService categoryService;
    
        public void setCategoryService(CategoryService categoryService) {
            this.categoryService = categoryService;
        }

	public String update() {
		System.out.println("----update----");
		categoryService.update(category);
 		return "index";
 	}

	public String save() {
		System.out.println("----save----");
		return "index";
	}

	public String query() {
		request.put("categoryList", categoryService.query());
		session.put("categoryList", categoryService.query());
		application.put("categoryList", categoryService.query());
		return "index";
	}

}

这样我们在前台JSP页面就不用带category.id这种繁琐的参数了,看JSP页面中的ModelDriven部分:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>
    <title>My JSP 'index.jsp' starting page</title>
  </head>

  <body>
    <a href="${pageContext.request.contextPath }/category_update.action?category.id=2&category.type=gga&category.hot=false">访问update</a>
    <a href="category_save.action?id=1&type=haha&hot=true">测试ModelDriven</a>
    <a href="category_query.action">查询所有类别</a><br/>
    <c:forEach items="${requestScope.categoryList }" var="category">
    	${category.id } | ${category.type } | ${category.hot } <br/>
    </c:forEach>

    <c:forEach items="${sessionScope.categoryList }" var="category">
    	${category.id } | ${category.type } | ${category.hot } <br/>
    </c:forEach>

    <c:forEach items="${applicationScope.categoryList }" var="category">
    	${category.id } | ${category.type } | ${category.hot } <br/>
    </c:forEach>
  </body>
</html>

测试结果是可以获得catgory,并且将id,type和hot属性全部赋值好。我们可以看出,通过实现ModelDriven接口,我们可以很方便的在url中携带参数,Action中只需要实现getModel方法,new一个要使用的对象返回即可。到这里我们很容易想到,struts中肯定会有很多这种model需要获取,所以这一块我们也要抽取到BaseAction中去。

3.4 抽取ModelDriven到BaseAction

首先我们在BaseAction中添加ModelDriven部分的代码,如下:

//因为有很多不同的model都需要使用ModelDriven,所以这里使用泛型
public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {

	protected Map<String, Object> request;
	protected Map<String, Object> session;
	protected Map<String, Object> application;

	protected T model;

	@Override
	public void setApplication(Map<String, Object> application) {
		this.application = application;
	}

	@Override
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}

	@Override
	public void setRequest(Map<String, Object> request) {
		this.request = request;
	}

	@Override
	public T getModel() { //这里通过解析传进来的T来new一个对应的instance
		ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
		Class clazz = (Class)type.getActualTypeArguments()[0];
		try {
			model = (T)clazz.newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return model;
	}
}

抽取完了后,CategoryAction中的代码会越来越少:

//继承BaseAction,并且加上泛型
public class CategoryAction extends BaseAction<Category> {

	private CategoryService categoryService;

	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}

	public String update() {
		System.out.println("----update----");
		categoryService.update(model);//直接使用model
		return "index";
	}

	public String save() {
		System.out.println("----save----");
		System.out.println(model); //直接使用model
		return "index";
	}

	public String query() {
		request.put("categoryList", categoryService.query());
		session.put("categoryList", categoryService.query());
		application.put("categoryList", categoryService.query());
		return "index";
	}

}

到这里,还有一个看着不爽的地方,就是categoryService这个成员变量,它一直存在在CategoryAction里,因为CategoryAction中有用到categoryService对象中的方法,所以必须得创建这个对象,并且有set方法才能注入进来。这就导致一个弊端:如果很多Action都需要使用categoryService的话,那就必须在它们的Action里创建这个对象和set方法,而且,如果一个Action中要使用好几个不同的service对象,那就得全部创建,这样就变得很冗杂。

3.5 抽取service到BaseAction

针对上面的问题,我们将工程中所有的service对象都抽取到BaseAction中创建,这样其他Action继承BaseAction后,想用什么service就直接拿来用即可:

//我将BaseAction中的内容归归类了
public class BaseAction<T> extends ActionSupport implements RequestAware,SessionAware,ApplicationAware,ModelDriven<T> {

	//service对象
	protected CategoryService categoryService;
	protected AccountService accountService;

	public void setCategoryService(CategoryService categoryService) {
		this.categoryService = categoryService;
	}
	public void setAccountService(AccountService accountService) {
		this.accountService = accountService;
	}

	//域对象
	protected Map<String, Object> request;
	protected Map<String, Object> session;
	protected Map<String, Object> application;

	@Override
	public void setApplication(Map<String, Object> application) {
		this.application = application;
	}
	@Override
	public void setSession(Map<String, Object> session) {
		this.session = session;
	}
	@Override
	public void setRequest(Map<String, Object> request) {
		this.request = request;
	}

	//ModelDriven
	protected T model;
	@Override
	public T getModel() {
		ParameterizedType type = (ParameterizedType)this.getClass().getGenericSuperclass();
		Class clazz = (Class)type.getActualTypeArguments()[0];
		try {
			model = (T)clazz.newInstance();
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		return model;
	}
}

这样CategoryAction中就更加清爽了:

public class CategoryAction extends BaseAction<Category> {

	public String update() {
		System.out.println("----update----");
		categoryService.update(model);
		return "index";
	}

	public String save() {
		System.out.println("----save----");
		System.out.println(model);
		return "index";
	}

	public String query() {
		request.put("categoryList", categoryService.query());
		session.put("categoryList", categoryService.query());
		application.put("categoryList", categoryService.query());
		return "index";
	}

}

有人可能会问,BaseAction中注入了那么多service对象的话不会冗余么?这是不会的,因为就算不写在BaseAction中,Spring容器也是会创建这个对象的,这点没有关系,相反,service对象全放在BaseAction中更加便于其他Action的开发,而且BaseAction不需要配到struts.xml文件中,因为根本就没有哪个JSP会请求BaseAction,它只是让其他Action来继承用的。

还有一点别忘了:那就是修改在beans.xml中的配置:

<!-- 如果是prototype类型,默认是使用时创建,不是启动时自动创建 -->
<bean id="baseAction" class="cn.it.shop.action.BaseAction" scope="prototype">
	 <property name="categoryService" ref="categoryService"></property>
	 <property name="accountService" ref="accountService"></property>
</bean>

<bean id="categoryAction" class="cn.it.shop.action.CategoryAction" scope="prototype" parent="baseAction"/>

新加一个baseAction的bean,将工程中所有service对象作为property配好,将原来的categoryAction中的property干掉。

以后我们如果要写新的xxxAction,直接继承BaseAction即可,如果xxxAction中有用到某个service,直接拿来用即可,只需要在beans.xml文件中加一个xxxAction对应的bean,在struts.xml文件中配置好跳转即可。

4. 将xml改成注解

我们可以看到,随着项目越写越大,beans.xml中的配置会越来越多,而且很多配置有冗余,为了更加便于开发,我们现在将xml的配置改成注解的形式,我们先看一下beans.xml中的配置:

这些是我们之前搭建环境以及抽取的时候写的bean,这些都需要转换成注解的形式,下面我们一块一块的换掉:首先替换service部分,这部分有三个:baseService、categoryService和accountService。替换如下:

然后将beans.xml中的相应部分干掉即可。接下来修改ActIon部分,主要有baseAction、categoryAction和accountAction三个,替换如下:

然后再干掉beans.xml中的Action部分的配置即可,最后在beans.xml文件中添加一个如下配置,就可以使用注解了。

<span style="font-family:Microsoft YaHei;"><context:component-scan base-package="cn.it.shop.."/></span>

有人可能会问,为什么service和action两个使用注解的时候不一样呢?service中使用的是@Service而action中使用的是@Controller呢?其实是一样的,只是为了区分它们是不同层的bean而已,便于阅读。

(注:到最后我会针对此项目申请博客专栏,并提供整个项目的源码下载!欢迎大家收藏或关注)

_____________________________________________________________________________________________________________________________________________________

-----乐于分享,共同进步!

-----更多文章请看:http://blog.csdn.net/eson_15

时间: 2024-09-30 05:30:28

【SSH项目实战02】基本增删查改、Service和Action的抽取以及使用注解替换xml的相关文章

JAVAEE——SSH项目实战02:客户列表和BaseDao封装

作者: kent鹏 转载请注明出处: http://www.cnblogs.com/xieyupeng/p/7129152.html 该项目在SSH三大框架整合基础上进行开发:http://www.cnblogs.com/xieyupeng/p/7108141.html 一.客户列表 1.分析 2.书写步骤 (1)封装PageBean public class PageBean { //当前页数 private Integer currentPage; //总记录数 private Intege

SSH框架的多表查询和增删查改 (方法一)上

原创作品,允许转载,转载时请务必标明作者信息和声明本文章==>  http://www.cnblogs.com/zhu520/p/7772823.html   因为最近在做Android 练习的项目,使用增删查改的时候还是使用jdbc的增删查改 发现实在是太麻烦了,所有果断抛弃它,使用ssh, 但是发现不会....经过了四天的时间我终于弄懂了. 哪个大神看到有问题指点一下. 在弄这前要先明白一下@Component @Controller @Service @Repository 这些注释 可以

nodejs连接mysql并进行简单的增删查改

最近在入门nodejs,正好学习到了如何使用nodejs进行数据库的连接,觉得比较重要,便写一下随笔,简单地记录一下 使用在安装好node之后,我们可以使用npm命令,在项目的根目录,安装nodejs中的mysql模块 npm install mysql 在连接数据库之前,要先引入nodejs连接处理mysql的模块 var mysql = require('mysql'); 类似php连接mysql的方式,编写连接代码 //使用nodejs处理mysql的模块,使用创建连接方法,创建与mysq

EF实现增删查改功能

In the previous tutorial you created an MVC application that stores and displays data using the Entity Framework and SQL Server LocalDB. In this tutorial you'll review and customize the CRUD (create, read, update, delete) code that the MVC scaffoldin

在MVC程序中,使用泛型仓储模式和工作单元实现增删查改

在这片文章中,我将自己动手为所有的实体:写一个泛型仓储类,还有一个工作单元. 工作单元的职责就是:为每一个实体,创建仓储实例.仓储(仓库)的职责:增删查改的功能实现. 我们将会在控制器中,创建工作单元类(UnitOfWork)的实例,然后根据实体,创建仓储实例,再就是使用仓储里面的方法,做操作了. 下面的图中,解释了,仓储和EF 数据上文的关系,在这个图里面,MVC控制器和仓储之间的交互,是通过工作单元来进行的,而不是直接和EF接触. 那么你可能就要问了,为什么要使用工作单元??? 工作单元,就

基于MVC实现增删查改

1.首先要理解MVC的架构.新建一个web项目取名叫Service. 2.建立eneity(实体包),tools(连接数据库),DAO(借助result的代码实现增删查改)servlet(实现跳转). 3.在建立实体时一定要和数据库中的字段名一致,否则在运行时会出错.连接数据库时一定要注意数据库名和密码. 4.在DAO层中实现增删查改的语句,并测试,代码如下: public class userDAO {  public List getAllUser(){//查询 String SQL="se

2015.8.2 jdbc实现商品类的增删查改

在惠普济宁基地进行了两周sql和java的学习,学到很多东西 刚才实现了用jdbc访问数据库对数据库进行操作,是用eclipse写的,过几天移植到NetBeans上,个人还是比较习惯看图形化界面 前几天茫然无头绪的时候闫老师指点迷津了一下,讲了具体的流程,如下: 1.创建项目2.导入相关JAR3.组织项目结构  util:工具类,公共类  po:实体类对象  dao:数据访问  biz:业务类  view:显示 第一步不多陈述 第二步具体如何配置可以参见蔡振华的博客http://qmkkd.bl

4.CRUD Operations Using the Repository Pattern in MVC【在MVC中使用仓储模式进行增删查改】

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-using-the-repository-pattern-in-mvc/ 上一篇文章,讲到了MVC中基本的增删查改,这篇文章,我会继续说到,使用仓储模式,进行增删查改. 什么是仓储模式呢,我们先来了解一下:  仓储模式是为了在程序的数据访问层和业务逻辑层之间创建一个抽象层,它是一种数据访问模式,提供了一种更松散耦合的数据访问方法.我们把创建数据访问的逻辑代码写在单独的类中,或者类库中

6.在MVC中使用泛型仓储模式和依赖注入实现增删查改

原文链接:http://www.c-sharpcorner.com/UploadFile/3d39b4/crud-operations-using-the-generic-repository-pattern-and-dep/ 系列目录: Relationship in Entity Framework Using Code First Approach With Fluent API[[使用EF Code-First方式和Fluent API来探讨EF中的关系]] Code First Mig