项目第二天 Employee的父类抽取 删除

要完成的功能

  • 父类的抽取
  • 删除功能
  • 查询功能

在我们完成这些功能之前 我们还需要做的一件事就是 就是给每一层抽取一个父类
那为什么要抽取一个父类呢
抽取父类有利于我们以后扩展代码 也就是扩展性强。还有就是做相应的规范,哪怕父类一句代码都没有也要写一个父类

父类的抽取

domain的父类抽取

/**
 * 泛化(继承) -> 父类
 *      告诉JPA,这是一个domain的父类(继承的时候才会用到字段)
 *      这个注解不会持久化到表
 */
 
@MappedSuperclass
public class BaseDomain {

    @Id
    @GeneratedValue
    protected Long id;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }
}

query的父类抽取

public abstract class BaseQuery {

    //当前页
    private int currentPage = 1;
    //每页条数
    private int pageSize = 10;
    //排序字段名字(如果这个值不存在,就不排序)
    private String orderName;
    //排序规则 true:升序  false:降序
    private boolean orderType = true;

    //这里加一个抽象方法,可以保证子类都去实现
    public abstract Specification createSpec();

    //创建排序对象
    public Sort createSort() {
        //1.只有orderName不为空,才进行排序
        if (StringUtils.isNotBlank(orderName)) {
            Sort sort = new Sort(orderType ? Sort.Direction.ASC : Sort.Direction.DESC, orderName);
            return sort;
        }
        return null;
    }

    public int getCurrentPage() {
        return currentPage;
    }

    //专门为SpringDataJpa的分页(从0开始)
    public int getJpaPage() {
        return currentPage - 1;
    }

由于我们还要集成EasyUI 所以还需要添加一下两个方法

 //兼容EasyUI的当前页数据
    public void setPage(int page) {
        this.currentPage = page;
    }

 //兼容EasyUI的每页条数
    public void setRows(int rows) {
        this.pageSize = rows;
    }

Repository的父类抽取

/**
 *  JPA里面,它的domain的id,都必需是实现序列化接口
 * 这个BaseRepository是一个父类(无法确定类型的)
 * @param <T>
 * @param <ID>
 *     @NoRepositoryBean:告诉Spring,不要去实现这个接口(原因是spring会去实现这个父接口 所以)
 */
@NoRepositoryBean
public interface BaseRepository<T,ID extends Serializable>
        extends JpaRepository<T,ID>, JpaSpecificationExecutor<T> {
}

service的父类抽取

先抽取service的父类接口

/**
 *  业务层的父类
 *  传一个范型 用来之类具体接收要操作的domain
 *  后面的id是继承序列化
 */
public interface IBaseService<T,ID extends Serializable> {

    //添加与修改是同一个
    void save(T t);
    void delete(ID id);
    T findOne(ID id);
    List<T> findAll();
    //1.根据查询条件查找对应的数据
    List<T> queryAll(BaseQuery query);
    //2.根据查询条件查找到对应的分页数据
    Page<T> queryPage(BaseQuery query);
    //3.根据JPQL进行查询
    /**
     * select o.username from Employee o where o.username like ? and o.email like ? ..
     */
    List<Object> queryByJpql(String jpql,Object... params);

接着抽取service的实现父类

/**
 *  父类的实现类
 * @Transactional  事务的注解 以后还是查询多
 *
 * @param <T>
 * @param <ID>
 */
@Transactional(readOnly = true,propagation = Propagation.SUPPORTS)
public abstract class BaseServiceImpl<T,ID extends Serializable> implements IBaseService<T, ID > {

    //注入父类的dao 实际上是所有子接口的实现
    @Autowired
    private BaseRepository<T,ID > baseRepository;
    /**
     *  为了解决扩展的JPQL 因为baseRepository 是没有这个功能的
     *
     */
    @PersistenceContext
    private EntityManager entityManager;

    //添加或者修改
    @Override
    @Transactional
    public void save(T t) {
        baseRepository.save(t);
    }

    //删除
    @Override
    @Transactional
    public void delete(ID id) {
        baseRepository.delete(id);

    }

    //查询一条数据
    @Override
    public T findOne(ID id) {
        return baseRepository.findOne(id);
    }

    //查询所有
    @Override
    public List<T> findAll() {
        return baseRepository.findAll();
    }

    //根据条件对象查询
    @Override
    public List<T> queryAll(BaseQuery query) {
        // 拿到排序
        Sort sort  = query.createSort();
        //拿到查询规则
        Specification spec = query.createSpec();
        //进行查询
        List<T> list = baseRepository.findAll(spec, sort);
        return list;
    }

    //分页查询
    @Override
    public Page<T> queryPage(BaseQuery query) {
        //拿到排序和分页
        Sort sort = query.createSort();
        Pageable pageable = new PageRequest(query.getJpaPage(),query.getPageSize(),sort);
        //拿到查询规则
        Specification spec = query.createSpec();
        //查询数据
        Page<T> page = baseRepository.findAll(spec, pageable);
        return page;
    }

