首页 > 代码库 > 云笔记开发思路

云笔记开发思路

前戏
配置前段控制器 web.xml 配置需要spring-*.xml文件 处理*.do的请求
配置mybatis spring-mybatis.xml 添加数据连接池BaseDataSource 有几个参数
测试:注意导包sql
添加Mybatis SqlSessionFactory配置ref
org.mybatis.spring.SqlSessionFactoryBean
添加Mapper接口扫描器配置
org.mybatis.spring.mapper.MapperScannerConfigurer

services.msc E:\tts9\mysql 删除文件 C:\ProgramData 隐藏文件夹下删除mysql
安装mysql 第二个,然后选择路径
导入mysql day01
create database cloud_note;
set names utf8;
source e:/cloud_note.sql;
update cn_user set cn_user_password= ‘23f97b1171789885989406b36f3d4035‘;
23f97b1171789885989406b36f3d4035

分别测试dataSource sqlSessionFactory MapperScanner getBean实例化输出测试
将准备好的数据添加到数据库
======================================================================
dao包中添加一个保存方法save
function trimStr(str){return str.replace(/(^\s*)|(\s*$)/g,"");} js中trim()
//org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.sm.note.dao.UserDao.saveUser
这个异常估计就是没有ssf 配置问题,bean工厂
给ssf配置添加,mapperscan的配置
//org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): cn.sm.note.dao.UserDao.saveUser
sqlid错
org.springframework.jdbc.BadSqlGrammarException:
/* Error querying database. Cause: com.mysql.jdbc.exceptions.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ‘as id,cn_user_name as name,cn_user_password as password,cn_user_token a‘ at line 2*/
在查询的时候给了一个别名
//org.springframework.dao.DuplicateKeyException
主键不唯一,复制真的很难控制,两个save()....

出现字段与实体类不匹配的时候会出现空指针

UserDao添加findUserByName方法 参数 username,password->userService
userController里使用JSONResoult 返回json对象
这个工具类 包含 泛型data(这个是设计好的),异常,还有一个状态信息
zhoujia123 23f97b1171789885989406b36f3d4035
编写Controller->界面整合

在持久层中,通过用户名可以查找对应的用户,若存在则返回用户信息即USer对象

login.js
找到用户名和密码的id,进行合理检验,利用ajax发送异步请求,发现不如何规则给予提示
登陆 用户名 id="count" 密码 id="password" 在登陆之后找到用户名绑定鼠标移除事件
具体过程如下
loginAction 登陆动作->账号检查 为了显示错误信息,在账号之后span id="count-msg" 判空以及合理性规则验证
如果符合要求,则清楚count-msg显示的错误信息 可以在登陆的时候给账号绑定一个focus ->获得焦点
同样的password也是如法炮制

添加登陆事件检查方法loginAction()
一番操作:账号符合要求则,直接tab到密码,提示,如果都正确则click() #login 按钮;
发送ajax请求,state==0,则跳转到edit.html? url,data,dataType,success,error
state返回0之后跳转到edit.html页面 //提示:使用location.href

映射器方法id为Sqlid,包是命名空间.如果不匹配会出现绑定失败的情况

步骤
我们实现在数据库中已经保存了一些调试信息
在持久层中,通过用户名可以查找对应的用户,若存在则返回用户信息即USer对象
业务层,实现登陆的功能逻辑,进行合理性检查调用持久层的方法若找不到用户就抛出一个用户名错误或者密码的异常,交给用户处理
登陆成功则,返回用户信息
表现层根据请求,调用不同的控制器处理
我门将处理结果,通过JSONResult封装起来,调用业务层登陆方法,同过Ajax请求将信息(json)发送给页面,
登陆成功重定向到编辑模块,登陆失败则给予提示
界面整合
登陆页面中根据jquery找到对应的控件进行简单的判断,不符合要求给予提示
给登陆按钮绑定一个事件,如果账号密码通过规则验证则,向服务器发起ajax请求
请求参数中包含用户名,账号等信息,POST方式进行提交
请求成功则返回一个JSON,根据状态码0 成功123 失败
给予提示或者重定向到编辑界面
=========================================================================
2.注册模块
用户注册时候->密码需要进行加密处理
使用-> 加盐摘要,首先密码与盐,也就是任意的一组字符串进行组合,经MD5算法保存到数据库中,有效的提高了密码的安全.
需要commons-code包
userService->userController //userName=userName.trim(); 人性化擦操作,万一空格多了下次不好登陆
进行第一次重构,异常部分略微繁琐
重构登陆方法userController

