1.数据库的创建:

    create table todo(
 id integer primary key,
 title varchar(50),
 todoclassid integer,
 state integer,
 create_dt datetime,
 modify_dt datetime
);
create table todoclass(
 id integer primary key,
 name varchar(30),
 parentid integer
);

2.html页面代码展示:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>TODOLIST</title>
<meta http-equiv="X-UA-Compatible" content="IE-edge">
<meta name="viewport" content="width=device-width,initial-scale=1"/>
<link rel="stylesheet" type="text/css" href="./bootstrap-3.3.7-dist/css/bootstrap.min.css" />
<script src="./js/vue.js"></script>
<script src="./js/axios.min.js"></script>
</head>
<body>
<div class="container" id="app">
<div class="row">
<div class="col-md-12">
<div class="page-header">
<h1>JAVA的TODOLIST</h1>
</div>
</div>
</div>
<div class="row">
<div class="col-md-4">
<form class="form form-inline">
<div class="form-group form-group-sm">
<input type="text" class="form-control" v-model="todoclassname" placeholder="请输入分类名称" />
<button type="button" class="btn btn-primary" v-on:click="addtodoclass('0')">添加同级</button>
<button type="button" class="btn btn-info" v-on:click="addtodoclass('1')">添加下级</button>
</div>
</form>
<ul class="nav nav-pills nav-stacked">
<li v-for="(item,index) in todoclasses" v-on:click="changetodoclass(item,index)">
<a href="#"> {{item.todoclass.name}}</a></li>
</ul>
</div>
<div class="col-md-8">
<form class="form form-inline">
<div class="form-group">
<input type="text" class="form-control" v-model="todotitle" placeholder="请输入待办事项名称" />
<button type="button" class="btn btn-primary" v-on:click="addtodo()">添加</button>

            </div>
        </form>
        <div class="list-group">
            <a href="#" class="list-group-item" v-for="(item,index) in currenttodoclass.todos">
                <span class="badge label-success" v-if="item.state==1">已完成</span>
                <span class="badge label-info" v-if="item.state==0" v-on:click="updatastate(item)">未完成</span>
                <span class="badge label-info" v-on:click="deltetodo(item)">删除</span>
                {{index+1}}.{{item.title}}【{{item.create_dt}}】
            </a>
        </div>

    </div>
</div>

</div>
</body>
</html>
<script type="text/javascript">
var vue=new Vue({
el:"#app",
data:{
index:0,
msg:'helloworld',
todoclassname:'',
todotitle:'',
currenttodoclass:{
todoclass:{
id:1,
name:"学习"
},
todos:[

            ]
        },
        todoclasses:[]
    },
    methods:{
        updatastate:function (item){
            if(confirm("确定事情已经做完了吗?")) {
                var param = '';
                param = "id=" + item.id;
                axios.post('/todo/updatetodo.wst', param).then(function (result) {
                    if (result.status == 200) {
                        console.log(result);
                        alert("保存成功!");
                        vue.init();
                    }
                })
            }
        },
        changetodoclass:function(item,index){
            this.index=index;
            this.currenttodoclass=item;
        },
        addtodoclass:function(level){
            var param='';
            param="todoclassname="+this.todoclassname;
            axios.post('/todo/savetodoclass.wst',param).then(function(result){

                    if(result.status==200){
                        console.log(result);
                         alert("保存成功!");
                         vue.init();
                    }

//
}).catch(function(err){
console.error(err);
alert('网络异常');
});

        },
        addtodo:function(){
            var param='';
            param='todoclassid='+this.currenttodoclass.todoclass.id+'&title='+this.todotitle;
            axios.post("/todo/savetodo.wst",param).then(function (result) {
                if(result.status==200){
                    console.log(result);
                    alert("保存成功!");
                    vue.init();
                }
            })

        },
        deltetodo:function(item){
            if(confirm("您确定要删除吗?")){
                var param=''
                param="id="+item.id
                axios.post('/todo/deletetodo.wst',param).then(function(result){
                    if(result.status==200){
                        console.log(result);
                        alert("保存成功!");
                        vue.init();
                    }
                })
            }
        },
        init:function(){
            axios.get('/todo/listtodoclasses.wst').then(function(result){
                console.log(result);
                while(vue.todoclasses.length>0){
                    vue.todoclasses.pop();
                }
                for(var i=0;i<result.data.todoclasses.length;i++){
                    vue.todoclasses.push(result.data.todoclasses[i]);
                }

                vue.currenttodoclass=vue.todoclasses[vue.index];
                vue.todoclassname='';
                vue.todotitle=''
            }).catch(function(err){
                console.error(err);
                alert('网络异常');
            });
        }
    },
    mounted:function(){
        console.log('inited');
        this.init();

    }
});

</script>
结果展示:
TODOLIST完整版

3.Java代码部分展示

TODOLIST完整版

