S2SH的MVC模版

来源:互联网 发布:河南工考网络培训平台 编辑:程序博客网 时间:2024/06/07 15:50






1.  原理:  


见图03-BaseDao与BaseDaoImpl的设计.PNG

见图02-MVC与三层架构的说明.PNG



2.  步骤:
        注:此时是并未合并service和dao的一般的MVC模式,仍为三层
这是刚开始第一次写的步骤:
1. 创建Action类,继承ActionSupport并在类上加注解@Controller和@Scope("prototype")
2. 写其中的方法:CRUD的6个方法(方法名、返回值、注释)
3. 创建JSP页面,此时为提示界面,并未完全实现
4. 配置struts.xml
5. 测试
6. 创建空的service接口,并在action中创建引用,并在引用上面写@Resource注解
7. 实现Action中的方法,此时先在service中创建需要的方法
(此处根据业务需要,不仅只有CRUD的6个方法),先写注释但不实现
8. 创建serviceImpl类,并在类上写@Service注解,实现service接口中的方法
9. 创建空的dao接口,并在service中创建引用,并在引用上面写@Resource注解
10.创建daoImpl类,并在类上写@Repository注解,实现dao接口中的方法   
11.写页面
12.测试

整合Dao层: 为了Dao层书写方便,抽取了BaseAction类和BaseDao接口和BaseDaoImpl实现类。
0. 创建带泛型的BaseAction类和BaseDao接口和BaseDaoImpl实现类。具体见模版
1. 将RoleAction类改为继承BaseAction<Role>类,并在BaseAction<Role>中引入service的注解
2. service和serviceImpl不变,此时不仅只有CRUD的6个方法,
根据RoleAction调用的service层的方法而定
3. 将RoleDao接口继承BaseDao接口即可,此时有父接口的CRUD6个操作,
如果还有需要的独属于自己的接口(根据service需要调用的方法而定),则在RoleDao接口中创建即可
4. 将RoleDaoImpl类继承BaseDaoImpl类,并实现RoleDao接口即可。
如果RoleDao中有除CRUD外别的方法,则再实现即可。




3.  MVC具体模板如下
注: 合并service与dao为BaseDao和BaseDaoImpl,抽取公共的

BaseAction.java
-------------------------------------------------------------------

public class BaseAction<T> extends ActionSupport implements ModelDriven<T>{                 


// 声明service
@Resource
protected RoleService roleService;

// 对modelDriven的支持
protected T model;

public T getModel() {
return model;
}


// 获取泛型的具体类型
public BaseAction(){
try {
// 通过反射获取T的真实类型
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();
Class<T> clazz = (Class<T>) pt.getActualTypeArguments()[0];
// 通过反射创建model的实例
model = clazz.newInstance();
} catch (Exception e) {
throw new RuntimeException(e);
}
}

}

-------------------------------------------------------------------





BaseDao.java
---------------------------------------------------------------------------------

// 定义通用的dao接口,里面包含常用的基本方法。
// 使用泛型其他dao接口继承该接口即可。
// 如果子接口中有另外的方法,则在子接口中独自定义
public interface BaseDao<T> {


/**
* 添加实体
* @param entity
*/
void save(T entity);

/**
* 删除实体
* @param id
*/
void delete(Long id);

/**
* 更新实体
* @param entity
*/
void update(T entity);

/**
* 根据id查询实体
* @param id
* @return
*/
T getById(Long id);

/**
* 根据id数组查询多个实体
* @param ids
* @return
*/
List<T> getByIds(Long[] ids);

/**
* 查询所有
* @return
*/
List<T> findAll();

}

---------------------------------------------------------------------------------



BaseDaoImpl.java
---------------------------------------------------------------------------------

// 使用泛型定义通用接口BeasDao的实现类
// 声明为抽象类,不将其注入到spring容器,且不能创建对象
// 由具体的实体类继承使用,并覆盖实现需要使用的方法
/*
使用父类方式:子类定义形式
@Resource
public class RoleDaoImpl extends BaseDaoImpl<Role> implements RoleDao{
// 此处为接口中另外定义的方法实现
// ...
}
*/


public abstract class BaseDaoImpl<T> implements BaseDao<T> {


@Resource
private SessionFactory sessionFactory;
private Class<T> clazz = null;


// 注:定义为protected类型,方便子类使用已经注解过的session
protected Session getSession() {
return sessionFactory.getCurrentSession();
}

// 子类创建的时候会自动调用该类(父类)的构造方法,传递参数类型T
public BaseDaoImpl(){
// 通过反射获取T的真实类型
ParameterizedType pt = (ParameterizedType) this.getClass().getGenericSuperclass();              
this.clazz = (Class<T>) pt.getActualTypeArguments()[0];
}


public void save(T entity) {
getSession().save(entity);
}


public void update(T entity) {
getSession().update(entity);
}


public void delete(Long id) {
if (id == null)
return;
Object entity = getById(id);
if (entity != null)
getSession().delete(entity);
}


public T getById(Long id) {
if(id == null){
return null;
}else{
// 注意: 此处返回值类型T 要加小括号
return (T) getSession().get(clazz, id);
}
}


public List<T> getByIds(Long[] ids) {
// 注:如果hql语句过长,则换行单独写
// 如果加了//之后,格式化代码的时候就不会在忽略了
return getSession().createQuery(//
"FROM " + clazz.getSimpleName() + " Where id IN (:ids)")//
.setParameterList("ids", ids)// 注意一定要使用该setParameterList方法传递集合类型的数据参数
.list();
}


public List<T> findAll() {
// 注; 注意FROM后面的空格
return getSession().createQuery("FROM " + clazz.getSimpleName()).list();
}
}



