初学java EE,虽然知道使用框架会使开发更加便捷高效,但是对于初学者来说,感到使用框架比较迷惑,尤其是各种jar包的引用、各种框架的配置、注解的使用等等。

最好的学习方法就是实践,于是下载了一个现成的DEMO,通过简单的修改先成功在自己电脑上跑起来,然后再逐个文件进行分析学习,最终才能从总体的高度上掌握框架的运行机制和配置方法,这样才能在实际运用中灵活配置,不会再局限于示例框架中。


SSM框架搭建流程

SSM框架Web程序的流程

上面链接总结的流程很好,但是该流程没有加入DAO这一层,经过分析本项目源码,流程应该是这样的:

database–>Entity.java–>mapper.xml–>Mapper.java–>Dao.java–>DaoImpl.java–>Service.java–>ServiceImpl.java–>Controller.java–>login.jsp

  • 根据需要建立数据库、数据表、字段;
  • 根据表中字段建立实体类;
  • 在Mapper中实现对数据库的增删改查操作;
  • 设计DAO(data access object)数据操作对象接口;
  • 设计Service,通过DAO获取对象,然后进行业务逻辑实现;
  • 设计控制层Controller,用于从页面获取请求,调用Service处理并将处理结果返回给页面。

根据上面所列,下面就按照这个流程进行设计。


数据库设计

使用MySQL数据库:

  • 建立数据库 DB_TEST
CREATE DATABASE DB_TEST;
  • 1
  • 建立用户表 T_USER
CREATE TABLE T_USER (
ID INTEGER PRIMARY KEY AUTO_INCREMENT NOT NULL,
USERNAME VARCHAR(16) NOT NULL,
PASSWORD VARCHAR(16) NOT NULL
);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 插入一条用户信息
INSERT INTO T_USER (USERNAME,PASSWORD) VALUES ("admin","123");
  • 1

建立USER实体类

public class User {

   private int id;
private String username;
private String password; public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

Mapper实现增删改查


  • UserMapper接口,定义通过用户名获取用户对象的方法
public interface UserMapper {

    public User getUserByName(String username);
}
  • 1
  • 2
  • 3
  • 4

  • usermapper.xml,用于操作数据库,实现接口中的方法
  <mapper namespace="com.crm.mapper.UserMapper">

    <resultMap type="com.crm.entity.User" id="userMap">
<id property="id" column="id" />
<result property="username" column="username" />
<result property="password" column="password" />
</resultMap> <!-- 此处select标签的id值对应Mapper类中方法名 -->
<select id="getUserByName" parameterType="string" resultMap="userMap">
<!-- 此处写sql语句,#{Mapper类传入的参数} -->
select * from T_USER where username = #{username}
</select>
</mapper>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

DAO 数据操作对象


  • DAO接口  UserDao.java
public interface UserDao {
//接口方法,通过用户名得到User对象
public User findUserByName(String username);
}
  • 1
  • 2
  • 3
  • 4

