码迷,mamicode.com
首页 > 其他好文 > 详细

SSM整合

时间:2019-09-14 22:20:02      阅读:113      评论:0      收藏:0      [点我收藏+]

标签:本质   password   mat   ssi   next   namespace   submit   integer   enc   

第一步:准备依赖

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整合

标签:本质   password   mat   ssi   next   namespace   submit   integer   enc   

原文地址:https://www.cnblogs.com/xfdhh/p/11520360.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!