首页 > 代码库 > spring、springmvc、mybatis整合笔记

spring、springmvc、mybatis整合笔记

  这段时间上一个项目刚做完,下一个项目还没开始,趁这个时候来认真总结一下上个项目使用的ssm开发框架。由于,项目中关于使用ssm这部分的代码和配置是我们项目的整体架构师一个独立完成的,我们只负责业务部分的代码,调用他写好的后台,所以涉及到ssm具体使用的我都没参与,之前简单的做过s(struts)sh,对于ssm不是很熟悉,所以,这段时间从头到尾独立搭建一个ssm框架的web应用。

  首先,spring、springmvc、mybatis所需要的jar包准备好,导入到新建web项目的lib中,然后开始搭建java源代码(src)下的结构,我在这里用到的是类似ssh的结构mapper.java、mapper.xml、dao、daoImpl、service、serviceImpl、controller。项目目录结构如下。

技术分享

  接下来,写配置文件。

  web.xml

<?xml version="1.0" encoding="UTF-8"?><web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd" id="WebApp_ID" version="3.0">  <display-name>SSM</display-name>    <!-- spring配置文件加载 -->  <context-param>      <param-name>contextConfigLocation</param-name>      <param-value>classpath:resources/spring-config.xml</param-value>  </context-param>    <!-- Spring ApplicationContext 载入 -->  <listener>      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>  </listener>    <!-- mvc控制器 -->  <servlet>      <servlet-name>dispatcher</servlet-name>      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>      <init-param>          <param-name>contextConfigLocation</param-name>            <param-value>                classpath:resources/mvc-config.xml            </param-value>      </init-param>      <load-on-startup>1</load-on-startup>  </servlet>    <servlet-mapping>      <servlet-name>dispatcher</servlet-name>      <url-pattern>*.do</url-pattern>  </servlet-mapping>    <!-- 默认显示的首页面 -->  <welcome-file-list>    <welcome-file>login.html</welcome-file>    <welcome-file>login.jsp</welcome-file>  </welcome-file-list></web-app>

-----------------------------------------------spring.xml--------------------------------------

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:aop="http://www.springframework.org/schema/aop"     xmlns:tx="http://www.springframework.org/schema/tx"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans.xsd     http://www.springframework.org/schema/aop     http://www.springframework.org/schema/aop/spring-aop.xsd     http://www.springframework.org/schema/tx      http://www.springframework.org/schema/tx/spring-tx.xsd     http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context.xsd">        <!-- 扫描DAO和SERVICE包,controller包在springmvc中扫描 -->    <context:component-scan base-package="com.liusk.serviceImpl,com.liusk.daoImpl" />        <!-- 数据源 -->    <bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">        <property name="driverClass" value="com.mysql.jdbc.Driver"></property>        <property name="jdbcUrl" value="jdbc:mysql://localhost:3306/ssm?characterEncoding=utf-8"></property>        <property name="user" value="root"></property>        <property name="password" value="java"></property>        <property name="minPoolSize" value="5"></property>        <property name="maxPoolSize" value="100"></property>    </bean>        <!-- 会话工厂 -->    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">        <property name="dataSource" ref="dataSource"></property>        <property name="configLocation" value="classpath:resources/mybatis-config.xml"></property>        <property name="mapperLocations" value="classpath:com/liusk/mapper/*.xml"></property>    </bean>        <!-- 事务处理 -->    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">        <property name="dataSource" ref="dataSource"></property>    </bean>    <tx:advice id="txAdvice" transaction-manager="txManager">        <tx:attributes>            <tx:method name="insert*" propagation="REQUIRED"></tx:method>            <tx:method name="delete*" propagation="REQUIRED"></tx:method>            <tx:method name="update*" propagation="REQUIRED"></tx:method>            <tx:method name="select*" propagation="SUPPORTS"></tx:method>        </tx:attributes>    </tx:advice>    <aop:config>        <aop:pointcut id="serviceCut" expression="execution(public * com.liusk.service.*.*(..))" />        <aop:advisor pointcut-ref="serviceCut" advice-ref="txAdvice" />    </aop:config>        <!-- spring和mybatis的整合 -->    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">        <property name="basePackage" value="com.liusk.mapper"/>    </bean>    </beans>

  关于spring和mybatis整合的方法有很多种,上面xml中是最基础的配置,还可以加入其它的限制条件,这个可以单独到百度上搜更详细的解释。

