开发前的分析

1.技能前提

JSP JSTL EL JS/JQUERY

Servlet JavaBean

JDBC(后期再用mybatis,这样体会更深) MYSQL

2.需求分析和模块划分

(1)基本功能

 接收发送指令
根据指令自动回复对应的功能

(2)模块划分

 回复内容维护
回复内容列表 对话功能
回复内容删除

开发:JSP+Servlet+JDBC

new -> web project -> 输入project name为MicroMessage

step1:确认程序能跑起来

(1)ListServlet

  package com.imooc.servlet;

  /**
* 列表页面初始化控制
*/
public class ListServlet extends httpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOExcepiton{
req.getRequestDispatcher("/WEB-INF/jsp/back/list.jsp").forward(req,resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOExcepiton{
this.doGet(req,resp);
}
}

(2)web.xml中加入servlet的配置

1 <servlet>
2 <servlet-name>ListServlet</servlet-name>
3 <servllet-class>com.imooc.Servlet.ListServlet</servlet-class>
4 </servlet>
5 <servlet-mapping>
6 <servlet-name>ListServlet</servlet-name>
7 <url-pattern>/List.action</url-pattern>
8 </servlet-mapping>

(3)/WEB-INF/jsp/back/list.jsp

注意jsp文件放在WEB-INF下,这样必须经过后台才能访问到jsp。

如果放在WebRoot下(和WEB-INF平级)是能够被直接访问到的,除非设置了jsp拦截。

另外,关于jsp中如何使用项目的根目录:

1 <%
2 String path = request.getContextPath();
3 Sring basePath = request.getScheme()+"://"+request.getServiceName+":"+request.getServicePort()+path+"/"
4 %>

(4)/WebRoot/resources/css|images

在jsp文件中引用css:

 <head>
<meta .../>
<title ../>
<link href="<%= basePath =%>css/all.css" rel="stylesheet" type="text/css"/>
</head>

(5)运行代码

访问路径:localhost:8080/MicroMessage/List.action 。可以成功显示静态页面。

step2:从数据库中取数据

(1)建表

 数据库名:micro_message。
表名:message
账号:root
密码:root

(2)创建JavaBean

 package com.imooc.bean;

 /**
*与消息表对应的实体类
*/
public class Message{
private String id;
private String command;
private String description;
private String content;
//getter和setter略。
}

(3)Servlet中增加读取数据的代码

 package com.imooc.servlet;

  /**
* 列表页面初始化控制
*/
public class ListServlet extends httpServlet {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOExcepiton{
try{
Class.forName("com.mysql.jdbc.Driver");
Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/micro_message","root","root");
String sql = "select ID,COMMAND,DESCRIPTION,CONTENT from MESSAGE"; //这里不要写select *
PreparedStatement statement = conn.prepareStatement(sql); ResultSet rs = statement.executeQuery();
List<Message> messageList = new ArrayList<Message>();
while(rs.next()){
  Message message = new Message();
  messageList.add(message);
  message.setId(rs.getString("ID"));
  message.setCommand(rs.getString("COMMAND"));
  message.setDescription(rs.getString("DESCRIPTION"));
  message.setContent(rs.getString("CONTENT"));
}
req.setAttribute("messageList",messageList);
}catch(ClassNotFoundException e){
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}
req.getRequestDispatcher(“/WEB-INF/jsp/back/list.jsp”).forward(req,resp);
} @Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException, IOExcepiton{
this.doGet(req,resp);
}
}

(4)list.jsp中获取值

这里用到了jstl(c:forEach,c:if),所以要加上库:<%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core” %>。其中的uri可以从/META-INF/c.tld中复制。c.tld有一个<uri>标签,值就是http://java.sun.com/jsp/jstl/core。

另外,这里还加上了偶数行有背景色的效果。因为status从0开始,所以实际上是表格的基数行

 <%@ taglib prefix=“c” uri=“http://java.sun.com/jsp/jstl/core”%>
<c:forEach items=“${messageList}” var=“message” varStatus=“status”> <tr <c:if test=“${status.index%2!=0}”> style='background-color:#ECF6EE;’ </c:if> >
>
<td><input type=“checkbox”/></td>
<td>${status.index+1}</td>
<td>${message.command}</td>
<td>${message.description}</td>
<td>
<a href=‘#’>修改</a>&nbsp;&nbsp;&nbsp;
<a href=‘#’>删除</a>
</td>
</tr>
</c:forEach>

(5)运行

重启项目(注意Servlet的生命周期,只实例化一次,所以必须要重启才能生效。但是debug模式下eclipse会为servlet重新加载)访问地址***,可以看到查出来的数据,和背景色效果。

step3:加查询条件command和description

(1)在jsp中添加action,并为查询框的input命名

