A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始


前言
​        本文是一款基于layui实现的日历记事本。我们可以根据点击页面上的日期,给这一天添加一个事件提醒。静态资源来自网络:http://www.jq22.com/jquery-info19169 。后台是用java语言实现。其中用到的技术有:LayUI,jQuery ajax,Servlet,MySQL和DBUtils。非常适合用作JavaWeb阶段的综合练习。
项目搭建1、创建web项目
​        使用IDEA创建web项目后,导入MySQL驱动包,C3P0和DBUtils的jar包。将静态资源复制到项目的web目录下。
2、数据表设计
​        经分析,日历记事本业务只与日期和给这个日期添加的事件有关。所以,设置了mark_date和mark_note两个字段,分别存储日期和这个日期对应的事件。另外,又设置了create_time和update_time存储设置和更改的时间。建表语句如下:







CREATE TABLE `date_note` (
  `id` int(11) NOT NULL AUTO_INCREMENT,  `mark_date` date DEFAULT NULL,  `mark_note` varchar(100) DEFAULT NULL,  `create_time` date DEFAULT NULL,  `update_time` date DEFAULT NULL,  PRIMARY KEY (`id`)) ENGINE=InnoDB AUTO_INCREMENT=11 DEFAULT CHARSET=utf8;







​        注:本项目只有涉及这一张表。如有需求,可增加用户表,将用户表和日历表进行关联。
3、修改C3P0配置文件
​         将C3P0的配置文件c3p0-config.xml复制到src下,并将相关信息修改成自己的数据库信息。C3P0配置文件信息如下:







<c3p0-config>
  <default-config>        <property name="driverClass">com.mysql.jdbc.Driver</property>        <property name="jdbcUrl">jdbc:mysql://localhost:3306/date_note</property>        <property name="user">root</property>        <property name="password">****</property>  </default-config></c3p0-config>







4、启动项目
​        使用IDEA配置tomcat启动项目,项目启动成功后自动加载首页。首页如下:
前端代码实现
所有的前端代码都在index.html中。js部分使用的是LayUI的语法。
1、页面加载数据(1)页面加载时发送ajax请求






        //定义json   
        var  data={};​        //页面加载后初始化data        $.post("/noteWeb/queryAll",function (res) {            console.log(res);            data = JSON.parse(res);            var new_date = new Date();            loding_date(new_date ,data);        });







【注意】data是json数据。数据格式如下:
{"2017-8-21": "发布","2017-8-22": "休息"}
(2) 将加载的数据展示到日历上
通过LayUI日历插件的render方法中设置mark参数,将查询到的数据与日历插件绑定:
代码如下:







