S2SH合并DAO层与service层
2016-04-02 11:06
423 查看
合并service和dao层,分俩层,即合并service层与Dao层为service层
准备有:
先实现Action类,DaoSupport接口,DaoSupportImpl类
一、 流程总结: 实现增删该查一组功能的步骤:
1. 做Action相关的准备:
a. 创建MyAction继承BaseAction
b. 定义Action中的方法,要写出方法名、作用、返回值
c. 创建所用到的JSP页面,空的未实现
d. 配置Action,在MyAction中加@Controller和@Scope("prototype")注解
e. 配置struts.xml
f. 测试
2. 做Service相关的准备:接口,实现类,配置
a. 创建接口MyService继承DaoSupport接口
b. 创建实现类MyServiceImpl继承DaoSupportImpl类
c. 在MyServiceImpl上写注解: @Service和@Transactional
3. 填空
a. Action方法
b. 新增的service方法
c. 修改jsp页面的内容: 拷贝写好的前端源代码,引入公共页面,修改路径,修改标签内容
二、 案例如下:
BaseAction类:
-------------------------------------------------------------------------------------------
package cn.itcast.oa.base;
public class BaseAction<T> extends ActionSupport implements ModelDriven<T>{
// 声明service
@Resource
protected DepartmentService departmentService;
@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);
}
}
}
-------------------------------------------------------------------------------------------
DaoSupport接口:
-------------------------------------------------------------------------------------------
// 定义通用的dao接口,里面包含常用的基本方法。
// 使用泛型其他dao接口继承该接口即可。
// 如果子接口中有另外的方法,则独自定义
public interface DaoSupport<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();
}
-------------------------------------------------------------------------------------------
DaoSupportImpl类
-------------------------------------------------------------------------------------------
// 使用泛型定义通用接口BeasDao的实现类
// 声明为抽象类,不将其注入到spring容器,且不能创建对象
// 由具体的实体类继承使用,并覆盖实现需要使用的方法
/*
使用父类方式:子类定义形式
@Resource
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{
// 此处为接口中另外定义的方法实现
// ...
}
*/
@Transactional // 该注解可以被继承
public abstract class DaoSupportImpl<T> implements DaoSupport<T> {
@Resource
private SessionFactory sessionFactory;
private Class<T> clazz = null;
// 注:定义为protected类型,方便子类使用已经注解过的session
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
// 子类创建的时候会自动调用该类(父类)的构造方法,传递参数类型T
public DaoSupportImpl() {
// 通过反射获取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) {
if (ids == null || ids.length == 0) {
// 对于集合,如果为null,不要返回null,
// 应返回的是空的list集合,但是ArrayList定义一个默认长度是10,会占用资源
// 所以使用Collections.EMPTY_LIST,里面没有长度,不占用资源
return Collections.EMPTY_LIST;
}
return getSession().createQuery(//
"FROM " + clazz.getSimpleName() + " WHERE id IN (:ids)")//
.setParameterList("ids", ids)// 注意一定要使用该方法传递数据参数
.list();
}
public List<T> findAll() {
// 注; 注意FROM后面的空格
return getSession().createQuery("FROM " + clazz.getSimpleName()).list();
}
}
-------------------------------------------------------------------------------------------
命名规则及配置
-------------------------------------------------------------------------------------------
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>
-------------------------------------------------------------------------------------------
UserAction类:
-------------------------------------------------------------------------------------------
@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User> {
// 封装jsp页面传递的参数(要有setter/getter属性)
private Long departmentId;
private Long[] roleIds;
/** 列表 */
public String list() throws Exception {
// 准备要显示的数据并放到map域中
List<User> userList = userService.findAll();
ActionContext.getContext().put("userList", userList);
}
/** 删除 */
public String delete() throws Exception {
userService.delete(model.getId());
return "toList";
}
/** 添加页面 */
public String addUI() throws Exception {
// 如果没有关联的属性则直接跳转到添加页面,如果有,则先准备数据再跳转
// 准备关联的数据: departmentList
List<Department> topList = departmentService.findTopList();
List<Department> departmentList = DepartmentUtils.getAllDepartmentList(topList, null);
ActionContext.getContext().put("departmentList", departmentList);
// 准备关联的数据: roleList
List<Role> roleList = roleService.findAll();
ActionContext.getContext().put("roleList", roleList);
return "saveUI";
}
/** 添加 */
public String add() throws Exception {
// 封装对象:处理关联的一个部门
model.setDepartment(departmentService.getById(departmentId));
// 封装对象:处理关联的多个岗位 注: model的setRoles方法中的参数类型为set<Role>类型,所有需转换
List<Role> roleList = roleService.getByIds(roleIds);
model.setRoles(new HashSet<Role>(roleList)); // 将list类型的roleList的数据取出来放到HashSet集合中
// 保存到数据库 注:由于此时model的字段和user的字段一样,可以直接传递model
userService.save(model);
return "toList";
}
/** 修改页面 注: 修改页面和添加页面基本相同,不过修改页面增加了一个要回显的数据 */
public String editUI() throws Exception {
// 1.准备要回显的数据
User user = userService.getById(model.getId());
// 2.得到值栈对象并将要回显数据的对象放在栈顶,这样可以方便直接获取
ActionContext.getContext().getValueStack().push(user);
// △单独处理部门的回显
if (user.getDepartment() != null) {
departmentId = user.getDepartment().getId();
}
// △单独处理岗位的回显
roleIds = new Long[user.getRoles().size()];
int index = 0;
for (Role role : user.getRoles()) {
roleIds[index++] = role.getId();
}
// 准备数据: departmentList和roleList
List<Department> topList = departmentService.findTopList();
List<Department> departmentList = DepartmentUtils.getAllDepartmentList(
topList, null);
ActionContext.getContext().put("departmentList", departmentList);
List<Role> roleList = roleService.findAll();
ActionContext.getContext().put("roleList", roleList);
return "saveUI";
}
/** 修改 */
public String edit() throws Exception {
// 1.从数据库中获得要修改的原始对象
User user = userService.getById(model.getId());
// 2.设置要修改的属性
user.setLoginName(model.getLoginName());
user.setName(model.getName());
user.setGender(model.getGender());
user.setPhoneNumber(model.getPhoneNumber());
user.setEmail(model.getEmail());
user.setDescription(model.getDescription());
// >> 处理关联的一个部门
user.setDepartment(departmentService.getById(departmentId));
// >> 处理管理的多个岗位
List<Role> roleList = roleService.getByIds(roleIds);
user.setRoles(new HashSet<Role>(roleList));
// 3.更新到数据库
userService.update(user);
return "toList";
}
/** 初始化密码为123456 */
public String initPassword() throws Exception {
// 从数据库中取出原对象
User user = userService.getById(model.getId());
// 设置要修改的属性,将密码加密
String md5 = DigestUtils.md5Hex("123456");
user.setPassword(md5);
// 保存到数据库
userService.update(user);
return "toList";
}
// getter/setter属性
}
-------------------------------------------------------------------------------------------
UserService接口
-------------------------------------------------------------------------------------------
public interface UserService extends DaoSupport<User>{
/**
* 根据用户名和密码查询用户
* @param loginName
* @param password 明文密码
* @return
*/
User findByLoginNameAndPassword(String loginName, String password);
}
-------------------------------------------------------------------------------------------
UserServiceImpl类:
-------------------------------------------------------------------------------------------
package cn.itcast.oa.service.impl;
@Service
@SuppressWarnings("unused")
public class UserServiceImpl extends DaoSupportImpl<User> implements UserService{
// DaoSupportImpl类中默认的save方法没有设置用户的默认密码,所有要在UserServiceImpl中复写save方法
@Override
public void save(User user) {
// 使用codec.digest.DigestUtils包的DigestUtils的md5Hex方法设置默认的密码为123456
String md5 = DigestUtils.md5Hex("123456");
user.setPassword(md5);
// 保存到数据库
getSession().save(user);
}
public User findByLoginNameAndPassword(String loginName, String password) {
String md5 = DigestUtils.md5Hex(password);
return (User) getSession().createQuery(//
"FROM User u WHERE u.loginName=? AND u.password=?")//
.setParameter(0, loginName)//
.setParameter(1, md5)//
.uniqueResult();
}
}
-------------------------------------------------------------------------------------------
页面。。。
准备有:
先实现Action类,DaoSupport接口,DaoSupportImpl类
一、 流程总结: 实现增删该查一组功能的步骤:
1. 做Action相关的准备:
a. 创建MyAction继承BaseAction
b. 定义Action中的方法,要写出方法名、作用、返回值
c. 创建所用到的JSP页面,空的未实现
d. 配置Action,在MyAction中加@Controller和@Scope("prototype")注解
e. 配置struts.xml
f. 测试
2. 做Service相关的准备:接口,实现类,配置
a. 创建接口MyService继承DaoSupport接口
b. 创建实现类MyServiceImpl继承DaoSupportImpl类
c. 在MyServiceImpl上写注解: @Service和@Transactional
3. 填空
a. Action方法
b. 新增的service方法
c. 修改jsp页面的内容: 拷贝写好的前端源代码,引入公共页面,修改路径,修改标签内容
二、 案例如下:
BaseAction类:
-------------------------------------------------------------------------------------------
package cn.itcast.oa.base;
public class BaseAction<T> extends ActionSupport implements ModelDriven<T>{
// 声明service
@Resource
protected DepartmentService departmentService;
@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);
}
}
}
-------------------------------------------------------------------------------------------
DaoSupport接口:
-------------------------------------------------------------------------------------------
// 定义通用的dao接口,里面包含常用的基本方法。
// 使用泛型其他dao接口继承该接口即可。
// 如果子接口中有另外的方法,则独自定义
public interface DaoSupport<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();
}
-------------------------------------------------------------------------------------------
DaoSupportImpl类
-------------------------------------------------------------------------------------------
// 使用泛型定义通用接口BeasDao的实现类
// 声明为抽象类,不将其注入到spring容器,且不能创建对象
// 由具体的实体类继承使用,并覆盖实现需要使用的方法
/*
使用父类方式:子类定义形式
@Resource
public class UserDaoImpl extends BaseDaoImpl<User> implements UserDao{
// 此处为接口中另外定义的方法实现
// ...
}
*/
@Transactional // 该注解可以被继承
public abstract class DaoSupportImpl<T> implements DaoSupport<T> {
@Resource
private SessionFactory sessionFactory;
private Class<T> clazz = null;
// 注:定义为protected类型,方便子类使用已经注解过的session
protected Session getSession() {
return sessionFactory.getCurrentSession();
}
// 子类创建的时候会自动调用该类(父类)的构造方法,传递参数类型T
public DaoSupportImpl() {
// 通过反射获取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) {
if (ids == null || ids.length == 0) {
// 对于集合,如果为null,不要返回null,
// 应返回的是空的list集合,但是ArrayList定义一个默认长度是10,会占用资源
// 所以使用Collections.EMPTY_LIST,里面没有长度,不占用资源
return Collections.EMPTY_LIST;
}
return getSession().createQuery(//
"FROM " + clazz.getSimpleName() + " WHERE id IN (:ids)")//
.setParameterList("ids", ids)// 注意一定要使用该方法传递数据参数
.list();
}
public List<T> findAll() {
// 注; 注意FROM后面的空格
return getSession().createQuery("FROM " + clazz.getSimpleName()).list();
}
}
-------------------------------------------------------------------------------------------
命名规则及配置
-------------------------------------------------------------------------------------------
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>
-------------------------------------------------------------------------------------------
UserAction类:
-------------------------------------------------------------------------------------------
@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User> {
// 封装jsp页面传递的参数(要有setter/getter属性)
private Long departmentId;
private Long[] roleIds;
/** 列表 */
public String list() throws Exception {
// 准备要显示的数据并放到map域中
List<User> userList = userService.findAll();
ActionContext.getContext().put("userList", userList);
}
/** 删除 */
public String delete() throws Exception {
userService.delete(model.getId());
return "toList";
}
/** 添加页面 */
public String addUI() throws Exception {
// 如果没有关联的属性则直接跳转到添加页面,如果有,则先准备数据再跳转
// 准备关联的数据: departmentList
List<Department> topList = departmentService.findTopList();
List<Department> departmentList = DepartmentUtils.getAllDepartmentList(topList, null);
ActionContext.getContext().put("departmentList", departmentList);
// 准备关联的数据: roleList
List<Role> roleList = roleService.findAll();
ActionContext.getContext().put("roleList", roleList);
return "saveUI";
}
/** 添加 */
public String add() throws Exception {
// 封装对象:处理关联的一个部门
model.setDepartment(departmentService.getById(departmentId));
// 封装对象:处理关联的多个岗位 注: model的setRoles方法中的参数类型为set<Role>类型,所有需转换
List<Role> roleList = roleService.getByIds(roleIds);
model.setRoles(new HashSet<Role>(roleList)); // 将list类型的roleList的数据取出来放到HashSet集合中
// 保存到数据库 注:由于此时model的字段和user的字段一样,可以直接传递model
userService.save(model);
return "toList";
}
/** 修改页面 注: 修改页面和添加页面基本相同,不过修改页面增加了一个要回显的数据 */
public String editUI() throws Exception {
// 1.准备要回显的数据
User user = userService.getById(model.getId());
// 2.得到值栈对象并将要回显数据的对象放在栈顶,这样可以方便直接获取
ActionContext.getContext().getValueStack().push(user);
// △单独处理部门的回显
if (user.getDepartment() != null) {
departmentId = user.getDepartment().getId();
}
// △单独处理岗位的回显
roleIds = new Long[user.getRoles().size()];
int index = 0;
for (Role role : user.getRoles()) {
roleIds[index++] = role.getId();
}
// 准备数据: departmentList和roleList
List<Department> topList = departmentService.findTopList();
List<Department> departmentList = DepartmentUtils.getAllDepartmentList(
topList, null);
ActionContext.getContext().put("departmentList", departmentList);
List<Role> roleList = roleService.findAll();
ActionContext.getContext().put("roleList", roleList);
return "saveUI";
}
/** 修改 */
public String edit() throws Exception {
// 1.从数据库中获得要修改的原始对象
User user = userService.getById(model.getId());
// 2.设置要修改的属性
user.setLoginName(model.getLoginName());
user.setName(model.getName());
user.setGender(model.getGender());
user.setPhoneNumber(model.getPhoneNumber());
user.setEmail(model.getEmail());
user.setDescription(model.getDescription());
// >> 处理关联的一个部门
user.setDepartment(departmentService.getById(departmentId));
// >> 处理管理的多个岗位
List<Role> roleList = roleService.getByIds(roleIds);
user.setRoles(new HashSet<Role>(roleList));
// 3.更新到数据库
userService.update(user);
return "toList";
}
/** 初始化密码为123456 */
public String initPassword() throws Exception {
// 从数据库中取出原对象
User user = userService.getById(model.getId());
// 设置要修改的属性,将密码加密
String md5 = DigestUtils.md5Hex("123456");
user.setPassword(md5);
// 保存到数据库
userService.update(user);
return "toList";
}
// getter/setter属性
}
-------------------------------------------------------------------------------------------
UserService接口
-------------------------------------------------------------------------------------------
public interface UserService extends DaoSupport<User>{
/**
* 根据用户名和密码查询用户
* @param loginName
* @param password 明文密码
* @return
*/
User findByLoginNameAndPassword(String loginName, String password);
}
-------------------------------------------------------------------------------------------
UserServiceImpl类:
-------------------------------------------------------------------------------------------
package cn.itcast.oa.service.impl;
@Service
@SuppressWarnings("unused")
public class UserServiceImpl extends DaoSupportImpl<User> implements UserService{
// DaoSupportImpl类中默认的save方法没有设置用户的默认密码,所有要在UserServiceImpl中复写save方法
@Override
public void save(User user) {
// 使用codec.digest.DigestUtils包的DigestUtils的md5Hex方法设置默认的密码为123456
String md5 = DigestUtils.md5Hex("123456");
user.setPassword(md5);
// 保存到数据库
getSession().save(user);
}
public User findByLoginNameAndPassword(String loginName, String password) {
String md5 = DigestUtils.md5Hex(password);
return (User) getSession().createQuery(//
"FROM User u WHERE u.loginName=? AND u.password=?")//
.setParameter(0, loginName)//
.setParameter(1, md5)//
.uniqueResult();
}
}
-------------------------------------------------------------------------------------------
页面。。。
相关文章推荐
- hibernate双向多对一(一对多)及自身一对多关联
- 评价中的星效果实现
- 面试时碰到的一道数据库题目
- 33.leetcode题目237: Delete Node in a Linked List
- java写文件
- 七牛---各种SDK Demo汇总
- linux 内核源代码目录结构
- IntelliJ IDEA windows与mac下常用快捷键
- S2SH的MVC模版
- IntelliJ IDEA 使用心得与常用快捷键IntelliJ IDEA 使用心得与常用快捷
- mina学习
- eclipse配置mybatis 的xml提示
- Wiki 开源软件
- C++中的输出格式 八进制 十进制 十六进制
- gtk 开发实践第二篇
- ccf 模板生成系统
- c++断言设置
- 购物商城shopping连载(11)
- 如何评估社交网络中信息内容的价值呢?
- HTTP报文