  • DAO接口实现  UserDaoImpl.java

@Repository对应数据访问层Bean

@Repository(value=”userDao”)注解是告诉Spring,让Spring创建一个名字叫“userDao”的UserDaoImpl实例。

当Service需要使用Spring创建的名为“userDao”的UserDaoImpl实例时,   就可以使用@Resource(name =”userDao”)注解告诉Spring,Spring把创建好的userDao注入给Service即可。

@Repository("userDao")
public class UserDaoImpl implements UserDao {
//注解引用Mapper类资源
@Resource(name = "userMapper")
private UserMapper userMapper; /* 根据用户名查找用户对象 */
public User findUserByName(String username) {
//调用Mapper类从数据库中得到User对象
return userMapper.getUserByName(username);
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

业务层 Service


  • 业务层接口 UserService.java
public interface UserService {
// 通过用户名及密码核查用户登录
public User checkLogin(String username, String password);
}
  • 1
  • 2
  • 3
  • 4

  • 业务层接口实现类 UserServiceImpl.java

@Service对应的是业务层Bean

这样当Action需要使用UserServiceImpl的的实例时,就可以由Spring创建好的”userService”注入给Action:在Action只需要声明一个名字叫“userService”的变量来接收由Spring注入的”userService”即可

@Service("userService")
public class UserServiceImpl implements UserService {
@Resource
private UserDao userDao; /* 登陆验证 */
public User checkLogin(String username, String password) {
//根据用户名实例化用户对象
User user = userDao.findUserByName(username);
if (user != null && user.getPassword().equals(password)) {
return user;
}
return null;
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

控制层 Controller


@Controller对应表现层的Bean,也就是Action

注意:如果@Controller不指定其value【@Controller】,则默认的bean名字为这个类的类名首字母小写,如果指定value【@Controller(value=”UserAction”)】或者【@Controller(“UserAction”)】,则使用value作为bean的名字。


@Scope(“prototype”)表示将Action的范围声明为原型

可以利用容器的scope=”prototype”来保证每一个请求有一个单独的Action来处理,避免struts中Action的线程安全问题。

spring 默认scope 是单例模式(scope=”singleton”),这样只会创建一个Action对象,每次访问都是同一Action对象,数据不安全。

struts2 是要求每次次访问都对应不同的Action,scope=”prototype” 可以保证当有请求的时候都创建一个Action对象


@RequestMapping(“/user”)

RequestMapping是一个用来处理请求地址映射的注解,可用于类或方法上。用于类上,表示类中的所有响应请求的方法都是以该地址作为父路径。


本项目中,该Controller类RequestMapping(”user”)   该Controller类的login方法RequestMapping(”login”)   所以登录页面中用户登录的 action=”/ssm/user/login”


@Controller
@Scope(value="prototype")
@RequestMapping("/user")
public class UserController { @Resource
private UserService userService; @RequestMapping(value="/login",method=RequestMethod.POST)
public String login(User user,Model model) throws Exception {
user=userService.checkLogin(user.getUsername(), user.getPassword());
if(user!=null){
model.addAttribute(user);
return "welcome";// 路径 WEB-INF/pages/welcome.jsp
}
return "fail";
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

页面 JSP


<html xmlns="http://www.w3.org/1999/xhtml">

<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>用户登录</title>
</head> <body>
<form action="/ssm/user/login" method="post" id="myform">
<input type="text" id="username" name="username"/>
<input type="password" id="password" name="password"/>
<input type="submit" value="提交" id="login" />
</form>
</body> </html>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

DEMO工程中的所有配置文件


applicationContext.xml

这个文件是Spring公共配置文件,下面分块进行解析。

  • 数据库配置文件database.properties的引入
    <bean id="property"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<!-- classpath 即src根目录 -->
<value>classpath:database.properties</value>
</list>
</property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

  • 数据库连接池的配置

数据库连接池可以让服务器预先与数据库建立部分连接,存入内存中,以减少连接数据库的耗时操作。   此处定义使用C3P0连接池的数据源。

    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource"
destroy-method="close"> <!-- 指定连接数据库的JDBC驱动 -->
<property name="driverClass">
<value>${mysql.driver_class}</value>
</property> <!-- 连接数据库所用的URL -->
<property name="jdbcUrl">
<value>${mysql.connection.url}</value>
</property> <!-- 连接数据库的用户名 -->
<property name="user">
<value>${mysql.connection.username}</value>
</property> <!-- 连接数据库的密码 -->
<property name="password">
<value>${mysql.connection.password}</value>
</property> <!-- 设置数据库连接池的最大连接数 -->
<property name="maxPoolSize">
<value>30</value>
</property> <!-- 设置数据库连接池的最小连接数 -->
<property name="minPoolSize">
<value>2</value>
</property> <!-- 设置数据库连接池的初始化连接数 -->
<property name="initialPoolSize">
<value>2</value>
</property> <!-- 设置数据库连接池的连接的最大空闲时间,单位为秒 -->
<property name="maxIdleTime">
<value>10</value>
</property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43

  • 自动扫描配置

使用< context:component-scan>标签后,spring可以自动去扫描base-pack下面或者子包下面的java文件,如果扫描到有@Component @Controller@Service等这些注解的类,则把这些类注册为bean

    <context:component-scan base-package="com.crm.*">
<!-- 不扫描注解为controller的类型 -->
<context:exclude-filter type="annotation" expression="org.springframework.stereotype.Controller" />
</context:component-scan>
  • 1
  • 2
  • 3
  • 4

  • 集成Mybatis

SqlSessionFactoryBean是一个工厂bean,它的作用就是解析配置(数据源、别名等)。

    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">

        <!-- 引用上面已经配置好的数据库连接池 -->
<property name="dataSource" ref="dataSource" /> <!-- Mybatis的配置文件路径 -->
<property name="configLocation" value="classpath:mybatis.xml" /> <!-- mapper配置路径 -->
<property name="mapperLocations">
<list>
<value>classpath:com/crm/mapper/*.xml</value>
</list>
</property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

  • Mapper扫描配置

dao需要配置,如果数量大不适合一个个配置,需要使用mapper自动扫描来批量进行配置。

    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.crm.mapper" />
</bean>
  • 1
  • 2
  • 3

  • Mybatis事务管理配置
    <bean id="transactionManager"
class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean>
  • 1
  • 2
  • 3
  • 4

数据库配置文件database.properties

mysql.driver_class=com.mysql.jdbc.Driver
<!-- DB_TEST为新建的数据库名 -->
mysql.connection.url=jdbc:mysql://localhost:3306/DB_TEST
<!-- 登录数据库的用户名密码 -->
mysql.connection.username=root
mysql.connection.password=root
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

日志管理文件 log4j.properties

此处省略,入门阶段暂不考虑这么高端的日志用法。


Mybatis配置文件

通过使用别名,可以缩短类名的长度,但是只能在配置文件中使用。

<configuration>
<!-- 别名 -->
<typeAliases>
<typeAlias type="com.crm.entity.User" alias="user" />
</typeAliases>
</configuration>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

web配置文件

此配置文件注释比较清楚,就不单独解析了。

    <display-name>crm</display-name>

    <!--一个server下如果有多个项目,要对webAppRootKey进行配置,让log能将日志写到对应项目根目录下-->
<context-param>
<param-name>webAppRootKey</param-name>
<param-value>crm.root</param-value>
</context-param> <!-- 由Sprng载入的Log4j配置文件位置 -->
<context-param>
<param-name>log4jConfigLocation</param-name>
<param-value>classpath:log4j.properties</param-value>
</context-param> <!-- Spring默认刷新Log4j配置文件的间隔,单位为millisecond -->
<context-param>
<param-name>log4jRefreshInterval</param-name>
<param-value>60000</param-value>
</context-param> <!-- Web 项目 Spring 加载 Log4j 的监听 -->
<listener>
<listener-class>org.springframework.web.util.Log4jConfigListener</listener-class>
</listener> <!-- 设置Spring容器加载配置文件路径 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:springContext/*Context.xml</param-value>
</context-param> <!-- 加载Spring容器配置 -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener> <!-- 防止内存泄漏的监听器 -->
<listener>
<listener-class>
org.springframework.web.util.IntrospectorCleanupListener
</listener-class>
</listener> <!-- 配置Springmvc核心控制器 -->
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/springmvc.xml</param-value>
</init-param>
<!-- 立马启动servlet -->
<load-on-startup>1</load-on-startup>
</servlet> <!-- servlet-mapping配置 -->
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping> <!-- 解决工程编码过滤器 -->
<filter>
<filter-name>characterEncodingFilter</filter-name>
<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
<init-param>
<param-name>encoding</param-name>
<param-value>UTF-8</param-value>
</init-param>
</filter> <filter-mapping>
<filter-name>characterEncodingFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping> <!-- 设置默认打开页面列表 -->
<welcome-file-list>
<welcome-file>login.jsp</welcome-file>
</welcome-file-list>
</web-app>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81

springmvc配置文件

之前扫描专门忽略了Controller,在此处扫描。

例如在Controller类中常有类似return welcome这样的语句

其实完整的应该是return WEB-INF/pages/welcome.jsp

    <!-- 注解Controller扫描器 -->
<context:component-scan base-package="com.crm.controller"/> <!-- 静态资源访问 -->
<mvc:resources location="/img/" mapping="/img/**"/>
<mvc:resources location="/js/" mapping="/js/**"/>
<mvc:resources location="/common/" mapping="/common/**"/> <!-- 注解功能的默认配置,处理器和映射器 -->
<bean id="handlerMapping" class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" /> <bean id="handlerAdapter" class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" /> <!-- 前后缀配置 -->
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/WEB-INF/pages/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

至此基本内容已经全部完了,项目可以轻松跑起来了。

但是在学习过程中,发现这些框架真的是太强大了,不知道什么时候才能掌握更多,目前仅仅是会用最基本的皮毛而已。

笔耕不缀,必有收获;代码不停,早晚能行。

SSM框架搭建web服务器实现登录功能(Spring+SpringMVC+Mybatis)的更多相关文章

  1. SSM 框架-06-详细整合教程(IDEA版)(Spring+SpringMVC+MyBatis)

    SSM 框架-06-详细整合教程(IDEA版)(Spring+SpringMVC+MyBatis) SSM(Spring.Spring MVC和Mybatis)如果你使用的是 Eclipse,请查看: ...

  2. SSM 框架-05-详细整合教程(Eclipse版)(Spring+SpringMVC+MyBatis)

    SSM 框架-05-详细整合教程(Eclipse版)(Spring+SpringMVC+MyBatis) 如果你使用的是 Intellij IDEA,请查看: SSM的配置流程详细的写了出来,方便很少 ...

  3. 记录-项目java项目框架搭建的一些问题(maven+spring+springmvc+mybatis)

    伴随着项目框架的落成后,本以为启动就能成功的,but.... 项目启动开始报错误1:java.lang.ClassNotFoundException: org.springframework.web. ...

  4. SSM框架Web程序的流程(Spring SpringMVC Mybatis)

    SSM框架的Web程序主要用到了三个技术: Spring:用到了注解和自动装配,就是Spring的两个精髓IOC(反向控制)和 AOP(面向切面编程). SpringMVC:用到了MVC模型,将逻辑代 ...

  5. 简单的使用Nginx框架搭建Web服务器~

    系统环境Debian 8,内核版本 一.首先来安装nginx服务程序:  1.安装nginx服务需要的相关程序(记得在root权限下操作下面的指令) aptitude install libpcre3 ...

  6. SSM框架开发web项目系列(六) SpringMVC入门

    前言 我们最初的javaSE部分学习后,基本算是入门了,也熟悉了Java的语法和一些常用API,然后再深入到数据库操作.WEB程序开发,渐渐会接触到JDBC.Servlet/Jsp之类的知识,期间可能 ...

  7. SSM框架开发web项目系列(七) SpringMVC请求接收

    前言 在上篇Spring MVC入门篇中,我们初步了解了Spring MVC开发的基本搭建过程,本文将针对实际开发过程的着重点Controller部分,将常用的知识点罗列出来,并配以示例.在这之前,我 ...

  8. Spring+SpringMVC+Mybatis(SSM)框架集成搭建

    Spring+SpringMVC+Mybatis框架集成搭建教程 一.背景 最近有很多同学由于没有过SSM(Spring+SpringMvc+Mybatis , 以下简称SSM)框架的搭建的经历,所以 ...

  9. Spring+SpringMvc+Mybatis框架集成搭建教程

    一.背景 最近有很多同学由于没有过SSM(Spring+SpringMvc+Mybatis , 以下简称SSM)框架的搭建的经历,所以在自己搭建SSM框架集成的时候,出现了这样或者那样的问题,很是苦恼 ...

随机推荐

  1. 归并树 划分树 可持久化线段树(主席树) 入门题 hdu 2665

    如果题目给出1e5的数据范围,,以前只会用n*log(n)的方法去想 今天学了一下两三种n*n*log(n)的数据结构 他们就是大名鼎鼎的 归并树 划分树 主席树,,,, 首先来说两个问题,,区间第k ...

  2. nginx+uwsgi+django1.8.5配置

    http://jingyan.baidu.com/article/2d5afd69cdf6ad85a3e28e4f.html(搜索: wusgi 配置django1.8项目) http://my.os ...

  3. C程序设计语言练习题1-7

    练习1-7 编写一个打印EOF的值的程序. #include <stdio.h> // 包含标准库的信息. int main() // 定义名为main的函数,它不接受参数值. { // ...

  4. 一个oracle存储过程

    打开plsql,在packages文件夹里新建存储过程 在sql窗口中运行如下语句 create or replace package SY_USER_PKG1 is TYPE MYCURSOR IS ...

  5. 十分钟让你的ASP.NET MVC网站变成PHP

    昨天从网上看来的,某个人发的方法: 第一:修改一下路由: 把RouteConfig中的: routes.MapRoute( name: "Default", url: " ...

  6. Ubuntu 下安装使用文件比较合并图形工具Meld

    Meld是一款跨平台的文件比较合并工具使用Python开发,具体内容参照官网:http://meldmerge.org/ 注意以下环境要求: Requirements Python 2.7 (Pyth ...

  7. 【Xamarin 在Mac OS 上的部署安装环境】

    ******************没用Mac 的机子,也只能靠虚拟机了**********1 安装VMware 10 从网上下载即可2 下载MAC OS 10.9.5的安装镜像,网上有很多,最好使用 ...

  8. android面试题之六

    三十一.AIDL的全称是什么?如何工作?能处理哪些类型的数据? 英文全称:Android Interface Define Language(Android接口定义语言). 当A进程要去调用B进程中的 ...

  9. pyqt一个小例子

    # -*- coding: utf-8 -*- __author__ = 'Administrator' from PyQt4 import Qt,QtCore,QtGui import sys,ra ...

  10. 使用python监听、模拟鼠标键盘事件

    最近守望职业选手疑似开挂事件挺热闹的,在下小菜一枚,并不能从视频中看出端倪.看了一些关于外挂的讨论,自动点射和压枪只需在鼠标驱动上做些改动即可,自瞄或其他高级功能则需要读内存或修改游戏文件,检测也更容 ...