界面整合->edit.html 同样的,在login.js中进行
观察log_in.html. 注解页面上,用户名后面的div中有一个span,里面就有错误信息,只不过display为none,相当于hide(),不显示
发送ajax请求,注册使用 $.post(url,data,function(result){})
注册的过程中好像有一些小毛病,由于使用加盐摘要,密码+你吃了吗? 取md5值存入数据库中,于是在登陆的时候需要把密码进行加盐之后与数据中中的密码比较?
确实需要这么比较,不过之后需要进行重构

登陆
持久层,根据用户名,密码等信息,将信息作为User对象保存到数据库中
业务层,同样的进行合理检验(不能空,规则3-10..重名.,user是否已经存在)调用持久层的save方法,返回一个user
控制层调用业务层的register方法,成功与否向页面发送JSON,
回到登陆页面或者提示信息
@ExceptionHandler统一异的处理,可以简化控制器方法的书写。
界面整合
上一步骤,已经引入了jquery.选择器找到注册名,昵称,密码,确认密码初步检验
检验通过点击注册按钮,想服务器发起ajax请求,将页面上的信息作为参数发送给服务器,服务器(把参数传递给Service层的方法,并调用service层注册的方法,检验..继续调用持久层保存用户信息)返回JSON对象,保存成功回到登陆页面,失败给予提示

有一些人性化的技巧,提交的时候可以将账号密码中多余的空格去掉
以及,返回注册页面的时候可以直接把用户刚刚注册的账号填到登陆页面上
过程是这样的,返回的json中带有user的信息,
var user =result.data;
name=user.name;即可获得刚刚注册的账号用户名

=========================================================================
实现笔记本列表功能
加载edit.html页面之后,显示笔记本列表,根据用户id在 数据库中查询属于该用户的笔记本,id哪里来,登陆的时候可以保存得到(具体实现)
使用List将查询得到的笔记本保存起来,
经验使用Map将查询结果封装起来可以减少流量,提高软件效率
Map<String,Object> key为笔记本id?value是笔记本名字?

想法一:
原本我的设想是返回值为notebook,假设我返回的是Notebook应该也能做到
根据userId查找所有的笔记本,查找到的不止一条数据,也就是说可能有很多本笔记
存放在list集合中,每条记录就是一个notebook对象?嗯->进行测试
NotebookController 调用NotebookService的findNotebookByUserId
传入一个UserID,就可以查找出所有的笔记本..
想法二:
实际情况下,查询所有的字段,返回一个Notebook对象比较影响性能,现在我门只需
跟据UserId 获取NotebookId 以及notebookName即可
这时,可以使用Map,将查询出来的id作为key,name作为value提高效率

返回Map类型的查询结果。一条记录对应一个Map对象,字段名作为key,字段值作为value
Map,一个字段对应一个key,value
{key:value,key:value},
{id:1101,name:读书笔记}

小技巧,如果仅需某条记录中几个字段的值,可以使用map作为查询结果

显示笔记本

 

 

 

 

 

 


************************************************************************
1、get方式的安全性较Post方式要差些,包含机密信息的话,建议用Post数据提交方式;
2、在做数据查询时,可以用Get方式,因为它效率高;而在做数据添加、修改或删除时,建议用Post方式,因为它安全;
至于ajax,那就更简单:ajax是异步,post是同步,至于很细的区分,
edit_init.js部分
页面加载以后显示笔记本列表
点击笔记本li显示该笔记本所有的笔记

notebook
将userId存起来
====================================================================
loadNotebookAction();
model.updateNotebooks(list); 存查询出来所有的笔记本,list.do返回来的 nb 16
model.notebooks nb 36 遍历得到每个笔记
在把li挂到ul上的时候顺便存放了notebooks的下标i nb 41

