您的位置:首页 > 编程语言

SSH项目底层代码构建

2018-01-19 15:54 387 查看

持久层代码抽取:

IBaseDao接口:

/**
* 持久层通用接口
*
* @param <T>
*/
public interface IBaseDao<T> {
public void save(T entity);
public void delete(T entity);
public void update(T entity);
public T findById(Serializable id);
public List<T> findAll();
}BaseDaoImpl<T>实现类:
/**
* 持久层通用实现
* @param <T>
*/
public class BaseDaoImpl<T> extends HibernateDaoSupport implements IBaseDao<T> {
//代表的是某个实体的类型
private Class<T> entityClass;

@Resource//根据类型注入spring工厂中的会话工厂对象sessionFactory
public void setMySessionFactory(SessionFactory sessionFactory){
super.setSessionFactory(sessionFactory);
}

//在父类(BaseDaoImpl)的构造方法中动态获得entityClass
public BaseDaoImpl() {
ParameterizedType superclass = (ParameterizedType) this.getClass().getGenericSuperclass();
//获得父类上声明的泛型数组
Type[] actualTypeArguments = superclass.getActualTypeArguments();
entityClass = (Class<T>) actualTypeArguments[0];
}

public void save(T entity) {
this.getHibernateTemplate().save(entity);
}

public void delete(T entity) {
this.getHibernateTemplate().delete(entity);
}

public void update(T entity) {
this.getHibernateTemplate().update(entity);
}

public T findById(Serializable id) {
return this.getHibernateTemplate().get(entityClass, id);
}

public List<T> findAll() {
String hql = "FROM " + entityClass.getSimpleName();
return (List<T>) this.getHibernateTemplate().find(hql);
}
}

表现层代码抽取:

