这一篇将如何实现一个具体的业务为基准,后面颗粒度不会像这样细。只会把业务逻辑梳理好
以管理员登录和退出 业务为中心
搭建POJO
根据数据库中,管理员的字段很容易创建pojo
package cn.hy.po;
import java.io.Serializable;
/**
* 管理员
*/
public class Manage implements Serializable {
/**主键*/
private Integer id;
/**登录名*/
private String userName;
/**密码*/
private String passWord;
/**姓名*/
private String realName;
public Manage(Integer id, String userName, String passWord, String realName) {
this.id = id;
this.userName = userName;
this.passWord = passWord;
this.realName = realName;
}
public Manage() {
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassWord() {
return passWord;
}
public void setPassWord(String passWord) {
this.passWord = passWord;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
@Override
public String toString() {
return "Manage{" +
"id=" + id +
", userName='" + userName + '\'' +
", passWord='" + passWord + '\'' +
", realName='" + realName + '\'' +
'}';
}
}
生成Dao
这里可以使用之前提到的mybatis那个插件,直接生成,甚至连pojo都可以自动生成。
不过up主的逻辑是把所有的方法都抽取成一个公共接口,接口分离原则
package cn.hy.base;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.annotations.Param;
/**
* 基础dao封装一些简单的方法
* @author
*
*/
public interface BaseDao<T>{
/**
* 插入一个实体
* @param entity
*/
int insert(T entity) ;
/**
* 根据实体主键删除一个实体
*/
void deleteById(Serializable id);
/**
* 通过实体删除
* @param entity
*/
void deleteByEntity(T entity);
/**
* 通过map删除
* @param params
*/
void deleteByMap(Map<String, Object> params);
/**
* 更新一个实体
* @param entity
*/
void update(T entity);
/**
* 通过id进行修改
*/
void updateById(T entity);
/**
* 根据参数查询
*/
public List<T> listByMap(Map<String, Object> params);
/**
* 查询所有实体
* @return
*/
List<T> listAll();
/**
* 查询所有实体,根据实体属性值为判断条件查询所有实体,
* @param entity
* @return
*/
List<T> listAllByEntity(T entity);
/**
* 根据主键获取一个实体
* @param id
* @return
*/
T load(Serializable id);
/**
* 根据主键获取一个实体
* @param id
* @return
*/
T getById(Serializable id);
/**
* 根据map查询--不分页
* @param params
* @return
*/
T getByMap(Map<String, Object> params);
/**
* 通过对象查询--不分页
*/
public T getByEntity(T entity);
/**
* 通过map查询分页
*/
public List<T> findByMap(Map<String, Object> params);
/**
* 通过对象查询分页
*/
public List<T> findByEntity(T entity);
/**
* 批量新增
* @param list
*/
public void insertBatch(List<T> list);
/**
* 批量修改
* @param list
*/
public void updateBatch(List<T> list);
//==============================封装纯sql语法================================
/**
* 查询一个对象返回map
* @param sql
* @return
*/
public Map<String,Object> getBySqlReturnMap(@Param("sql") String sql);
/**
* 查询一个对象返回实体类
* @param sql
* @return
*/
public T getBySqlReturnEntity(@Param("sql") String sql);
/**
* 查询列表返回map
* @param sql
* @return
*/
public List<Map<String,Object>> listBySqlReturnMap(@Param("sql") String sql);
/**
* 查询列表返回实体
* @param sql
* @return
*/
public List<T> listBySqlReturnEntity(@Param("sql") String sql);
/**
* 查询分页
* @param sql
* @return
*/
public List<T> findBySqlRerturnEntity(@Param("sql") String sql);
/**
* 通过sql修改
* @param sql
*/
public void updateBysql(@Param("sql") String sql);
/**
* 通过sql删除
* @param sql
*/
public void deleteBySql(@Param("sql") String sql);
}
管理员接口继承上面这个公共接口
package cn.hy.mapper;
import cn.hy.base.BaseDao;
import cn.hy.po.Manage;
/**
* 管理员
*/
public interface ManageMapper extends BaseDao<Manage> {
}
然后就是就是写mapper配置sql语句,由于方法太多了,这里就不展示了
搭建service层
同样的,抽取一个公共的service接口,以及实现。后期应该会把一些比较重要的单独拎出来讲一下,比如分页的逻辑。
package cn.hy.service;
import cn.hy.base.BaseService;
import cn.hy.po.Manage;
public interface ManageService extends BaseService<Manage> {
}
实现类 这里需要特别注意的是,在写实现的时候,别忘记添加Service的注解
package cn.hy.service.impl;
import cn.hy.base.BaseDao;
import cn.hy.base.BaseServiceImpl;
import cn.hy.mapper.ManageMapper;
import cn.hy.po.Manage;
import cn.hy.service.ManageService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ManageServiceImpl extends BaseServiceImpl<Manage> implements ManageService {
@Autowired
ManageMapper manageMapper;
@Override
public BaseDao<Manage> getBaseDao() {
return manageMapper;
}
}
Controller层
up主是以业务功能去分模块,比如登录与注册、留言、公告这样的业务逻辑去分。
同样的,抽取出公共的接口为BaseController
package cn.hy.base;
import java.io.Serializable;
import java.util.Collection;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.alibaba.fastjson.JSONObject;
/**
* Controller基类
*/
public class BaseController {
protected Logger logger = LoggerFactory.getLogger(this.getClass());
protected final static String DATE_FORMATE = "yyyy-MM-dd";
/**
* 返回服务端处理结果
*
* @param obj
* 服务端输出对象
* @return 输出处理结果给前段JSON格式数据
*/
public String responseResult(Object obj) {
String jsonObj = null;
if (obj != null) {
logger.info("后端返回对象:{}", obj);
jsonObj = JSONObject.toJSONString(obj);
logger.info("后端返回数据:" + jsonObj);
}
logger.info("输出结果:{}", jsonObj);
return jsonObj;
}
// 下面是判断null的操作
public boolean isEmpty(String str) {
return (null == str) || (str.trim().length() <= 0);
}
public boolean isEmpty(Character cha) {
return (null == cha) || cha.equals(' ');
}
public boolean isEmpty(Object obj) {
return (null == obj);
}
public boolean isEmpty(Object[] objs) {
return (null == objs) || (objs.length <= 0);
}
public boolean isEmpty(Collection<?> obj) {
return (null == obj) || obj.isEmpty();
}
public boolean isEmpty(Set<?> set) {
return (null == set) || set.isEmpty();
}
public boolean isEmpty(Serializable obj) {
return null == obj;
}
public boolean isEmpty(Map<?, ?> map) {
return (null == map) || map.isEmpty();
}
/**
*
* 获得map
* @return
*/
public Map<String,Object> getMap(){
return new HashMap<String,Object>();
}
}
先把controller搭建起来,同样的需要controller的注解
@RequestMapping("/login")是将请求与处理方法一一对应
SpringMvc具有依赖注入的优点,用@Autowired注解将依赖注入到一个属性或方法里
/**
* 登录
*/
@Controller
@RequestMapping("/login")
public class LoginController extends BaseController {
@Autowired
ManageService manageService;
}
实现登录,首先需跳转到登陆页面。即用户请求/login/login,服务器响应把/login/mLogin.jsp返回给用户
/**
* 管理员登录前
* @return
*/
@RequestMapping("login")
public String login(){
return "/login/mLogin";
}
管理员输入账号与密码,提交登录
我们用Manage实体去接受前端传来的参数,查询manage对象是否存在。
存在则在request域中保存登录的信息,并返回到管理员登陆后的节目mIndex.jsp
如果不存在,就重定向到mQuit.jsp
/**
* 登录验证
* @return
*/
@RequestMapping("toLogin")
public String toLogin(Manage manage, HttpServletRequest request){
Manage byEntity=manageService.getByEntity(manage);
//判断是否存在
if(null==byEntity){
return "redirect:/login/mQuit";
}
request.getSession().setAttribute(Consts.MANAGE,byEntity);
return "/login/mIndex";
}
逻辑大概是上面这样,我们仔细去看实现
manageService是继承了BaseService的getByEntiy方法
/**
* 通过对象查询
* @param entity
* @return
*/
T getByEntity(T entity);
而在mapper是这样实现的
<!-- 声明数据库字段 -->
<sql id="Manage_field">
id,userName,passWord,realName
</sql>
<!-- 查询时条件 -->
<sql id="Manage_where">
<if test="id != null">
and id = #{id}
</if>
<if test="userName != null">
and userName = #{userName}
</if>
<if test="passWord != null">
and passWord = #{passWord}
</if>
<if test="realName != null">
and realName = #{realName}
</if>
</sql>
<!--通过对象查询-不分页-->
<select id="getByEntity" resultMap="ResultMapManage" parameterType="cn.hy.po.Manage">
select <include refid="Manage_field"/>
from manage where 1=1
<include refid="Manage_where"/>
</select>
不得不说,这样抽取是方便高效
另外代码已经放入github中,这些经过我的亲自上手,似乎更加简单直白。