SSH Unit01

来源:互联网 发布:国内外大数据现状分析 编辑:程序博客网 时间:2024/06/06 15:49

SSH

MyBatis 关联映射

MyBatis可以处理赋值关系映射:

业务描述:

这里写图片描述

数据库SQL:

create table p_person(    id int not null AUTO_INCREMENT,    name varchar(100),    primary key(id));insert into p_person (name) values ('李老师');insert into p_person (id, name) values (null,'李老师');create table p_comment(    id int not null AUTO_INCREMENT,    title varchar(100),    post_id int,    primary key(id));create table p_post(    id int not null AUTO_INCREMENT,     title varchar(100),    person_id int,    primary key(id));insert into p_post (id, title, person_id)    values (null, '今天天气不错', 1);insert into p_post (id, title, person_id)    values (null, '高考又来了', 1);insert into p_comment(id, title, post_id)    values ( null, '少穿了哪一件呀?', 1);insert into p_comment(id, title, post_id)    values (null, '冻成狗', 1);insert into p_comment(id, title, post_id)    values (null, '喜欢下雪', 1);

关联映射步骤

  1. 声明实体类:

    public class Person implements Serializable {    private static final long serialVersionUID = -2365398342302306276L;    private Integer id;    private String name;    public Person() {    }    public Person(Integer id, String name) {        super();        this.id = id;        this.name = name;    }    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    @Override    public String toString() {        return "Person [id=" + id + ", name=" + name + "]";    }    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + ((id == null) ? 0 : id.hashCode());        return result;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Person other = (Person) obj;        if (id == null) {            if (other.id != null)                return false;        } else if (!id.equals(other.id))            return false;        return true;    }}public class Comment implements Serializable {    private static final long serialVersionUID = -5881249634665160256L;    private Integer id;    private String title;    public Comment() {    }    public Comment(String title) {        super();        this.title = title;    }    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + ((id == null) ? 0 : id.hashCode());        return result;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Comment other = (Comment) obj;        if (id == null) {            if (other.id != null)                return false;        } else if (!id.equals(other.id))            return false;        return true;    }    @Override    public String toString() {        return "Comment [id=" + id + ", title=" + title + "]";    }}public class Post implements Serializable{    private static final long serialVersionUID = -4722438109030592372L;    private Integer id;    private String title;    /** 发帖人 */    private Person person;    /** 当前帖子收到的回复 */    private List<Comment> comments =             new ArrayList<Comment>();    public Post() {    }    public Integer getId() {        return id;    }    public void setId(Integer id) {        this.id = id;    }    public String getTitle() {        return title;    }    public void setTitle(String title) {        this.title = title;    }    public Person getPerson() {        return person;    }    public void setPerson(Person person) {        this.person = person;    }    public List<Comment> getComments() {        return comments;    }    public void setComments(List<Comment> comments) {        this.comments = comments;    }    @Override    public String toString() {        return "Post [id=" + id + ", title=" + title + ", person=" + person + ", comments=" + comments + "]";    }    @Override    public int hashCode() {        final int prime = 31;        int result = 1;        result = prime * result + ((id == null) ? 0 : id.hashCode());        return result;    }    @Override    public boolean equals(Object obj) {        if (this == obj)            return true;        if (obj == null)            return false;        if (getClass() != obj.getClass())            return false;        Post other = (Post) obj;        if (id == null) {            if (other.id != null)                return false;        } else if (!id.equals(other.id))            return false;        return true;    }}
  2. 添加映射接口:

    public interface PostDao {    Post findPostById(Integer id);}
  3. 添加映射基本属性映射: NoteMapper.xml

    <mapper namespace="cn.tedu.note.dao.PostDao">    <!-- 复杂映射必须使用resultMap 进行处理 -->    <resultMap type="cn.tedu.note.entity.Post"        id="postMap">        <!-- 逐一映射每个属性 -->        <!-- 数据库主键, 使用id映射 -->        <id column="id" property="id"/>        <!-- 非主键, 使用 result 映射-->        <result column="title" property="title"/>    </resultMap>    <select id="findPostById"        parameterType="int"        resultMap="postMap">        select             id,             title,            person_id        from             p_post         where             id=#{id}    </select>   </mapper>

    提示: MyBatis不自动支持复杂的映射关联, 复杂的关联关系必须使用resultMap进行手动映射.

  4. 测试:

    public class PostDaoTest extends BaseTest {    PostDao dao;    @Before    public void initDao(){        dao = ctx.getBean(            "postDao", PostDao.class);    }    @Test    public void testFindPostById(){        Post post = dao.findPostById(1);        System.out.println(post);    }}

    测试结果说明, 可以映射基本属性 id和name, 但是无法映射person属性和commons属性.

  5. 映射 person 属性, 使用关联映射: 重构PersonMapper.xml

    <mapper namespace="cn.tedu.note.dao.PostDao">    <!-- 复杂映射必须使用resultMap 进行处理 -->    <resultMap type="cn.tedu.note.entity.Post"        id="postMap">        <!-- 逐一映射每个属性 -->        <!-- 数据库主键, 使用id映射 -->        <id column="id" property="id"/>        <!-- 非主键, 使用 result 映射-->        <result column="title" property="title"/>        <!-- 映射 person 属性使用association(关联)映射 -->        <association property="person"             javaType="cn.tedu.note.entity.Person">            <id column="person_id" property="id"/>            <result column="name" property="name"/>        </association>    </resultMap>    <select id="findPostById"        parameterType="int"        resultMap="postMap">        select             p_post.id,             title,            person_id,            p.name        from             p_post        left outer join            p_person p on p.id=person_id         where             p_post.id=#{id}    </select>   </mapper>

    首先使用关联SQL查询, 查询出person对象的属性值, 再利用association标签将查询结果映射到Person对象的属性.

  6. 测试:

    经过测试可用发现已经成功映射了person属性.

  7. 映射 comments 属性, 使用collection标签: 重构PostMapper.xml

    <mapper namespace="cn.tedu.note.dao.PostDao">    <!-- 复杂映射必须使用resultMap 进行处理 -->    <resultMap type="cn.tedu.note.entity.Post"        id="postMap">        <!-- 逐一映射每个属性 -->        <!-- 数据库主键, 使用id映射 -->        <id column="id" property="id"/>        <!-- 非主键, 使用 result 映射-->        <result column="title" property="title"/>        <!-- 映射 person 属性使用association(关联)映射 -->        <association property="person"             javaType="cn.tedu.note.entity.Person">            <id column="person_id" property="id"/>            <result column="name" property="name"/>        </association>        <!-- 属性是一个集合, 使用collection 进行        映射处理, 其中 column="id" 是查询参数-->        <collection property="comments"             select="findCommentsByPostId"            column="id">        </collection>    </resultMap>    <select id="findCommentsByPostId"        parameterType="int"        resultType="cn.tedu.note.entity.Comment">        select             id,            title        from             p_comment        where            post_id=#{id}    </select>    <select id="findPostById"        parameterType="int"        resultMap="postMap">        select             p_post.id,             title,            person_id,            p.name        from             p_post        left outer join            p_person p on p.id=person_id         where             p_post.id=#{id}    </select>   </mapper>

    首先利用collection表示将comments属性委托到SQL查询 findCommentsByPostId , 再定义SQL查询findCommentsByPostId, 将comment属性的数据查询并且映射到Comment对象.

  8. 测试

    测试结果中将出现comments属性的值.