Controller层:
public class TodoController {
// xxx/todo/listtodoclasses.wst
public TodoVO listtodoclasses(HttpServletRequest req, HttpServletResponse response){
TodoService todoService=new TodoServiceImpl();
List<TodoClassVO> result = todoService.listTodoClasses(null);
TodoVO todoVO=new TodoVO();
todoVO.setTodoclasses(result);
return todoVO;
}

// xxx/todo/savetodoclass.wst
public Boolean savetodoclass(HttpServletRequest req, HttpServletResponse response){
    TodoService todoService=new TodoServiceImpl();
    TodoClass todoClass=new TodoClass();
    todoClass.setName(req.getParameter("todoclassname"));
    Boolean result=todoService.saveTodoClass(todoClass);
    return result;
}

// xxx/todo/savetodo.wst
public Boolean savetodo(HttpServletRequest req, HttpServletResponse response){
    TodoService todoService=new TodoServiceImpl();
    Todo todo=new Todo();
    Date date =new Date();
    todo.setCreate_dt(date);
    todo.setState(0);
    todo.setTitle(req.getParameter("title"));
    todo.setTodoclassid(Integer.parseInt(req.getParameter("todoclassid")));
    Boolean result=todoService.saveTodo(todo);
    return result;
}

// xxx/todo/updatetodo.wst
public Boolean updatetodo(HttpServletRequest req, HttpServletResponse response){
    TodoService todoService=new TodoServiceImpl();
    Boolean result=todoService.updateTodo(Integer.parseInt(req.getParameter("id")));
    return result;
}

public Boolean deletetodo(HttpServletRequest req,HttpServletResponse response ){
    TodoService todoService=new TodoServiceImpl();
    Boolean result=todoService.deletetodo(Integer.parseInt(req.getParameter("id")));
    return result;
}

}
Service层
接口:
public interface TodoService {
/**

  • 获取所有的todo分类
  • @return
    */
    List<TodoClassVO> listTodoClasses(Integer parentid);

    /**

  • 保存Todo分类
  • @param todoClass
  • @return
    */
    Boolean saveTodoClass(TodoClass todoClass);

    Boolean saveTodo(Todo todo);

    Boolean updateTodo(Integer todoid);

    Boolean deletetodo(Integer todoid);
    }
    实现接口
    public class TodoServiceImpl implements TodoService {

    @Override
    public List<TodoClassVO> listTodoClasses(Integer parentid) {
    SqlSession sqlSession = MybatisUtil.getInstance().getSqlSessionFactory().openSession();
    TodoDAO dao=sqlSession.getMapper(TodoDAO.class);
    List<TodoClassVO> result=new ArrayList<>();
    try{
    List<TodoClass> root = dao.listTodoClassesByParentid(parentid);
    for(TodoClass tc:root){
    TodoClassVO todoClassVO=new TodoClassVO();
    todoClassVO.setTodoclass(tc);
    todoClassVO.setTodos(dao.listTodosByClassid(tc.getId()));
    todoClassVO.setTodoclassvolist(listTodoClasses(tc.getId()));
    result.add(todoClassVO);
    }
    return result;
    }finally {
    sqlSession.close();
    }

    }

    @Override
    public Boolean saveTodoClass(TodoClass todoClass) {
    SqlSession sqlSession = MybatisUtil.getInstance().getSqlSessionFactory().openSession();
    TodoDAO dao=sqlSession.getMapper(TodoDAO.class);
    int result=0;
    try {
    result=dao.saveTodoClass(todoClass);
    sqlSession.commit();
    }finally{
    sqlSession.close();
    }
    return result>0;
    }

    @Override
    public Boolean saveTodo(Todo todo) {
    SqlSession sqlSession = MybatisUtil.getInstance().getSqlSessionFactory().openSession();
    TodoDAO dao=sqlSession.getMapper(TodoDAO.class);
    int result =0;
    try {
    result= dao.saveTodo(todo);
    sqlSession.commit();
    }finally {
    sqlSession.close();
    }

    return result>0;

    }

    @Override
    public Boolean updateTodo(Integer todoid) {
    SqlSession sqlSession = MybatisUtil.getInstance().getSqlSessionFactory().openSession();
    TodoDAO dao=sqlSession.getMapper(TodoDAO.class);
    int result =0;
    try {
    result= dao.updateTodo(todoid);
    sqlSession.commit();
    }finally {
    sqlSession.close();
    }

    return result>0;

    }

    @Override
    public Boolean deletetodo(Integer todoid) {
    SqlSession sqlSession = MybatisUtil.getInstance().getSqlSessionFactory().openSession();
    TodoDAO dao=sqlSession.getMapper(TodoDAO.class);
    int result =0;
    try {
    result= dao.deletetodo(todoid);
    sqlSession.commit();
    }finally {
    sqlSession.close();
    }

    return result>0;

    }

}
DAO层
接口:
public interface TodoDAO {
List<Todo> listTodosByClassid(@Param("todoclassid") Integer todoclassid);
List<TodoClass> listTodoClassesByParentid(@Param("parentid") Integer parentid);
int saveTodoClass(TodoClass todoClass);
int saveTodo(Todo todo);
int updateTodo(Integer todoid);
int deletetodo(Integer todoid);
}
配置文件:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">;

<mapper namespace="com.westos.todo.dao.TodoDAO">
<select id="listTodosByClassid" resultType="com.westos.todo.entity.Todo">
select from todo
<where>
todoclassid=#{todoclassid}
</where>
</select>
<select id="listTodoClassesByParentid" resultType="com.westos.todo.entity.TodoClass">
select
from todoclass
<where>
<if test="parentid==null">
parentid is NULL
</if>
<if test="parentid!=null">
parentid=#{parentid}
</if>
</where>
</select>
<insert id="saveTodoClass" parameterType="com.westos.todo.entity.TodoClass">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select max(ifnull(id,0))+1 from todoclass
</selectKey>
insert into todoclass(id,name) VALUES (#{id},#{name});
</insert>
<insert id="saveTodo" parameterType="com.westos.todo.entity.Todo">
<selectKey keyProperty="id" resultType="int" order="BEFORE">
select max(ifnull(id,0))+1 from todo
</selectKey>
insert into todo(id,title,todoclassid,create_dt,state) VALUES (#{id},#{title},#{todoclassid},#{create_dt},#{state});
</insert>
<update id="updateTodo" parameterType="java.lang.Integer">
update todo set state=1 where id=#{id}
</update>
<delete id="deletetodo" parameterType="java.lang.Integer">
delete from todo where id=#{id}
</delete>
</mapper>