$(‘#notebooks‘).on(‘click‘,‘li‘,showNotesAction);
冒泡获取li,刚刚存的index,取出来
添加效果,checked
model.showNotes(notebookIndex), 显示所有的笔记
再把this.notebookIndex=notebookIndex 在把笔记本下标存起来
根据下标就可以获得单个笔记本
model.updataNote (notes) 将note显示到界面
if this.notes=notes 把所有的笔记存起来
发送请求,遍历 (if i=this.noteIndex 就有checked的效果)
挂到笔记的ul下
function loadNoteAction 获取选定元素的序号 index
model.loadNote=function(index) 加载选定的笔记 发送数据用get 90
model.updataNote=function(note,newNotes) 将note对象显示到编辑区
function saveNoteAction() 处理保存按钮事件 #input_note_title
从model获取笔记id
model.updateTitle=function(title)
function showAddNoteDialog() 响应添加笔记按钮事件,打开添加笔记对话框
function addNoteAction() 处理点击保存笔记按钮事件

当元素失去焦点时发生 blur 事件。
ctrl+i可以排版

持久层根据userId到数据库中查找有关该用户的笔记本,返回map类型的结果
因为只需要查询,笔记本id以及笔记本的名,其他无关的不需要(不用全都差回来)
参考
<!-- 返回Map类型的查询结果
map是java.util.Map的简写形式
-->
<select id="findById2"
parameterType="int"
resultType="map">
SELECT * FROM emp WHERE id = #{id1}
</select>

@Test
public void test6(){
Map data = http://www.mamicode.com/
session.selectOne(
"test.findById2",
23);
//注意字段名要大写,
//oracle会将字段名都转换成大写形式。
System.out.println(
data.get("ENAME"));
session.close();
}
具体没有细说,我想应该就是需要几个字段就返回几个字段,更加灵活一些,如果不对,以后改回来
2016年11月26日 16:44:32
业务层调用持久层,根据id找笔记本的方法,合理检查(id,存在...)返回list,因为一个用户笔记本不只一本
表现层调用业务层的listnotebook方法,如果找到则将信息用json发送给页面
整合页面
把有关编辑页面的方法写在一个js中,edit_inti 也包括全局变量的操作
重点说一下 var model={} js对象***可以用的时候在定义属性和方法
在登陆页面中,使用setCookie工具方法将userId在登陆的时候保存在Cookie中,
编辑页面中可以取出Cookie中的id,通过$.getJSON想服务器发送AJax请求,
-----------------------------------------
作为补充:
$.getJSON这个方法从服务器获得数据返回的数据必须是json对象,否则回调函数XHR对象为空,jquery会先将这个方法转为对应的js对象
$.post $.get两种提交方式
---------------------------------------------
根据返回的,json实质上是许多笔记本id以及笔记本名的组成的list
使用model对象更新笔记本列表,添加一个updateNotebooks();进入编辑界面之后跟新笔记本列表,通过模版,然后将li挂到ul下面
====================================================================

跟新笔记列表
2016年11月27日 10:37:27
时间来不及,先简单的理解一下


保存笔记功能
界面整合
点击保存按钮向服务器发起Ajax请求,请求参数包括标题title,内容body,以及笔记本id NoteId.首先在编辑页面上,合理检查如:
检查title是否为空
我设定的规则是不能为空.然后判断判断title以及body是否变化

以title\body作为参数发送给服务器,/note/save.do
若失败则弹窗提示.
在服务器,前段控制器根据handleMapping的配置调用响应的控制器,将参数传递给业务层,调用持久层的保存方法,返回一个int 值,业务层判断值是否为一,
若为一,说明保存成功,返回给控制器一个true,否则返回flase.
编辑页面接受json返回结果,进行响应处理
在持久层中,使用mybatis动态传递参数,实现代码复用.通过id 标签test属性判断是否传入参数,实现mybatis的动态拼接功能的实现

添加笔记功能,类似的笔记本的功能
持久层中添加一个根据note 保存笔记的方法,接受Note对象 返回int值
在notemapper.xml 映射文件中进行配置由于条件较多,可以先进行测试
业务层中,需要的参数有用户ID,笔记本Id,title,body(可以有
进行合理检验,判断是否为空,以及用户&&笔记本是否存在等
其他入noteId 可以自动生成,修改时间为当前时间...
将这些信息保存称为一个Note对象调用持久层的add方法
若添加成功返回1则,把note对象返回
控制层中接受Ajax请求的参数,逐层调用方法,成功则返回note的json对象
整合页面
点击添加按钮,弹出添加笔记的对话框,调用相关方法显示...
$obj.load();,将返回的数据放置到指定的元素中
从model数据模型中可以获取到用户id以及笔记本id 先获取笔记本然后根据下标获取
***解释一下,因为是通过list发送过来,根据下标与get(i)的效果一致
发送ajax请求,获得返回得到的note对象.
调用跟新笔记本的方法updateNote()<--重构

实现登陆权限检查,
原理是给Cookie中添加token.检查每次登陆时候的token是否一致,不一致则无法登陆,,轮到spring 监听器出场了以及过滤器
重构业务层UserSerivie,添加检查userId以及token的方法
过滤器实现filter接口.对请求路径进行检查
init中,通过容器获得userService对象
dofileter中进行业务处理
从Cookie中获得userId,以及Token调用业务层的方法进行检查,符合条件返回true,正常执行业务
返回flase则重定向到登陆页面

 

云笔记开发思路