-------------------------------------------------------mvc-config.xml------------------------------------------------

<?xml version="1.0" encoding="UTF-8"?><beans xmlns="http://www.springframework.org/schema/beans"    xmlns:context="http://www.springframework.org/schema/context"    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"    xsi:schemaLocation="http://www.springframework.org/schema/beans     http://www.springframework.org/schema/beans/spring-beans-3.0.xsd     http://www.springframework.org/schema/context     http://www.springframework.org/schema/context/spring-context-3.0.xsd">    <!-- 扫描controller包 -->    <context:component-scan base-package="com.liusk.controller"></context:component-scan>        <!-- 完成请求和注解POJO的映射 -->    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter"/>        <!-- 页面转向解析 -->    <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">        <property name="prefix" value="/" />        <property name="suffix" value=".jsp" />    </bean>        <!-- 支持文件上传 -->    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    </bean>    </beans>

  在mvcconfig中,最重要的工作是控制转发,这个配置文件中做了最简单的转发操作,只能转发页面,如果想要通过ajax实现转发数据,那么需要重写ViewResolver来实现这个功能。

--------------------------------------------------------mybatis-config.xml-------------------------------------

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>        <!-- 定义别名 -->    <typeAliases>        <typeAlias type="com.liusk.entity.User" alias="User"/>    </typeAliases>    </configuration>

  至此,配置文件部分完毕。

  下面是src源码

----------------------------------------------------------User.java------------------------------------------------------

package com.liusk.entity;public class User {    private String userId;    private String username;    private String password;        public String getUserId() {        return userId;    }    public void setUserId(String userId) {        this.userId = userId;    }    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;    }}

  mybatis的实体类和hibernate实体类的不同是mybatis的实体类不需要加载到spring的beanFactory中,而是通过操作数据库的mapper来持久化数据。

-----------------------------------------------------------UserMapper.java------------------------------------------

package com.liusk.mapper;import java.util.List;import com.liusk.entity.User;public interface UserMapper {    public List<User> selectUser(User user);    public void insertUser(User user);    public List<User> selectUserByUserName(String username);}

  UserMapper.java这个文件是在何时被加载到spring中的呢?我们知道它是在daoImpl中使用到的,而且是注解到daoImpl中的,所以它一定在之前已经被加载到beanFactory中了,我在第一次配置的时候也不是太清楚它是什么时候进入beanFactory因为它身上没有任何注解,所以,根据spring配置文件中spring和mybatis的整合,推测UserMapper.java就是在

<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="http://www.mamicode.com/com.liusk.mapper"/></bean>

这个地方被加载的。这个下面有详细解答。

----------------------------------------------------------UserMapper.xml------------------------------------------

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.liusk.mapper.UserMapper">        <resultMap type="com.liusk.entity.User" id="userMap">        <id column="user_id" property="userId" ></id>        <result column="user_name" property="username"/>        <result column="password" property="password"/>    </resultMap>        <select id="selectUser" parameterType="User" resultType="java.util.List" resultMap="userMap">        select * from user where user_name = #{username} and password = #{password}    </select>        <select id="selectUserByUserName" parameterType="java.lang.String" resultType="java.util.List" resultMap="userMap">        select * from user where user_name = #{username}    </select>        <insert id="insertUser" parameterType="User">        insert into user values (#{userId},#{username},#{password})    </insert>    </mapper>

  该配置文件中namespace对应接口的路径,也就是mapper.java的路径,否则抛出异常。所以这里牵涉到一个问题:UserMapper.java到底是何时加载到beanFactory的?为什么会用这个问题呢,应为UserMapper.xml在spring的sessionFactory初始化的时候被扫描并加载到spring,那么这个时候会不会根据这个命名空间同时把UserMapper.java加载到beanFactory中呢,其实我没有看过spring和mybatis的源码,所以不太了解。根据猜测和验证,UserMapper.java不是在这个时候被加载的。

------------------------------------------------------UserDAO--------------------------------------------

package com.liusk.dao;import java.util.List;import com.liusk.entity.User;public interface UserDAO {        public List<User> selectUser(User user);        public void insertUser(User user);        public List<User> selectUserByUserName(String username);}

这个UserDAO的存在就是在向我的第一个项目使用ssh致敬的,其实这个UserDAO他就是个接口,可以不存在,下面的UserService也是这个道理。

------------------------------------------------------UserDAOImpl----------------------------------------

