前言 本文是一款基于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、上述代码中用到的工具类和bean1、日期转化工具类
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技术。
|