---------------------------------------------------------------------------------





3. 使用案例如下


RoleAction.java
---------------------------------------------------------------------------------


/*
Action中的表命名规则:
方法名 返回值页面
列表 list()list list.jsp
删除 delete()toList
添加页面 addUI()addUI addUI.jsp  ---> saveUI.jsp
添加 add()toList
修改页面 editUI()editUI editUI.jsp ---> saveUI.jsp
修改 edit()toList


注:因为重定向地址栏改变 , 转发地址栏不变,所以为了防止表单重复提交
删除、添加、修改都重定向到列表动作
<result name="toList" type="redirectAction">role_list</result>
 
 
struts.xml中的命名规则:
<!-- 岗位管理 -->
<action name="role_*" class="roleAction" method="{1}">
<result name="list">/WEB-INF/jsp/roleAction/list.jsp</result>
<result name="saveUI">/WEB-INF/jsp/roleAction/saveUI.jsp</result>
<result name="toList" type="redirectAction">role_list</result>
</action>




合并添加修改页面的方式:
1. Action中  addUI()和editUI()的方法的返回值都为saveUI,saveUI转向saveUI.jsp
2. 写saveUI.jsp,根据是否传id值来确定是转向添加页面还是修改页面
  <s:form action="role_%{id==null?'add':'edit'}">
<s:hidden name="id"></s:hidden>
......其他内容
  </s:form>

*/
 
 


@Controller
@Scope("prototype") // 多例,默认action是单例
public class RoleAction extends BaseAction<Role> {

/** 列表 */
public String list() throws Exception {
// 准备数据
List<Role> roleList = roleService.findAll();
ActionContext.getContext().put("roleList", roleList);
return "list";
}



/** 删除 */
public String delete() throws Exception {
roleService.delete(model.getId());
return "toList";
}



/** 添加页面 */
public String addUI() throws Exception {
// 如果没有关联的属性则直接跳转到添加页面,如果有,则先准备数据再跳转
return "saveUI";
}



/** 添加 */
public String add() throws Exception {
// 1.封装对象 注:正规情况要new一个对象再封装。
// Role role = new Role();
// role.setName(model.getName());
// role.setDescription(model.getDescription());


// 2.保存到数据库 注:由于此时model的字段和role的字段一样,可以直接传递model
roleService.save(model);


return "toList";
}



/** 修改页面 */
public String editUI() throws Exception {
// 1.准备要回显的数据
Role role = roleService.getById(model.getId());
// 2.得到值栈对象并将要回显数据的对象放在栈顶,这样可以方便直接获取
ActionContext.getContext().getValueStack().push(role);
// 如果有需要单独处理回显的数据则单独处理
return "saveUI";
}



/** 修改 */
public String edit() throws Exception {
// 1.从数据库中获得要修改的原始对象 
//   注:此处的id为提交修改动作时传过来的id,在modelDriven中封装了其值到id字段中
Role role = roleService.getById(model.getId());


// 2.设置要修改的属性
role.setName(model.getName());
role.setDescription(model.getDescription());


// 3,更新到数据库 注:此处实际上已经是持久化对象了,所以update语句可以省略
roleService.update(role);


return "toList";
}


}

---------------------------------------------------------------------------------



RoleService.java
---------------------------------------------------------------------------------


public interface RoleService {


/**
* 查询所有的岗位信息
* @return
*/
List<Role> findAll();


/**
* 根据id删除岗位信息
* @param id
*/
void delete(Long id);


/**
* 添加岗位
* @param model
*/
void save(Role model);


/**
* 根据id获取岗位信息
* @param id
* @return
*/
Role getById(Long id);


/**
* 修改岗位信息
* @param role
*/
void update(Role role);


}

---------------------------------------------------------------------------------




RoleServiceImpl.java
---------------------------------------------------------------------------------

@Service
@Transactional
public class RoleServiceImpl implements RoleService {


@Resource
private RoleDao roleDao = new RoleDaoImpl();


public List<Role> findAll() {
return roleDao.findAll();
}


public void delete(Long id) {
roleDao.delete(id);
}


public void save(Role model) {
roleDao.save(model);
}


public Role getById(Long id) {
return roleDao.getById(id);
}


public void update(Role role) {
roleDao.update(role);
}


}

---------------------------------------------------------------------------------



RoleDao.java
---------------------------------------------------------------------------------

public interface RoleDao extends BaseDao<Role> {
// 在此处可以自定义除父类接口BaseDao中默认的CRUD之外的dao接口
}

---------------------------------------------------------------------------------



RoleDaoImpl.java
---------------------------------------------------------------------------------

@Repository
public class RoleDaoImpl extends BaseDaoImpl<Role> implements RoleDao {


// 如果需要,可以在此处复写crud的函数实现新增的功能
}

---------------------------------------------------------------------------------
















































0 0
原创粉丝点击