    //解决特殊的查询 自己写JQPL
    @Override
    public List<Object> queryByJpql(String jpql, Object... params) {
        //这里应该是拿到query 对象
        Query query = entityManager.createQuery(jpql);
        //然后把数据放到query 中
        for (int i = 0;i<params.length;i++){
            query.setParameter(i+1, params[i]);
        }
        //返回结果集
        return query.getResultList();
    }
}

最后就是controller的父类抽取

这个里面就是一句代码都没有

public class BaseController {
}

总结父类抽取

当我们把每个层的父类抽取好以后 我们后面实现功能就很快了 那简直就是一帆风顺呀!只需要继承父类就好!

删除功能的完成

集成前台页面

我们把所有公共的引入(css,js) 都放在head.jsp中
以后要使用easyui直接引入即可

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%--引入easyui中的基本的CSS与JS--%>
<link rel="stylesheet" type="text/css" href="/easyui/themes/default/easyui.css">
<%--图标样式--%>
<link rel="stylesheet" type="text/css" href="/easyui/themes/icon.css">
<%--支持风格的包--%>
<link rel="stylesheet" type="text/css" href="/easyui/themes/color.css">

<script type="text/javascript" src="/easyui/jquery.min.js"></script>
<script type="text/javascript" src="/easyui/jquery.easyui.min.js"></script>
<%--引入国际化的js--%>
<script type="text/javascript" src="/easyui/locale/easyui-lang-zh_CN.js"></script>

employee的jsp页面

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
    <%--引入公共的jsp--%>
    <%@ include file="/WEB-INF/views/head.jsp" %>
    <%--引入当前模板对应的js--%>
    <script src="/js/model/employee.js"></script>
</head>
<body>
<div id="toolbar">
    <%--iconCls:图标  plain:简洁--%>
    <a href="javascript:;" data-method="add" class="easyui-linkbutton" data-options="iconCls:'icon-add',plain:true">添加</a>
    <a href="javascript:;" data-method="update" class="easyui-linkbutton" data-options="iconCls:'icon-edit',plain:true">修改</a>
    <a href="javascript:;" data-method="delete" class="easyui-linkbutton" data-options="iconCls:'icon-remove',plain:true">删除</a>
</div>
<%--展示数据使用datagrid组件
    url:请求路径(数据)  fit:自适应父容器
    fitColumns:列的自适应 singleSelect:是否单选
    pagination:分页工具栏
    ctrl+shift+delete
--%>

<table class="easyui-datagrid"
       data-options="url:'/employee/page',fitColumns:true,singleSelect:true,fit:true,toolbar:'#toolbar',pagination:true">
    <thead>
    <tr>
        <th data-options="field:'username',width:100">用户名</th>
        <th data-options="field:'password',width:100">密码</th>
        <th data-options="field:'age',width:100">年龄</th>
        <th data-options="field:'email',width:100">邮箱</th>
    </tr>
    </thead>
</table>


</body>
</html>

employee的js

我们一个模块需要一个功能 所有需要单独建与之对应的js
这里只是集成相关的js 也就是相当于一个模板 然后要完成相应的功能直接写就好

//入口函数:页面读取所有元素再执行
$(function () {

    //只要有data-method属性的元素我都要为它注册事件
    $("*[data-method]").on("click",function () {
        //谁调用,this就指向谁(这个this是普通dom对象)
        //$(dom对象) -> 变成jQuery对象,有很多jQuery特有的功能(更加强大)
        //console.debug($(this));
        //1.拿到当前按键的属性 add,update
        //var methodName = $(this).attr("data-method");
        //var methodName = $(this).data("method");
        //2.执行对应的方法(动态调用)
        //  itsource.say() == itsource["say"]();
        itsource[$(this).data("method")]();
    })


    //准备了相应的方法功能
    itsource = {
        add:function(){
            alert("add")
        },
        update:function () {
            alert("update")
        },
        delete:function () {
            //1.拿到你选择的那一条数据 (easyui的datagrid中有这个功能)
            //2.如果没有拿到数据,给一个提示,让他选中再执行(后面的代码就不运行) Messager alert
            //3.如果拿到数据,给一个提示,是否要删除? Messager confirm
            //4.如果要删除 -> 发送Ajax请求到后台进行数据删除 $.get/post("/employee/delete",{id:2},function(){....})
            //  后台会返回相应的数据 :{success:true/false,msg:xxx}
            //  如果成功,刷新datagrid
        }
    };
})

EmployeeController提供删除功能

/**
 * 前台会传一个id过来
 *  需要返回:{success:true/false,msg:"xx"}
 *     返回这种结构有两种方法:1种是写map, 1种是直接返回对象
 */
@RequestMapping("/delete")
@ResponseBody
public JsonResult delete(Long id){
    try {
        employeeService.delete(id);
        return new JsonResult();
    } catch (Exception e) {
        e.printStackTrace();
        //失败后返回的结果
        return new JsonResult(false,e.getMessage());
    }
}

employee.js完成删除

 delete () {
    //1.拿到你选择的那一条数据 (easyui的datagrid中有这个功能)
    //  row就是你选择的这一行的数据
    var row = employeeDataGrid.datagrid("getSelected");
    //2.如果没有拿到数据,给一个提示,让他选中再执行(后面的代码就不运行) Messager alert
    if(row==null){
        //alert("没有货,滚蛋!"); //不建议使用 1.不同浏览器效果不一样 2.它会阻塞进程
        $.messager.alert('警告','没有货,滚蛋!',"info");
        return;
    }
    //3.如果拿到数据,给一个提示,是否要删除? Messager confirm
    $.messager.confirm('确认','您要狠心的干掉我嘛?',function(r){
        if (r){
            //4.如果要删除 -> 发送Ajax请求到后台进行数据删除 $.get/post("/employee/delete",{id:2},function(){....})
            //  后台会返回相应的数据 :{success:true/false,msg:xxx}
            //  如果成功,刷新datagrid
            $.get("/employee/delete",{id:row.id},function (result) {
                if(result.success){
                    //删除成功,刷新datagrid
                    employeeDataGrid.datagrid("reload");
                }else{
                    //删除失败,给出失败提示
                    $.messager.alert('失败','删除没有成功,原因是:'+result.msg,"error");
                }
            })
        }
    });
},

总结

今天的重点就是父类的是抽取!为啥这样说呢!在我们以往写代码都养成了一种惯性的思维,几乎就不会想到每个层去抽取父类。所以 这是一种代码思维的转变,需要好好的理解一番!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值