Struts2

MVC

  1. MVC模式是用户界面的经典设计模式! 无论是手机还是桌面以及WEB应用界面都采用了MVC模式.
  2. 在Java WEB编程中, 有很多的框架采用了MVC模式.

这里写图片描述

Spring MVC

这里写图片描述

Struts2 简介

  1. 来自Apache基金会的软件: http://struts.apache.org
  2. Struts2 与 Struts1 完全没有关系
  3. Struts2 的前身是 WebWorks
  4. Spring MVC\Struts2\Struts1 都是 MVC 模式的Web框架
    • MVC是非常流行的 用户界面设计模式。
    • MVC是3层架构中的表现层。

配置Struts2

配置步骤:

  1. 创建项目, 导入Struts2:

    <dependency>  <groupId>org.apache.struts</groupId>  <artifactId>struts2-core</artifactId>  <version>2.3.8</version></dependency>
  2. 配置Struts2 主控制器 web.xml

      <filter>    <display-name>StrutsPrepareAndExecuteFilter</display-name>    <filter-name>StrutsPrepareAndExecuteFilter</filter-name>    <filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>  </filter>  <filter-mapping>    <filter-name>StrutsPrepareAndExecuteFilter</filter-name>    <url-pattern>/*</url-pattern>  </filter-mapping>
  3. 添加Struts2的配置文件 struts.xml:

    <?xml version="1.0" encoding="UTF-8"?><!DOCTYPE struts PUBLIC    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"    "http://struts.apache.org/dtds/struts-2.3.dtd"><struts></struts>

    提示: DTD 信息可以从 struts2-core-2.3.8.jar 包的struts-2.3.dtd 文件中找到.

  4. 部署到tomcat 进行测试.

Hello World

工作原理为:

这里写图片描述

  1. 编写控制器类:

    public class DemoAction {    /**     * Struts2 控制器中的默认处理方法名为execute     * @return 返回视图的名称     */    public String execute(){        System.out.println("Hello World!");        return "success";    }}

    默认的控制器方法为execute!

  2. 编写jsp: /WEB-INF/jsp/ok.jsp

    <%@ page language="java"     contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title></title></head><body>    <h1>Struts2</h1>    <p>Hello World!</p></body></html>
  3. 编写配置文件

    <struts>    <!-- 定义WEB请求的第一层路径 namespace="/demo" -->    <package name="demo" namespace="/demo"        extends="struts-default" >        <action name="hello"             class="cn.tedu.controller.DemoAction">            <result name="success">                /WEB-INF/jsp/ok.jsp            </result>        </action>        <!-- 请求 /demo/hello.action 时候, 执行        DemoAction的execute方法, 当方法返回值是        success时候, 转发到ok.jsp -->    </package></struts>

    package 的 name 属性任意定义, 不重复即可

  4. 部署测试:

    http://localhost:8080/ssh1/demo/hello.action