package com.liusk.daoImpl;import java.util.List;import org.safehaus.uuid.UUIDGenerator;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Repository;import com.liusk.dao.UserDAO;import com.liusk.entity.User;import com.liusk.mapper.UserMapper;@Repositorypublic class UserDAOImpl implements UserDAO {        @Autowired    private UserMapper userMapper;        private UUIDGenerator uuidGen = UUIDGenerator.getInstance();        @Override    public List<User> selectUser(User user) {        return userMapper.selectUser(user);    }    @Override    public void insertUser(User user) {        String userId = uuidGen.generateTimeBasedUUID().toString();        if(user.getUserId()==null||user.getUserId()=="")            user.setUserId(userId.replace("-", ""));        System.out.println(user.getUserId());        userMapper.insertUser(user);     }    @Override    public List<User> selectUserByUserName(String username) {        return userMapper.selectUserByUserName(username);            }    }

UserDAOImpl和UserServiceImpl类似,都是实现类,做具体的数据持久化操作。

--------------------------------------------------------UserService-----------------------------------------

package com.liusk.service;import java.util.List;import com.liusk.entity.User;public interface UserService {        public void insertUser(User user);        public List<User> selectUser(User user);        public boolean existUser(String username);    }

--------------------------------------------------------UserServiceImpl--------------------------------------

package com.liusk.serviceImpl;import java.util.List;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import com.liusk.dao.UserDAO;import com.liusk.entity.User;import com.liusk.service.UserService;@Servicepublic class UserServiceImpl implements UserService{    @Autowired    private UserDAO userDAO;        @Override    public void insertUser(User user) {        userDAO.insertUser(user);    }    @Override    public List<User> selectUser(User user) {        return userDAO.selectUser(user);    }    @Override    public boolean existUser(String username) {        List<User> userList = userDAO.selectUserByUserName(username);        if(userList.size()>0)            return true;        else            return false;    }}

-------------------------------------------------------UserController-------------------------------------

package com.liusk.controller;import java.util.List;import javax.servlet.http.HttpServletRequest;import javax.servlet.http.HttpSession;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Controller;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.servlet.ModelAndView;import com.liusk.base.UserCounts;import com.liusk.entity.User;import com.liusk.service.UserService;@Controller@RequestMapping("user")public class UserController {        @Autowired    private UserService userService;        @SuppressWarnings("rawtypes")    @RequestMapping("login.do")    public ModelAndView login(String username,String password,HttpServletRequest request){        User user = new User();        user.setUsername(username);        user.setPassword(password);        List<User> userList = userService.selectUser(user);        if(userList.size()>0){            request.setAttribute("userList", userList);return new ModelAndView("index");        }else            return new ModelAndView("login");    }        @RequestMapping("regist.do")    public ModelAndView regist(String username,String password,HttpServletRequest request){        User user = new User();        user.setUsername(username);        user.setPassword(password);        boolean flag = true;        flag = userService.existUser(username);        if(!flag)            userService.insertUser(user);        return new ModelAndView("login");    }}

  至此,src下的java源码完毕。

  下面是jsp页面部分。

-----------------------------------------------------login.jsp--------------------------------------------------

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%>    <%    String path = request.getContextPath();    String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><base href=" <%=basePath%>"><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>登录页面</title></head><body><div>    <div>            <form action="user/login.do" method="post">            <label>用户名:</label>            <input type="text" name="username" />            <label>密码:</label>            <input type="password" name="password"/>            <button type="submit">登录</button>            <button type="reset" >重置</button>                </form>        </div>    </div></body></html>

-----------------------------------------------------index.jsp--------------------------------------------------------

<%@ page language="java" contentType="text/html; charset=UTF-8"    pageEncoding="UTF-8"%><%@ page import="com.liusk.entity.User" %><%@ page import="java.util.List" %><%String path = request.getContextPath();String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/";%><%    List<User> userList = (List<User>)request.getAttribute("userList");%><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><base href=" <%=basePath%>"/><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>index</title></head><body><div>    <p>欢迎<%=userList.get(0).getUsername() %>!</p></div><div align="center" style="width:200;height:200">    <form action="user/regist.do" method="post">        <input type="text" name="username"/>        <input type="text" name="password"/>        <button type="submit">提交</button>        <button type="reset">重置</button>    </form></div></body></html>

  jsp你懂得,这些页面就不做多解释。

  总结,会用框架不难,难的是写一个框架出来,有梦就要勇敢飞。

技术分享

spring、springmvc、mybatis整合笔记