BaseAction代码:
/**
* 表现层通用实现
* @param <T>
*/
public class BaseAction<T> extends ActionSupport implements ModelDriven<T> {
//模型对象
private T model;
public T getModel() {
return model;
}

//在构造方法中动态获取实体类型,通过反射创建model对象
public BaseAction() {
ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
//获得BaseAction上声明的泛型数组
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
Class<T> entityClass = (Class<T>) actualTypeArguments[0];
//通过反射创建对象
try {
model = entityClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}测试:登陆功能举例1.创建UserAction,提供login登录方法:
@Controller
@Scope("prototype")
public class UserAction extends BaseAction<User> {
//属性驱动,接收页面输入的验证码
private String checkcode;
public void setCheckcode(String checkcode) {
this.checkcode = checkcode;
}

@Autowired
private IUserService userService;

/**
* 用户登录
*/
public String login(){
//从Session中获取生成的验证码
String validatecode = (String) ServletActionContext.getRequest().getSession().getAttribute("key");
//校验验证码是否输入正确
if(StringUtils.isNotBlank(checkcode) && checkcode.equals(validatecode)){
//输入的验证码正确
User user = userService.login(model);
if(user != null){
//登录成功,将user对象放入session,跳转到首页
ServletActionContext.getRequest().getSession().setAttribute("loginUser", user);
return HOME;
}else{
//登录失败,,设置提示信息,跳转到登录页面
//输入的验证码错误,设置提示信息,跳转到登录页面
this.addActionError("用户名或者密码输入错误!");
return LOGIN;
}
}else{
//输入的验证码错误,设置提示信息,跳转到登录页面
this.addActionError("输入的验证码错误!");
return LOGIN;
}
}
}提供UserService接口和实现类:@Service
@Transactional
public class UserServiceImpl implements IUserService{
@Autowired
private IUserDao userDao;
/***
* 用户登录
*/
public User login(User user) {
//使用MD5加密密码
String password = MD5Utils.md5(user.getPassword());
return userDao.findUserByUsernameAndPassword(user.getUsername(),password);
}
}
提供UserDao接口和实现类:@Repository
public class UserDaoImpl extends BaseDaoImpl<User> implements IUserDao {
/**
* 根据用户名和密码查询用户
*/
public User findUserByUsernameAndPassword(String username, String password) {
String hql = "FROM User u WHERE u.username = ? AND u.password = ?";
List<User> list = (List<User>) this.getHibernateTemplate().find(hql, username,password);
if(list != null && list.size() > 0){
return list.get(0);
}
return null;
}
}
配置struts.xml:<!-- 用户管理 -->
<action name="userAction_*" class="userAction" method="{1}">
<result name="login">/login.jsp</result>
<result name="home">/index.jsp</result>
</action>

扩展通用更新方法:

1. 在IBaseDao接口中添加更新方法
public void executeUpdate(String queryName, Object... objects);备注:Object... objects任意个参数,
2.在BaseDaoImpl中实现方法。
//执行更新
public void executeUpdate(String queryName, Object... objects) {
Session session = this.getSessionFactory().getCurrentSession();
Query query = session.getNamedQuery(queryName);
int i = 0;
for (Object object : objects) {
//为HQL语句中的?赋值
query.setParameter(i++, object);
}
//执行更新
query.executeUpdate();
}3.在.xml映射文件中定义更新语句,举例:根据id更新用户密码实现
<query name="user.editpassword">
UPDATE User SET password = ? WHERE id = ?
</query>4.在UserService中提供修改密码方法
/**
* 根据用户id修改密码
*/
public void editPassword(String id, String password) {
//使用MD5加密密码
password = MD5Utils.md5(password);
userDao.executeUpdate("user.editpassword", password,id);
}这里的user.editpassword为xml映射文件中定义的id名。userDao继承baseDao,直接调用更新方法。5.controller中

/**
* 修改当前用户密码
* @throws IOException
*/
public String editPassword() throws IOException{
String f = "1";
//从session中获取当前登录用户
User user = BOSUtils.getLoginUser();
try{
userService.editPassword(user.getId(),model.getPassword());
}catch(Exception e){
f = "0";
e.printStackTrace();
}
ServletActionContext.getResponse().setContentType("text/html;charset=utf-8");
ServletActionContext.getResponse().getWriter().print(f);
return NONE;
}

扩展分页查询通用方法:

前端参考,将静态HTML渲染为datagrid样式文章结合来看更清晰。
1.包装PageBean工具类:封装分页相关的属性,生成get,set方法。
/**
* 封装分页属性
*/
public class PageBean {
private int currentPage;//当前页码
private int pageSize;//每页显示的记录数
private DetachedCriteria detachedCriteria;//查询条件
private int total;//总记录数
private List rows;//当前页需要展示的数据集合
2.在BaseDao中扩展通用分页查询方法
/**
* 通用分页查询方法
*/
public void pageQuery(PageBean pageBean) {
int currentPage = pageBean.getCurrentPage();
int pageSize = pageBean.getPageSize();
DetachedCriteria detachedCriteria = pageBean.getDetachedCriteria();

//查询total---总数据量
detachedCriteria.setProjection(Projections.rowCount());//指定hibernate框架发出sql的形式----》select count(*) from bc_staff;
List<Long> countList = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
Long count = countList.get(0);
pageBean.setTotal(count.intValue());

//查询rows---当前页需要展示的数据集合
detachedCriteria.setProjection(null);//指定hibernate框架发出sql的形式----》select * from bc_staff;
int firstResult = (currentPage - 1) * pageSize;
int maxResults = pageSize;
List rows = this.getHibernateTemplate().findByCriteria(detachedCriteria, firstResult, maxResults);
pageBean.setRows(rows);
}3.在demoAction中定义分页查询方法,别忘了继承baseAction。
//属性驱动,接收页面提交的分页参数
private int page;
private int rows;

/**
* 分页查询方法
* @throws IOException
*/
public String pageQuery() throws IOException{
PageBean pageBean = new PageBean();
pageBean.setCurrentPage(page);
pageBean.setPageSize(rows);
//创建离线提交查询对象
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(Demo.class);
pageBean.setDetachedCriteria(detachedCriteria);
demoService.pageQuery(pageBean);

//使用json-lib将PageBean对象转为json,通过输出流写回页面中
//JSONObject---将单一对象转为json
//JSONArray----将数组或者集合对象转为json
JsonConfig jsonConfig = new JsonConfig();
//指定哪些属性不需要转json
jsonConfig.setExcludes(new String[]{"currentPage","detachedCriteria","pageSize"});
String json = JSONObject.fromObject(pageBean,jsonConfig).toString();
ServletActionContext.getResponse().setContentType("text/json;charset=utf-8");
ServletActionContext.getResponse().getWriter().print(json);
return NONE;
}4.demoService
public void pageQuery(PageBean pageBean){
demoDao.pageQuery(pageBean);
};5demoDao继承baseDao

重构分页代码:

将重复分页代码统一抽取到BaseAction中
/**
* 表现层通用实现
* @param
c5b9
<T>
*/
public class BaseAction<T> extends ActionSupport implements ModelDriven<T> {
protected PageBean pageBean = new PageBean();
//创建离线提交查询对象
DetachedCriteria detachedCriteria = null;

public void setPage(int page) {
pageBean.setCurrentPage(page);
}

public void setRows(int rows) {
pageBean.setPageSize(rows);
}

/**
* 将指定Java对象转为json,并响应到客户端页面
* @param o
* @param exclueds
*/
public void java2Json(Object o ,String[] exclueds){
JsonConfig jsonConfig = new JsonConfig();
//指定哪些属性不需要转json
jsonConfig.setExcludes(exclueds);
String json = JSONObject.fromObject(o,jsonConfig).toString();
ServletActionContext.getResponse().setContentType("text/json;charset=utf-8");
try {
ServletActionContext.getResponse().getWriter().print(json);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 将指定Java对象转为json,并响应到客户端页面
* @param o
* @param exclueds
*/
public void java2Json(List o ,String[] exclueds){
JsonConfig jsonConfig = new JsonConfig();
//指定哪些属性不需要转json
jsonConfig.setExcludes(exclueds);
String json = JSONArray.fromObject(o,jsonConfig).toString();
ServletActionContext.getResponse().setContentType("text/json;charset=utf-8");
try {
ServletActionContext.getResponse().getWriter().print(json);
} catch (IOException e) {
e.printStackTrace();
}
}

public static final String HOME = "home";
public static final String LIST = "list";

//模型对象
protected T model;
public T getModel() {
return model;
}

//在构造方法中动态获取实体类型,通过反射创建model对象
public BaseAction() {
ParameterizedType genericSuperclass = (ParameterizedType) this.getClass().getGenericSuperclass();
//获得BaseAction上声明的泛型数组
Type[] actualTypeArguments = genericSuperclass.getActualTypeArguments();
Class<T> entityClass = (Class<T>) actualTypeArguments[0];
detachedCriteria = DetachedCriteria.forClass(entityClass);
pageBean.setDetachedCriteria(detachedCriteria);
//通过反射创建对象
try {
model = entityClass.newInstance();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
}
}
}在demoAction中,就可以简化了 public String pageQuery() throws IOException{

demoService.pageQuery(pageBean);
//指定哪些属性不需要转
jsonthis.java2json(pageBean,new String[]{"currentPage","detachedCriteria","pageSize"});
return NONE;
}

带查询条件的:

前端需要datagrid配合使用,请参考文章”datagrid数据表格使用方法“。
后端实现

public String pageQuery(){
DetachedCriteria dc = pageBean.getDetachedCriteria();
//动态添加过滤条件
String addresskey = model.getAddresskey();
if(StringUtils.isNotBlank(addresskey)){
//添加过滤条件,根据地址关键字模糊查询
dc.add(Restrictions.like("addresskey", "%"+addresskey+"%"));
}

Region region = model.getRegion();
if(region != null){
String province = region.getProvince();
String city = region.getCity();
String district = region.getDistrict();
dc.createAlias("region", "r");
if(StringUtils.isNotBlank(province)){
//添加过滤条件,根据省份模糊查询-----多表关联查询,使用别名方式实现
//参数一:分区对象中关联的区域对象属性名称
//参数二:别名,可以任意
dc.add(Restrictions.like("r.province", "%"+province+"%"));
}
if(StringUtils.isNotBlank(city)){
//添加过滤条件,根据市模糊查询-----多表关联查询,使用别名方式实现
//参数一:分区对象中关联的区域对象属性名称
//参数二:别名,可以任意
dc.add(Restrictions.like("r.city", "%"+city+"%"));
}
if(StringUtils.isNotBlank(district)){
//添加过滤条件,根据区模糊查询-----多表关联查询,使用别名方式实现
//参数一:分区对象中关联的区域对象属性名称
//参数二:别名,可以任意
dc.add(Restrictions.like("r.district", "%"+district+"%"));
}
}
subareaService.pageQuery(pageBean);
this.java2Json(pageBean, new String[]{"currentPage","detachedCriteria","pageSize",
"decidedzone","subareas"});
return NONE;
}
修改BaseDao中的分页查询方法
/**
* 通用分页查询方法
*/
public void pageQuery(PageBean pageBean) {
int currentPage = pageBean.getCurrentPage();
int pageSize = pageBean.getPageSize();
DetachedCriteria detachedCriteria = pageBean.getDetachedCriteria();

//查询total---总数据量
detachedCriteria.setProjection(Projections.rowCount());//指定hibernate框架发出sql的形式----》select count(*) from bc_staff;
List<Long> countList = (List<Long>) this.getHibernateTemplate().findByCriteria(detachedCriteria);
Long count = countList.get(0);
pageBean.setTotal(count.intValue());

//查询rows---当前页需要展示的数据集合
detachedCriteria.setProjection(null);//指定hibernate框架发出sql的形式----》select * from bc_staff;
//指定hibernate框架封装对象的方式
detachedCriteria.setResultTransformer(DetachedCriteria.ROOT_ENTITY);
int firstResult = (currentPage - 1) * pageSize;
int maxResults = pageSize;
List rows = this.getHibernateTemplate().findByCriteria(detachedCriteria, firstResult, maxResults);
pageBean.setRows(rows);
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ssh