接收用户提交的数据

利用 控制器 的 “Bean属性” 接收用户提交的数据

Bean属性: 是指类上声明的getXXX和setXXX方法

原理为:

这里写图片描述

案例:

  1. 声明控制器

    /** * 利用Bean属性接收用户提交的参数  */public class ParamAction {    private String name;    private int age;    public void setName(String name) {        this.name = name;    }    public void setAge(int age) {        this.age = age;    }    public String execute(){        System.out.println("name:"+name);        System.out.println("age:"+age);        return "success";    }}
  2. 编写JSP: param.jsp

    <%@ page language="java"     contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title>控制器接收参数</title></head><body>    <h1>Struts2</h1>    <p>接收参数</p></body></html>
  3. 配置控制器:

    <!-- 请求路径: /demo/param.action?name=Tom&age=5 --><action name="param"    class="cn.tedu.controller.ParamAction">    <result name="success">        /WEB-INF/jsp/param.jsp    </result></action>
  4. 测试:

    http://localhost:8080/ssh1/demo/param.action?name=Tom&age=5

    参数: Tom 和 5 将出现在 服务器的控制台上

利用领域模型(值对象)封装用户提交的参数

当用户提交的表单数据很多, 并且表单项目会重用时候, 可以利用领域模型(值对象)封装用户提交的表单:

这里写图片描述

案例:

  1. 声明领域模型(值对象)

    public class UserValue implements Serializable {    private static final long serialVersionUID = 232L;    private String name;    private String password;    private Integer age;    private String address;    public UserValue() {    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public String getPassword() {        return password;    }    public void setPassword(String password) {        this.password = password;    }    public Integer getAge() {        return age;    }    public void setAge(Integer age) {        this.age = age;    }    public String getAddress() {        return address;    }    public void setAddress(String address) {        this.address = address;    }    @Override    public String toString() {        return "UserValue [name=" + name + ", password=" + password + ", age=" + age + ", address=" + address + "]";    }}
  2. 定义控制器, 接收领域模型参数:

    public class UserAction {    private UserValue userValue;    public void setUserValue(UserValue userValue) {        this.userValue = userValue;    }    public UserValue getUserValue() {        return userValue;    }    public String execute(){        System.out.println(userValue);        return "success";    }}
  3. 开发JSP页面, 用于提交表单参数:

    <%@ page language="java"     contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title></title></head><body>    <h1>提交用户信息</h1>    <form action="demo/user.action"         method="post">        <div>            用户名:<input type="text"                 name="userValue.name">        </div>              <div>            密码:<input type="password"                name="userValue.password">        </div>        <div>            年龄:<input type="text"                name="userValue.age">         </div>        <div>            地址: <input type="text"                name="userValue.address">        </div>        <div>            <input type="submit" value="保存">        </div>    </form></body></html>

    表单中的input元素name属性必须写为 name=”userValue.address” 这样才能传递参数.

  4. 配置控制器 struts.xml

    <!-- 利用值对象打包传递参数 --><action name="user"    class="cn.tedu.controller.UserAction">    <result name="success">        /WEB-INF/jsp/ok.jsp    </result></action>
  5. 测试

    利用表单提交参数, 服务端手动打包的van是

将服务端的数据显示到页面上

控制器中的bean属性getXXX方法会自动传递到JSP中, 其底层是利用request传递的.

原理:

这里写图片描述

案例:

  1. 重构 UserAction, 添加 bean 属性 message:

    private String message;public String getMessage() {    return message;}public String execute(){    System.out.println(userValue);    message = "成功!";    //转发目标JSP收到两个Bean对象:     // message 和 userValue    //对应着 Action 对象的 getXXX方法    //在JSP中可以使用 EL 表达式访问这些属性    return "success";}

    在控制器方法中为message属性赋值

  2. 编写数据展示页面 success.jsp

    <%@ page language="java"     contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><!DOCTYPE html><html><head><meta charset="UTF-8"><title></title></head><body>    <h1>表单结果</h1>    <p>收到了两个bean对象: message, userValue</p>    <p>消息: ${message}</p>     <p>用户名: ${userValue.name}</p>    <p>密码: ${userValue.password}</p>    <p>年龄: ${userValue.age}</p>    <p>地址: ${userValue.address}</p></body></html>

    在JSP中可以利用EL表达式和 JSTL 配合显示控制器传递来的属性.

  3. 重构配置文件, UserAction 控制器处理结束后转发到 success.jsp

    <!-- 利用值对象打包传递参数 --><action name="user"    class="cn.tedu.controller.UserAction">    <result name="success">        /WEB-INF/jsp/success.jsp    </result></action>
  4. 测试

    控制器的数据可以成功的显示到JSP页面上.

Struts 2 控制器中访问 Session对象

在 Struts 2 控制器用两种访问Session的方式:

  1. 利用ActionContext 获取Session.

    • 代表当前控制器的工作环境: 被那个主控制器调用, 当前的request, 当前的resopnse, 当前session等信息, 都可以从 ActionContext 获得.

      ActionContext ctx = ActionContent.getContext();
      Map