 <form action="<%= basePath =%>List.action" id="mainForm" method="post">
...
<td>
<input name="command" type="text" class="allInput" value=""/>
</td>
<td>
<input name="description" type="text" class="allInput" value=""/>
</td>
..
</form>

(2)ListServlet中处理查询参数

         req.setCharacterEncoding(“UTF-8"); //不加这句的话,在查询框里输入中文,下面getParameter得到的值会是乱码
String command = req.getParameter("command");//和jsp中查询框input的name匹配
String description = req.getParameter("description");
4 try{
  Class.forName("com.mysql.jdbc.Driver");
  Connection conn = DriverManager.getConnection("jdbc:mysql://127.0.0.1:3306/micro_message","root","root");
  StringBuilder sql = new StringBuilder(“select ID,COMMAND,DESCRIPTION,CONTENT from MESSAGE where 1==1");
  List<String> paramList = new ArrayList<String>();
  if(command != null && !"".equals(command.trim())){
    sql.append(" and COMMAND=?"); //注意这里有个空格,否则拼接完成后有语法错误。
  }
  if(description != null && !"".equals(description.trim())){
    sql.append(“ and DESCRIPTION like '%'?'%'”);//mysql的模糊查询格式
  }
  PreparedStatement statement = conn.prepareStatement(sql.toString());
  for(int i=0; i<paramList.size();i++){
    statement.setString(i+1,paramList.get(i)); //sql中?的位置从1开始
  }
  statement.executeQuery();
20 ...
21 }

(3)让查询框中的参数保留

前面运行后,可以发现,当在查询框中输入值进行查询后,查询框中的值会消失。是因为这里的value为""。

 <input name="description" type="text" class="allInput" value=""/>

首先要将参数的值保存在req中,这样jsp中才能拿到值。

 req.setCharacterEncoding(“UTF-8");
String command = req.getParameter(“command”);
String description = req.getParameter(description); 5 req.setAttribute("command",command);
6 req.setAttribute("description", description);
try{
  Class.forName(“com.mysql.jdbc.Driver”);
  Connection conn = DriverManager.getConnection(“jdbc:mysql://127.0.0.1:3306/micro_message”,”root”,”root”);
10 ...
11 }

然后将jsp中input的value设置为req中的属性值。

1 <input name="description" type="text" class="allInput" value="${description}"/>

重构:在进行下一步开发前整理代码

可以看到前面的代码,注释少,内容都放在一个方法里。所以需要对代码进行重构。根据功能进行层次划分。

step1:dao层

 package com.immoc.dao;
/**
*和message表相关的数据库操作
*/
public class MessageDao{
public List<Message> queryMessageList(String command,String description){
  List<Message> messageList = new ArrayList<Message>();
   try{
   Class.forName("com.mysql.jdbc.Driver");
10 ...
11 while(){...}
}catch(ClassNotFoundException e){
e.printStackTrace();
}catch(SQLException e){
e.printStackTrace();
}
return meesageList;
29 }
}

step2:service层

 package com.immoc.service
/**
*列表相关的业务功能
*/
public class ListService{
public List<Message> queryMessageList(String command, String description){
MessageDao messageDao = new MessageDao();
return messageDao.queryMessageList(command,description);
}
}

step3: Servlet

 1 package com.imooc.servlet;
2
3 /**
4 * 列表页面初始化控制
5 */
6 public class ListServlet extends httpServlet {
7 @Override
8 protected void doGet(HttpServletRequest req, HttpServletResponse resp)
9 throws ServletException, IOExcepiton{
10 //接受页面的值
10 req.setCharacterEncoding("UTF-8");
11 String command = req.getParameter("command");
12 String description = req.getParameter("description”);
13 //向页面传值
14 req.setAttribute("command",command);
15 req.setAttribute("description", description);
15 //查询消息列表并传给页面
16 ListService listService = new ListService();
17 req.setAttribute("messageList”,listService.queryMessageList(command,description));
18 //向页面跳转
18 req.getRequestDispatcher(“/WEB-INF/jsp/back/list.jsp”).forward(req,resp);
19 }
20 ...
21 }

step4:运行测试。

mybatis

step1:下载mybatis

注意:mybatis-**-SNAPSHOT是正在开发的版本,不要下载使用。下载mybatis-**.zip后,也下载一下mybatis的source code。因为source code里有一个test文件夹,里面是一些演示代码,会有帮助。

下载完成后,将mybatis-**.jar放至项目的lib目录下。

step2:mybatis的主配置文件

从source code中拷贝文件:src\test\java\org\apache\ibatis\submitted\complex_property\Configuration.xml 放到项目中

 <configuration>
<environments>
<environment>
<transactionManager type=“JDBC”>
<property name=“” value=“”/>
</transactionManager>
<dataSource type=“UNPOOLED”>
<property name=“driver” value=“com.mysql.jdbc.Driver”/>
<property name=“url” value=“adbc:mysql://127.0.0.1:3306/micro_message”/>
<property name=“username” value=“root”/>
<property name=“password” value=“root”/>
</dataSource>
</environment>
</enviroments>
...
</configuration>

step3:读取mybatis的配置文件

1.几个问题

Dao层的真实需求?

对象能与数据库交互;能执行sql语句。

mybatis如何像dao层提供需求的?

通过SqlSession。

SqlSession的作用?

 向SQL语句传入参数
执行SQL语句
获取执行SQL语句的结果
事务的控制

如何获得SqlSession?

 通过配置文件获取数据库连接相关信息
通过配置信息构建SqlSessionFactory
通过SqlSessionFactory打开数据库会话(SqlSession就是一次与数据库交互的会话)

2.db层(真正与数据库交互的层)

 package com.imooc.db;

 /**
*访问数据库类
*/
public class DBAcess{
public SqlSession getSqlSession() throws IOException{
//通过配置文件获取数据库连接信息
Resources.getResourceAsReader(“com/imooc/config/Configuration.xml”);//src是根路径
//通过配置信息构建SqlSessionFactory
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = SqlSessionFactoryBuilder().build(reader);
//通过SqlSessionFactory打开一个数据库会话
SqlSession sqlSession = SqlSessionFactory.openSession();
return sqlSession;
}
}

3.增加mybatis的映射文件

(1)在mybatis的主配置文件里加载映射文件Message.xml

1 <configuration>
2 ...
3 <mappers>
4 <!—-同样从src下开始算起—->
5 <mapper resource=“com/imooc/config/sqlxml/Message.xml”/>
6 </mappers>
7 </configuration>

(2)Message.xml

命名空间:必须有,否则读取配置文件会报错。

<select/update/delete id=" "> 中id的值在同一个namespace下同一个标签下必须唯一。

<resultMap type="" id=""> 中:

type的值为对应的JavaBean,必须填写全路径或者定义的别名。id的值为<select/update/delete resultMap="">中resultMap的值,表明是与哪个sql语句相对应的resultMap。

<resultMap>的子标签中:

<id column"">中填写的是主键的字段名。<result column="">填写的是普通的列名。property中填写的是JavaBean中属性名。

(3)mybatis的OGNL

上面的<if test=""> </if>等是OGNL表达式。不是mybatis专有的。但是在mybatis里有特性?(这句话不确定)

(ps:前面jsp文件中的<c:if>是EL表达式。)

step4:修改dao层代码

 public class MessageDao{
public List<Messag> queryMessageList(String command,String description){
List<Message> messageList = new ArrayList<Message>();
DBAccess dbAccess = new DBAccess();
SqlSession sqlSession = null;
try{
sqlSession = dbAccess.getSqlSession();
Message message = new Message();
message.setCommand(command);
message.setDescription(description);
messageList = sqlSession.selectList(“Message.queryMessageList”,message); //Message.xml中的sql语句的namespase.id
}catch(IOException e){
e.printStackTrace();
}finally{
if(sqlSession != null){
16 sqlSession.close();
17 }
}
19 return messageList;
}

step5: 运行测试,ok。

2017.4.19 慕课网-通过自动回复机器人学习mybatis的更多相关文章

  1. 2017.4.26 慕课网--Java 高并发秒杀API(一)

    Java高并发秒杀API系列(一) -----------------业务分析及Dao层 第一章 课程介绍 1.1 内容介绍及业务分析 (1)课程内容 SSM框架的整合使用 秒杀类系统需求理解和实现 ...

  2. 2017.4.26 慕课网--Java 高并发秒杀API配置文件(持续更新)

    新建项目,new maven project. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi=&q ...

  3. 2017.4.18 慕课网-spring事务管理总结

    1.课程目标 事务回顾 spring中的事务管理的api spring中编程式事务管理 spring中声明式事务管理 2.事务回顾 2.1 事务的概念 事务是指逻辑上的一组操作,要么全成功,要么全失败 ...

  4. HTML学习案例-仿慕课网网页制作(二)

    制作部分:网页footer部分 制作效果: 涉及知识:link部分要复习: dl- definition list dt- definition title dd - definition descr ...

  5. Node.js爬虫-爬取慕课网课程信息

    第一次学习Node.js爬虫,所以这时一个简单的爬虫,Node.js的好处就是可以并发的执行 这个爬虫主要就是获取慕课网的课程信息,并把获得的信息存储到一个文件中,其中要用到cheerio库,它可以让 ...

  6. java网络爬虫----------简单抓取慕课网首页数据

    © 版权声明:本文为博主原创文章,转载请注明出处 一.分析 1.目标:抓取慕课网首页推荐课程的名称和描述信息 2.分析:浏览器F12分析得到,推荐课程的名称都放在class="course- ...

  7. es6 Object.assign ECMAScript 6 笔记(六) ECMAScript 6 笔记(一) react入门——慕课网笔记 jquery中动态新增的元素节点无法触发事件解决办法 响应式图像 弹窗细节 微信浏览器——返回操作 Float 的那些事 Flex布局 HTML5 data-* 自定义属性 参数传递的四种形式

    es6 Object.assign   目录 一.基本用法 二.用途 1. 为对象添加属性 2. 为对象添加方法 3. 克隆对象 4. 合并多个对象 5. 为属性指定默认值 三.浏览器支持 ES6 O ...

  8. 关于慕课网《使用vue2.0实现购物车和地址选配功能》的总结

    视频学习网址:http://www.imooc.com/learn/796 源码打包:https://codeload.github.com/fachaoshao/Vue-ShoppingCart/z ...

  9. 慕课网go语言体系课抢先体验

    慕课网go语言体系课抢先体验,课程分四个阶段: <第一阶段go语言基础语法篇>,从go语言基础语法篇讲起,go语言环境集成,常用开发工具集成,常用数据类型讲解,流程控制,函数,结构体,方法 ...

随机推荐

  1. echarts异步加载

    echarts体积很大,在移动端使用异步加载是一种提高渲染速度的方法,结合webpack的做法如下: require.ensure([], function(require){ const echar ...

  2. Educational Codeforces Round 42 (Rated for Div. 2) C

    C. Make a Square time limit per test 2 seconds memory limit per test 256 megabytes input standard in ...

  3. 02 Java 基础语法

    在开始 Java 基本语法之前,先说明 Java 程序的基本规范: 大小写敏感,例如 Person 和 person 是不同的 类名首字母大写,如果类名由多个单词组成,每个单词首字母都大写,例如 He ...

  4. mysql截取字符串与reverse函数

    mysql的函数大全: http://www.jb51.net/Special/606.htm 这个网页上很多知识点,可以学习下,关于mysql的函数,也可以作为API查询: 这里只说下mysql的截 ...

  5. Require.js 详细了解

    一.Require.js 作用 1.1.是JS 文件加载器,实现js脚本的AMD异步加载. 保证不阻塞页面的渲染和其后的脚本的执行,并提供了在加载完成之后的执行相应回调函数的功能. 1.2.实现JS. ...

  6. Android控件点击事件

    1. 介绍 本文介绍了Android控件的点击事件 Android控件点击(onClick)事件可以用如下三种方式来实现 2. 实现onClick方法 在layout的xml中指定onClick方法, ...

  7. VS2013 生成sqlite3动态连接库及sqlite3.dll的调用

    一,生成sqlite3动态连接库1,去sqlite官网上下载最近的sqlite源码包,解压后得到四个文件:shell.c,sqlite3.c,sqlite3.h,sqlite3ext.h此处还需要sq ...

  8. 静态链接和动态链接库混用导致的链接错误LINK2005

    对于一个静态链接库L.lib,它的使用者app.exe会静态链接L.lib,意思是app.exe会将L.lib中的代码(app需要的部分,例如函数定义,类的定义等等)链接到app.exe中.   而对 ...

  9. python tips(3);import的机制

    1.标准的import python中,所有加载到内存中的模块都是放在sys.modules中,当import一个模块的时候,会在这个列表中查看是否加载了这个模块,如果加载了,则只是将模块名字加入到正 ...

  10. Ubuntu安装java环境

    Ubuntu安装java环境 1.添加ppa sudo add-apt-repository ppa:webupd8team/java sudo apt-get update 2.安装oracle-j ...