SSM整合

Posted xfdhh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了SSM整合相关的知识,希望对你有一定的参考价值。

第一步:准备依赖

1、Spring-core beans expression context aop tx jdbc web webmvc
2、Druid mysql-connector-java mybatis mybatis-spring
3、 Log4j slf4j-api slf4j-log4j12
4、Jstl servlet-api Lombok aspectjweaver

第二步:项目准备

1、数据库准备,准备好测试要用的表及数据

2、架构设计

技术图片

 3、bean中的类(属性与数据库中的表对应)

技术图片
@Setter@Getter@AllArgsConstructor@NoArgsConstructor@ToString
public class User 
    private Integer id;
    private String username;
    private String pwd;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private Date date;
    public String getDate()
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(this.date);
    
User

  条件查询时封装的条件类

技术图片
@Setter@Getter@ToString
public class QueryBean 

    private String username;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    private String date;
    private Integer currentPage;
    private Integer pageSize;
    //修改set方法可以在接收前端参数进行封装时进行判断修改
    public void setCurrentPage(Integer currentPage)
        if(currentPage!=null)
            this.currentPage=currentPage;
        else
            this.currentPage=1;
        
    
    public void setPageSize(Integer pageSize)
        if(pageSize!=null)
            this.pageSize=pageSize;
        else
            this.pageSize=3;
        
    

    //重写get方法,对多条件的结果进行预判断,可以减少xml中配置的代码
    public String getUsername()
        return StringUtils.isNullOrEmpty(this.username)?null:this.username;
    
    public String getDate()
        return StringUtils.isNullOrEmpty(this.date)?null:this.date;
    
    //使用getStart方法可以返回start属性,在定义分页工具查询时使用
    public Integer getStart()
        return (this.currentPage-1)*this.pageSize;
    

    /*如果使用date类型的date,可以将get方法返回的结果转换格式返回
    public String getDate()
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(this.date);
    */
条件查询时封装的条件类QueryBean

4、mapper接口,以及对应方法的xml文件

技术图片
public interface UserMapper 
    //增删改查
    Integer save(User user);
    Integer update(User user);
    Integer delete(Integer id);
    User findById(Integer id);
    List<User> findAll();
    //条件查询用到的方法
    List<User> select(QueryBean queryBean);

    //登录检查需要用到的方法
    String login(String username);
    //手动实现分页需要用到的方法
    Integer selectCount(QueryBean queryBean);
    List<User> selectAll(QueryBean queryBean);