//日历插件调用方法  
        function loding_date(date_value,data){                  laydate.render({            elem: '#test-n2'            ,type: 'date'            ,theme: 'grid'            ,max: '2099-06-16 23:59:59'            ,position: 'static'            ,range: false            ,value:date_value            ,calendar: true            ,btns:false            ,done: function(value, date, endDate){              console.log(value); //得到日期生成的值,如:2017-08-18              console.log(date); //得到日期时间对象:{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}              console.log(endDate); //得结束的日期时间对象,开启范围选择(range: true)才会返回。对象成员同上。              //layer.msg(value)                            //调用弹出层方法              date_chose(value,data);                          }           , mark:data//重要json!                     });        }







2、向后台插入或者更新数据
​     后台提交的数据是通过LayUI的弹出层收集的。点击日历插件上的某一天,会弹出如下图的弹出层:
其中弹出层代码实现如下:







//定义弹出层方法
      function date_chose(obj_date,data){          var index = layer.open({          type: 1,          skin: 'layui-layer-rim', //加上边框          title:'添加记录',          area: ['400px', 'auto'], //宽高          btn:['确定','撤销','取消'],          content: '<div class="text_box">'+                '<form class="layui-form" action="">'+                 '<div class="layui-form-item layui-form-text">'+                             ' <textarea id="text_book" placeholder="请输入内容"  class="layui-textarea"></textarea>'+                          '</div>'+                '</form>'+                '</div>'          ,success:function(){                $('#text_book').val(data[obj_date])            }          ,yes:function (){            //调用添加/编辑标注方法            if($('#text_book').val()!=''){                 chose_moban(obj_date,data);                layer.close(index);             }else{                 layer.msg('不能为空', {icon: 2});            }                     },btn2:function (){            chexiao(obj_date,data);          }        });      }







弹出层中的数据书写完毕后,点击确定按钮会执行以上代码的yes:function(){}回调函数,如下图:
我们只需要在chose_moban(obj_date,data)方法中通过ajax技术向后台发送请求,将数据插入数据库即可。具体代码如下:







        //定义添加/编辑标注方法
        function chose_moban(obj_date,markJson){          //获取弹出层val          var chose_moban_val = $('#text_book').val();                    $('#test-n2').html('');//重要!由于插件是嵌套指定容器,再次调用前需要清空原日历控件            //添加属性             markJson[obj_date] = chose_moban_val;            console.log(JSON.stringify(markJson));​            //使用ajax向后台插入数据            $.post("/noteWeb/insert",{markDate:obj_date,markNote:markJson[obj_date]},function () {​            });            //再次调用日历控件,            loding_date(obj_date,markJson);//重要!,再标注一个日期后会刷新当前日期变为初始值,所以必须调用当前选定日期。                    }







完整前端代码如下:







<script>
layui.use(['layer', 'form','jquery','laydate'], function() {    var layer = layui.layer,        $ = layui.jquery,        laydate = layui.laydate,        form = layui.form;                //定义json            var  data={};​        //页面加载后初始化data        $.post("/noteWeb/queryAll",function (res) {            console.log(res);            data = JSON.parse(res);            var new_date = new Date();            loding_date(new_date ,data);        });                //日历插件调用方法          function loding_date(date_value,data){                  laydate.render({            elem: '#test-n2'            ,type: 'date'            ,theme: 'grid'            ,max: '2099-06-16 23:59:59'            ,position: 'static'            ,range: false            ,value:date_value            ,calendar: true            ,btns:false            ,done: function(value, date, endDate){              console.log(value); //得到日期生成的值,如:2017-08-18              console.log(date); //得到日期时间对象:{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}              console.log(endDate); //得结束的日期时间对象,开启范围选择(range: true)才会返回。对象成员同上。              //layer.msg(value)                            //调用弹出层方法              date_chose(value,data);                          }           , mark:data//重要json!                     });        }​        //获取隐藏的弹出层内容      var date_choebox = $('.date_box').html();        //定义弹出层方法      function date_chose(obj_date,data){          var index = layer.open({          type: 1,          skin: 'layui-layer-rim', //加上边框          title:'添加记录',          area: ['400px', 'auto'], //宽高          btn:['确定','撤销','取消'],          content: '<div class="text_box">'+                '<form class="layui-form" action="">'+                 '<div class="layui-form-item layui-form-text">'+                             ' <textarea id="text_book" placeholder="请输入内容"  class="layui-textarea"></textarea>'+                          '</div>'+                '</form>'+                '</div>'          ,success:function(){                $('#text_book').val(data[obj_date])            }          ,yes:function (){            //调用添加/编辑标注方法            if($('#text_book').val()!=''){                 chose_moban(obj_date,data);                layer.close(index);             }else{                 layer.msg('不能为空', {icon: 2});            }                     },btn2:function (){            chexiao(obj_date,data);          }        });      }          //定义添加/编辑标注方法        function chose_moban(obj_date,markJson){          //获取弹出层val          var chose_moban_val = $('#text_book').val();                    $('#test-n2').html('');//重要!由于插件是嵌套指定容器,再次调用前需要清空原日历控件            //添加属性             markJson[obj_date] = chose_moban_val;            console.log(JSON.stringify(markJson));​            //使用ajax向后台插入数据            $.post("/noteWeb/insert",{markDate:obj_date,markNote:markJson[obj_date]},function () {​            });            //再次调用日历控件,            loding_date(obj_date,markJson);//重要!,再标注一个日期后会刷新当前日期变为初始值,所以必须调用当前选定日期。                    }​        //撤销选择        function chexiao(obj_date,markJson){            //删除指定日期标注            delete markJson[obj_date];             console.log(JSON.stringify(markJson));            //原理同添加一致            $('#test-n2').html('');            loding_date(obj_date,markJson);        }​});</script>







后台代码实现
后台使用的技术是Servlet+DBUtils+MySQL。
1、查询所有
​        页面加载时向后台发送请求查询数据。查询到的数据手动拼接成JSON字符串,数据返回到页面后再使用JSON.parse()方法解析。查询逻辑代码如下:
web层代码:







@WebServlet(name = "QueryListServlet",urlPatterns = "/noteWeb/queryAll")
public class QueryListServlet extends HttpServlet {    @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        doGet(request,response);    }​    @Override    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {​        response.setContentType("text/html;charset=UTF-8");        NoteService noteService = new NoteService();        String  jsonStr = noteService.queryStringList();        response.getWriter().write(jsonStr);    }}







service层代码如下:







public String queryStringList() {
        NoteDao noteDao = new NoteDao();       List<NoteMark> noteMarkList =  noteDao.queryAll();​       //将集合拼接成JSON字符串        StringBuffer sb = new StringBuffer();​        if(null != noteMarkList && noteMarkList.size()>0){            for (NoteMark noteMark:noteMarkList) {                sb.append(",\""+noteMark.getMarkDate()+"\":\""+noteMark.getMarkNote()+"\"");            }        }​        String sbStr = sb.toString().replaceAll("\n","");​        String str ="{"+ sbStr.substring(1,sbStr.length())+"}";        return  str;​    }







dao层代码如下:







public List<NoteMark> queryAll() {
        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());        String sql = "select id,mark_date as markDate,mark_note as markNote,create_time as createDate,update_time as updateDate from date_note ";        try {            List<NoteMark> noteMarkList = qr.query(sql, new BeanListHandler<>(NoteMark.class));            return noteMarkList;        } catch (SQLException e) {            e.printStackTrace();        }        return  null;​    }







2、新增数据
  用户通过点击页面上某个日期后向后台发送请求添加数据。请求的数据如下:
{markDate:obj_date,markNote:markJson[obj_date]}
后台拿到数据后,需要根据markDate进行判断。如果这个日期已经插入数据,则根据日期更新这条数据。如果这个日期的数据没有插入则插入这条数据:
Web层代码如下:







@WebServlet(name = "NoteInsertServlet",urlPatterns = "/noteWeb/insert")
public class NoteInsertServlet extends HttpServlet {    @Override    protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {        //插入日历记事本数据​        //获取日期        String markDate = request.getParameter("markDate");​        //获取事件        String markNote = request.getParameter("markNote");​​        //将数据封装到实体类中        NoteMark noteMark = new NoteMark();        noteMark.setUpdateDate(new Date());        noteMark.setMarkDate(DateFormartUtil.getDateFromStrDate(markDate));        noteMark.setMarkNote(markNote);​        //调用service层处理相关业务        NoteService noteService = new NoteService();        noteService.insertOrUpdateNoteMark(noteMark);​    }​    @Override    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {​    }}







Service层代码如下:







package com.heima.service;
​import com.heima.bean.NoteMark;import com.heima.dao.NoteDao;import com.heima.util.JDBCUtil;​import java.sql.Connection;import java.sql.SQLException;import java.util.Date;import java.util.List;​/** * @author buguniao * @date 2018-06-18 18:34 */public class NoteService {    public void insertOrUpdateNoteMark(NoteMark noteMark) {​        //Dao        NoteDao noteDao = new NoteDao();        Connection connection = null;        try {            connection = JDBCUtil.getConnection();        } catch (SQLException e) {            e.printStackTrace();        }​​        //根据日期判断是新增还是更新操作        Date markDate  = noteMark.getMarkDate();        NoteMark myNoteMark = noteDao.getNoteByNoteDate(markDate);​        if(null == myNoteMark){           //新增操作            noteMark.setCreateDate(new Date());            noteDao.insertDateNote(noteMark);​        }else{            myNoteMark.setMarkNote(noteMark.getMarkNote());            myNoteMark.setUpdateDate(new Date());            //更新操作            noteDao.updateDateNote(myNoteMark);​        }    }​}







Dao层代码如下:






package com.heima.dao;
​import com.heima.bean.NoteMark;import com.heima.util.JDBCUtil;import org.apache.commons.dbutils.QueryRunner;import org.apache.commons.dbutils.handlers.BeanHandler;import org.apache.commons.dbutils.handlers.BeanListHandler;​import java.sql.Connection;import java.sql.SQLException;import java.util.Date;import java.util.List;​/** * @author buguniao * @date 2018-06-18 18:34 */public class NoteDao {
    /**
     * 根据日期查询存储的事件     * @param markDate     * @return     */    public NoteMark getNoteByNoteDate(Date markDate) {        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());        String sql = "select id,mark_date as markDate,mark_note as markNote,create_time as createDate,update_time as updateDate from date_note where mark_date = ?";        try {            NoteMark noteMark = qr.query(sql, new BeanHandler<>(NoteMark.class), markDate);            return noteMark;        } catch (SQLException e) {            e.printStackTrace();        }        return  null;    }​​    /**     * 往数据库中插入事件     * @param noteMark     */    public void insertDateNote( NoteMark noteMark) {        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());        String sql = "insert into date_note values(null,?,?,?,?)";        try {            qr.update(sql,noteMark.getMarkDate(),noteMark.getMarkNote(),noteMark.getCreateDate(),noteMark.getUpdateDate());        } catch (SQLException e) {            e.printStackTrace();        }    }​​    /**     * 根据日期更新     * @param noteMark     */    public void updateDateNote( NoteMark noteMark) {        QueryRunner qr = new QueryRunner(JDBCUtil.getDataSource());        String sql = "update date_note set  mark_note=? ,create_time=? , update_time=? where mark_date = ?";        try {            qr.update(sql,noteMark.getMarkNote(),noteMark.getCreateDate(),noteMark.getUpdateDate(),noteMark.getMarkDate());        } catch (SQLException e) {            e.printStackTrace();        }    }}







  
3、上述代码中用到的工具类和bean
1、日期转化工具类






public class DateFormartUtil {
​    /**     * 将字符串date转化成java.util.Date类型数据     * @param strDate     * @return     */    public  static Date getDateFromStrDate(String strDate){        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");        try {            Date parse = sdf.parse(strDate);            return  parse;        } catch (ParseException e) {            e.printStackTrace();            return  null;        }    }}







2、JDBC工具类






public class JDBCUtil {
        private static ComboPooledDataSource cpds = new ComboPooledDataSource();    /**     * ThreadLocal     */    private static ThreadLocal<Connection> local = new ThreadLocal<Connection>();        public static ComboPooledDataSource  getDataSource(){        return cpds;    }    public static Connection getConnection() throws SQLException{        Connection conn = local.get();        if(conn == null){            conn = cpds.getConnection();            local.set(conn);        }        return conn;    }​    public static void commitAndClose(Connection conn){        DbUtils.commitAndCloseQuietly(conn);    }    public static void rollbackAndClose(Connection conn){        DbUtils.rollbackAndCloseQuietly(conn);    }}







3、实体类






package com.heima.bean;
​import java.util.Date;​/** * @author buguniao * @date 2018-06-18 18:34 */public class NoteMark {    private Integer id;    private Date markDate;    private String markNote;    private Date createDate;    private Date updateDate;​    public Integer getId() {        return id;    }​    public void setId(Integer id) {        this.id = id;    }​    public Date getMarkDate() {        return markDate;    }​    public void setMarkDate(Date markDate) {        this.markDate = markDate;    }​    public String getMarkNote() {        return markNote;    }​    public void setMarkNote(String markNote) {        this.markNote = markNote;    }​    public Date getCreateDate() {        return createDate;    }​    public void setCreateDate(Date createDate) {        this.createDate = createDate;    }​    public Date getUpdateDate() {        return updateDate;    }​    public void setUpdateDate(Date updateDate) {        this.updateDate = updateDate;    }​    public NoteMark(Integer id, Date markDate, String markNote, Date createDate, Date updateDate) {        this.id = id;        this.markDate = markDate;        this.markNote = markNote;        this.createDate = createDate;        this.updateDate = updateDate;    }​    public NoteMark() {    }​    @Override    public String toString() {        return "NoteMark{" +                "id=" + id +                ", markDate=" + markDate +                ", markNote='" + markNote + '\'' +                ", createDate=" + createDate +                ", updateDate=" + updateDate +                '}';    }}







说明
1、本项目前端代码绝大部分已经有素材提供者实现,我们只需要在对应的地方添加ajax向后台发送请求即可;
2、本项目是针对JavaWeb阶段的学员设计的,所以后台主要使用的是Servlet技术。



1529327414166.png (12.1 KB, 下载次数: 207)

1529327414166.png

5 个回复

倒序浏览
回复 使用道具 举报
回复 使用道具 举报
奈斯,很赞
回复 使用道具 举报
回复 使用道具 举报
wrf 初级黑马 2019-11-18 13:51:35
地板
您好,请问有项目源码或者git仓库分享一下吗?我现在后端还不是很清楚,前段显示了,但是后端还做不出来了,谢谢
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马