UserMapper接口
技术图片
<?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.test.ssm.mapper.UserMapper">
    <insert id="save">
        insert into users values(null,#username,#pwd,#date)
    </insert>
    <update id="update">
        update users set username=#username,pwd=#pwd,date=#date where id=#id
    </update>
    <delete id="delete">
        delete from users where id=#id
    </delete>

    <resultMap id="myResultMap" type="user">
        <id property="id" column="id"/>
        <result column="username" property="username"/>
        <result column="pwd" property="pwd"/>
        <result column="date" property="date"/>
    </resultMap>

    <select id="findById" resultMap="myResultMap">
        select * from users where id=#id
    </select>

    <select id="findAll" resultMap="myResultMap">
        select * from users
    </select>

    <select id="select" resultMap="myResultMap">
        select * from users
        <where>
            <!--在条件类中将get方法封装后可以简化的代码
            <if test="username!=null and username!=‘‘">
                and username like concat(‘%‘,#username,‘%‘)
            </if>
            <if test="date!=null and date!=‘‘">
                and date like concat(‘%‘,#date,‘%‘)
            </if>-->
            <if test="username!=null">
                and username like concat(‘%‘,#username,‘%‘)
            </if>
            <if test="date!=null">
                and date like concat(‘%‘,#date,‘%‘)
            </if>
        </where>
    </select>
    
    <!--手动实现分页需要用到的查询,查询总条数-->
    <select id="selectCount" resultType="integer">
        select count(*) from users
        <where>
            <if test="username!=null">
                and username like concat(‘%‘,#username,‘%‘)
            </if>
            <if test="date!=null">
                and date like concat(‘%‘,#date,‘%‘)
            </if>
        </where>
    </select>
    <!--手动实现分页需要用到的查询,条件查询-->
    <select id="selectAll" resultMap="myResultMap">
        select * from users
        <where>
            <if test="username!=null">
                and username like concat(‘%‘,#username,‘%‘)
            </if>
            <if test="date!=null">
                and date like concat(‘%‘,#date,‘%‘)
            </if>
        </where>
        limit #start,#pageSize
    </select>

    <!--登录检测需要用到的查询-->
    <select id="login" resultType="java.lang.String">
        select pwd from users where username=#username
    </select>
</mapper>
UserMapper.xml

5、service接口,以及实现类(使用mapper对象)

  传统的方式是

  1:获取Factory对象,new SqlSessionFactoryBuilder().build(输入流);

  2:获取SqlSession对象,Factory.openSession()

  3:获取mapper对象,SqlSession.getMapper()

  整合后的方式为

  1.配置MapperFactoryBean(一次只能创建一个) mapperScannerConfigurer(批量创建,从配置的包中扫描所有赛接口,并且创建代理对象)

  2.两个属性,一个是要创建的接口<property name="mapperInterface" value=""/>,一个是sqlsessionfactory

  3.配置sqlsessionfactory,几个主要属性

    数据源dataSource
    配置别名typeAliasesPackage
    关联mapper映射文件mapperLocations
    关联mybatis的主配置文件configLocation

技术图片
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xsi:schemaLocation="
       http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.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
       http://www.springframework.org/schema/aop
       http://www.springframework.org/schema/aop/spring-aop.xsd
">
    <!--加载数据库的配置文件-->
    <context:property-placeholder location="classpath:db.properties" system-properties-mode="NEVER"/>

    <bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource">
        <property name="driverClassName" value="$jdbc.driverClassName"/>
        <property name="url" value="$jdbc.url"/>
        <property name="username" value="$jdbc.username"/>
        <property name="password" value="$jdbc.password"/>
    </bean>
    <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
        <!--数据源-->
        <property name="dataSource" ref="dataSource"/>
        <!--配置别名-->
        <property name="typeAliasesPackage" value="com.test.ssm.bean"/>
        <!--关联mapper映射文件-->
        <property name="mapperLocations" value="classpath:com/test/ssm/mapper/*Mapper.xml"/>
        <!--关联mybatis的主配置文件-->
        <property name="configLocation" value="classpath:mybatis.xml"/>
    </bean>

    <!--<bean id="mapperFactory" class="org.mybatis.spring.mapper.MapperFactoryBean">
        <property name="mapperInterface" value="com.test.ssm.mapper.UserMapper"/>
        <property name="sqlSessionFactory" ref="sqlSessionFactory"/>
    </bean>

    <bean id="service" class="com.test.ssm.service.impl.UserServiceImpl">
        <property name="userMapper" ref="mapperFactory"/>
    </bean>-->

    <!--配置mapper接口扫描器MapperScannerConfigurer
        会从配置的包中,扫描所有的接口,并且创建接口的代理对象
        下面的bean等同与上面注释的两个的作用
    -->
    <bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.test.ssm.mapper"/>
        <!--当配置文件中只有一个数据源的时候,可以不写这个参数
        有多个数据源的时候,需要指定使用哪个数据源-->
        <!--<property name="sqlSessionFactoryBeanName" value="sqlSessionFactory" />-->
    </bean>

    <!--IoC注解扫描-->
    <context:component-scan base-package="com.test.ssm"/>
    <!--事务管理器-->
    <bean id="txManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="dataSource"/>
</bean>

    <!--使用注解方式只需要配置事务注解驱动,然后将事务管理器进行绑定
    在需要事务控制的类上贴上@Transactional即可-->
    <!--<aop:config>
        <aop:pointcut id="pointcut" expression="execution( * com.test.ssm.service..*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>-->

    <!--事务管理器注解驱动-->
    <tx:annotation-driven transaction-manager="txManager"/>
</beans>
applicationContext.xml
技术图片
public interface UserMapper 
    //增删改查
    Integer save(User user);
    Integer update(User user);
    Integer delete(Integer id);
    User findById(Integer id);
    List<User> findAll();
    //条件查询用到的方法
    List<User> select(QueryBean queryBean);

    //登录检查需要用到的方法
    String login(String username);
    //手动实现分页需要用到的方法
    Integer selectCount(QueryBean queryBean);
    List<User> selectAll(QueryBean queryBean);
IUserService
技术图片
@Service
@Transactional
public class UserServiceImpl implements IUserService 
    @Autowired
    private UserMapper userMapper;

    public Integer save(User user) 
        return userMapper.save(user);
    

    public Integer update(User user) 
        Integer update = userMapper.update(user);
        //System.out.println(1/0);
        return update;
    

    public Integer delete(Integer id) 
        return userMapper.delete(id);
    

    public User findById(Integer id) 
        return userMapper.findById(id);
    

    public List<User> findAll() 
        return userMapper.findAll();
    

    public Boolean login(String username, String pwd) 
        String login = userMapper.login(username);
        if(login.equals(pwd))
            return true;
        
        return false;
    

    public List<User> select(QueryBean queryBean) 

        return userMapper.select(queryBean);
    

    //分页插件的使用
    public PageInfo<User> select2(QueryBean queryBean) 
        PageHelper.startPage(queryBean.getCurrentPage(),queryBean.getPageSize());
        List<User> list = userMapper.select(queryBean);
        PageInfo<User> pageInfo = new PageInfo<>(list);
        return pageInfo;
    

    /*将属性封装到类中,减少业务端代码
    public PageUtils select3(QueryBean queryBean) 
        Integer total = userMapper.selectCount(queryBean);
        PageUtils pageUtils = new PageUtils();
        //从前台取出的数据赋值
        pageUtils.setPageNum(queryBean.getCurrentPage());
        pageUtils.setPageSize(queryBean.getPageSize());
        //从数据库中查询出的数据赋值
        pageUtils.setList(userMapper.selectAll(queryBean));
        pageUtils.setTotal(total);
        //经过计算得到的数据赋值
        int pages = Double.valueOf(Math.ceil(pageUtils.getTotal()*1.0/pageUtils.getPageSize())).intValue();
        pageUtils.setPages(pages);
        Integer nextPage;
        if(queryBean.getCurrentPage()==pageUtils.getPages())
            nextPage=1;
        else
            nextPage=queryBean.getCurrentPage()+1;
        
        pageUtils.setNextPage(nextPage);
        Integer prePage;
        if(queryBean.getCurrentPage()==1)
            prePage=pageUtils.getPages();
        else
            prePage=queryBean.getCurrentPage()-1;
        
        pageUtils.setPrePage(prePage);

        return pageUtils;
    */
    public PageUtils select3(QueryBean queryBean) 
        Integer total = userMapper.selectCount(queryBean);
        if(total==0)
            //可以减少一次查询,提高效率
            return new PageUtils(queryBean.getCurrentPage(),queryBean.getPageSize(),null,total);
        
        List<User> list = userMapper.selectAll(queryBean);
        return new PageUtils(queryBean.getCurrentPage(),queryBean.getPageSize(),list,total);
    

UserServiceImpl

6、这时可先测试一下代码,使用测试类App测试增删改查

技术图片
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext.xml")
public class App 
    @Autowired
    private IUserService userService;

    @Test
    public void testSave()
        User user = new User(null,"林丹","qwer",new Date());
        userService.save(user);
    
    @Test
    public void testUpdate()
        User user =new User(10,"小芳","qwer",new Date());
        userService.update(user);
    
    @Test
    public void testDelete()
        userService.delete(5);
    
    @Test
    public void testFindOneById()
        System.out.println(userService.findById(3));
    
    @Test
    public void testFindAll()
        System.out.println(userService.findAll());
    

App

 第三步:添加事务控制

1、添加依赖 aspectj

2、配置事务管理器,本质上是一个<bean id="txManager" class=""/>

3、配置事务(两种方式)

   1.xml方式

    <aop:config>
        <aop:pointcut id="pointcut" expression="execution( * com.test.ssm.service..*.*(..))"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="pointcut"/>
    </aop:config>
    <tx:advice id="txAdvice" transaction-manager="txManager">
        <tx:attributes>
            <tx:method name="find*" read-only="true"/>
            <tx:method name="*"/>
        </tx:attributes>
    </tx:advice>

  2.使用注解的方式

  配置事务管理器,需要配置事务管理器注解驱动@Transactional即可

<!--事务管理器注解驱动-->
    <tx:annotation-driven transaction-manager="txManager"/>

第四步:配置前端页面

1、导入依赖servlet-api

2、在web.xml中配置前端控制器(本质上是一个servlet)

  客户端访问时会先通过前端控制器,再通过拦截器

<!--配置前端控制器-->
  <servlet>
    <servlet-name>dispatcherServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <!--配置有请求访问时加载的文件-->
    <init-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>classpath:springMVC.xml</param-value>
    </init-param>
    <!--配置自动启动前端控制器-->
    <load-on-startup>2</load-on-startup>
  </servlet>
  <servlet-mapping>
    <servlet-name>dispatcherServlet</servlet-name>
    <url-pattern>*.do</url-pattern>
  </servlet-mapping>

  注意:配置中的文件关联有没有将配置信息引入,可以在springMVC中使用import标签进行引入

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:mvc="http://www.springframework.org/schema/mvc"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

    <!--引入后台的Spring配置文件-->
    <import resource="classpath:applicationContext.xml"/>

</beans>

3、在web.xml中配置编码过滤器,解决中文乱码问题

<!--请求编码过滤器-->
  <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>
    <!--设置请求和响应是否强制编码-->
    <init-param>
      <param-name>forceEncoding</param-name>
      <param-value>true</param-value>
    </init-param>
  </filter>
  <filter-mapping>
    <filter-name>characterEncodingFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

4、在springMVC中配置拦截器,拦截想要跳过登录界面访问受保护资源的请求

<!--拦截器-->
   <mvc:interceptors>
       <!--登录检查拦截器-->
       <!--路径/**表示拦截所有路径,/*只能拦截所有一级路径-->
       <mvc:interceptor>
           <mvc:mapping path="/**"/>
           <!--对某个请求放行-->
           <mvc:exclude-mapping path="/login.do"/>
           <!--配置拦截器的全限定名-->
           <bean class="com.test.ssm.interceptor.MyInterceptor"></bean>
       </mvc:interceptor>
   </mvc:interceptors>

  拦截器

技术图片
public class MyInterceptor implements HandlerInterceptor 

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception 
        HttpSession session = request.getSession();
        if(session.getAttribute("USER_IN_SESSION")==null)
            response.sendRedirect("/index.html");
            return false;
        
        return true;
    
MyInterceptor

 第五步:编写Controller和访问页面

  在web.xml中添加如下代码,可以默认访问此页面

<welcome-file-list>
    <welcome-file>index.html</welcome-file>
  </welcome-file-list>

   Controller代码示例

技术图片
@Controller
public class UserController 

    @Autowired
    private IUserService userService;
    
    @RequestMapping("/findAll")
    public String findAll(Model model)
        List<User> list = userService.findAll();
        model.addAttribute("list",list);
        return "list";
    
    @RequestMapping("/login")
    public String login(String username, String pwd, HttpSession session)
        Boolean login = userService.login(username, pwd);
        if(login)
            session.setAttribute("USER_IN_SESSION",username);
            return "redirect:/findAll.do";
        
        return "redirect:/index.html";
    
    @RequestMapping("/edit")
    public String edit(Integer id,Model model)
        if(id!=null)
            model.addAttribute("user",userService.findById(id));
        
        return "edit";
    
    //将添加和保存写在同一个页面内
    @RequestMapping("/saveOrUpdate")
    public String saveOrUpdate(User user)
        if(user.getId()!=null)
            userService.update(user);
        else
            userService.save(user);
        
        return "redirect:/findAll.do";
    
    @RequestMapping("/delete")
    public String delete(Integer id)
        if(id!=null)
            userService.delete(id);
        
        return "redirect:/findAll.do";
    
    
    //条件查询
    @RequestMapping("/select")
    public String select(@ModelAttribute("queryBean") QueryBean queryBean, Model model)
        List<User> list = userService.select(queryBean);
        model.addAttribute("list",list);
        return "list";
    

    //使用分页插件进行条件查询
    @RequestMapping("/select2")
    public String select2(@ModelAttribute("queryBean") QueryBean queryBean, Model model)
        PageInfo<User> pageInfo = userService.select2(queryBean);
        model.addAttribute("page",pageInfo);
        return "list";
    

    //使用自己定义的分页功能进行条件查询
    @RequestMapping("/select3")
    public String select3(@ModelAttribute("queryBean") QueryBean queryBean, Model model)
        PageUtils pageUtils = userService.select3(queryBean);
        model.addAttribute("page",pageUtils);
        return "list";
    
UserController

   页面代码

技术图片
<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
<h2>Hello World!</h2>
<form action="/login.do" method="post">
    用户名:<input type="text" name="username"/>
    密码:<input type="text" name="pwd"/>
    <input type="submit"/>
</form>
</body>
</html>
index.html

  下面两个页面在WEB-INF下的views里,是受保护页面

技术图片
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Title</title>
</head>
<body>
<div style="text-align: center;">
    <h2>用户编辑</h2>
    <form action="/saveOrUpdate.do" method="post">
        <input type="hidden" name="id" value="$user.id"/>
        用户名:<input type="text" name="username" value="$user.username"/>
  <br/>密码:<input type="text" name="pwd" value="$user.pwd"/><br/>
        日期:<input type="date" name="date" value="$user.date"/><br/>
        <input type="submit" value="保存"/>
    </form>
</div>
</body>
</html>
edit.jsp
技术图片
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<html>
<head>
    <title>Title</title>
    <script type="text/javascript">
        function goPage(page) 
            //设置当前页的值
            document.getElementById("currentPage").value = page;
            //提交表单
            var form = document.getElementById("f1");
            form.submit();   //提交表单
        
    </script>
</head>
<body>
<div style="text-align: center;">
<h1>用户列表</h1>

    <%--使用了对象进行参数接受的时候,在参数封装的同时会将对象加入到作用域中 --%>
    <form id="f1" action="/select3.do" method="post">

        用户姓名:<input type="text" name="username" value="$queryBean.username"/>
        注册日期:<input type="text" name="date" value="$queryBean.date"/>
        <input type="submit" value="查询"/>
        <input type="button" onclick="location.href=‘/edit.do‘" value="增加" style="width: 40px;text-align: center"/>
    <table border="1px" width="60%" style="text-align: center;margin: 0 auto;">
        <tr>
            <th>编号</th>
            <th>姓名</th>
            <th>密码</th>
            <th>注册日期</th>
            <th>操作</th>
        </tr>
        <c:forEach items="$page.list" var="user" varStatus="index">
            <tr>
                <td>$index.count</td>
                <td>$user.username</td>
                <td>$user.pwd</td>
                <td>$user.date</td>
                <td><a href="/edit.do?id=$user.id">修改</a>|<a href="/delete.do?id=$user.id">删除</a></td>
            </tr>
        </c:forEach>

        <tr>
            <td colspan="5">
                <a href="javascript:void(0);" onclick="goPage(1)">首页</a>
                <a href="javascript:void(0);" onclick="goPage($page.prePage)">上一页</a>
                <a href="javascript:void(0);" onclick="goPage($page.nextPage)">下一页</a>
                <a href="javascript:void(0);" onclick="goPage($page.pages)">尾页</a>
                <input type="text" name="currentPage" id="currentPage"/>
                <input type="submit" value="跳转"/>
                每页显示:
                <select name="pageSize" onchange="goPage(1)">
                    <option value="3" $queryBean.pageSize==3?‘selected‘:‘‘>3</option>
                    <option value="4" $queryBean.pageSize==4?‘selected‘:‘‘>4</option>
                    <option value="5" $queryBean.pageSize==5?‘selected‘:‘‘>5</option>
                </select>
                当前$page.pageNum页/共$page.pages页/共$page.total条记录
            </td>
        </tr>
    </table>
    </form>
</div>
</body>
</html>
list.jsp

多条件查询

待明天补充,休息拉

分页

 

以上是关于SSM整合的主要内容,如果未能解决你的问题,请参考以下文章

SSM整合

SSM整合

SSM整合

SSM整合

SSM整合:Spring整合Mybatis

14-SSM整合