快速搭建SSM+redis

目录

1、创建maven项目

2、导入所有相关pom依赖

3、开始整合

项目结构:

①Mybaties+SSM逆向工程

a、导入pom依赖

b、创建配置文件

c、一键生成代码配置

②spring

a、创建配置文件

c、我们配置的为注解开发的相关配置。

③redis

a、创建配置文件

b、创建工具类

c.开启缓存

d、详细缓存使用

④SpringMVC

a、创建配置文件

b、配置web.xml

c、配置Tomcat+部署

4、测试

准备:

component包:

model包:

mapper包:

service包:

impl包:

controller包:

util

运行:

注解总结:

5、结尾:


1、创建maven项目

jdk1.8 tomcat8.0

2、导入所有相关pom依赖

替换版本请考虑冲突问题

该pom是一次将该环境搭建所需的所有依赖导入!!!




  4.0.0

  org.zwf
  SSM_YL
  1.0-SNAPSHOT
  war

  SSM_YL Maven Webapp
  
  http://www.example.com

  
    UTF-8
    1.8
    1.8
    3.7.0

    
    
    5.0.2.RELEASE
    
    3.4.5
    
    2.9.0
    1.7.1.RELEASE
    
    2.9.3
    
    5.1.44
    
    5.1.2
    
    1.3.1
    
    2.1.1
    2.4.3
    
    2.9.1
    3.2.0
    1.7.13
    
    4.12
    4.0.0
    1.18.2
  


  
    
    
      org.springframework
      spring-context
      ${spring.version}
    
    
      org.springframework
      spring-orm
      ${spring.version}
    
    
      org.springframework
      spring-tx
      ${spring.version}
    
    
      org.springframework
      spring-aspects
      ${spring.version}
    
    
      org.springframework
      spring-web
      ${spring.version}
    
    
      org.springframework
      spring-test
      ${spring.version}
    
    
      org.springframework
      spring-webmvc
      ${spring.version}
    

    
    
      org.mybatis
      mybatis
      ${mybatis.version}
    

    
    
      mysql
      mysql-connector-java
      ${mysql.version}
    

    
    
      com.github.pagehelper
      pagehelper
      ${pagehelper.version}
    

    
    
      org.mybatis
      mybatis-spring
      ${mybatis.spring.version}
    

    
    
      org.apache.commons
      commons-dbcp2
      ${commons.dbcp2.version}
    
    
      org.apache.commons
      commons-pool2
      ${commons.pool2.version}
    

    
    
    
    
    
    
      org.slf4j
      slf4j-api
      ${slf4j.version}
    
    
      org.slf4j
      jcl-over-slf4j
      ${slf4j.version}
      runtime
    

    
    
      org.apache.logging.log4j
      log4j-api
      ${log4j2.version}
    
    
      org.apache.logging.log4j
      log4j-core
      ${log4j2.version}
    
    
    
      org.apache.logging.log4j
      log4j-slf4j-impl
      ${log4j2.version}
    

    
    
      redis.clients
      jedis
      ${redis.version}
    
    
      org.springframework.data
      spring-data-redis
      ${redis.spring.version}
    

    
    
      com.fasterxml.jackson.core
      jackson-databind
      ${jackson.version}
    
    
      com.fasterxml.jackson.core
      jackson-core
      ${jackson.version}
    
    
      com.fasterxml.jackson.core
      jackson-annotations
      ${jackson.version}
    

    
    
      org.apache.logging.log4j
      log4j-web
      ${log4j2.version}
    

    
    
    
    
      jstl
      jstl
      1.2
      
    
      taglibs
      standard
      1.1.2
    


    
    
      junit
      junit
      ${junit.version}
      test
    
    
      javax.servlet
      javax.servlet-api
      ${servlet.version}
      provided
    
    
      org.projectlombok
      lombok
      ${lombok.version}
      provided
    
  


  
    SSM_YL
    
      
      
        src/main/java
        
          **/*.xml
        
      
      
      
        src/main/resources
        
          *.properties
          *.xml
        
      
    

    
      
        org.mybatis.generator
        mybatis-generator-maven-plugin
        1.3.2
        
          
          
            mysql
            mysql-connector-java
            5.1.44
          
        
        
          true
        
      
    

    
      
      
    
  

3、开始整合

项目结构:

快速搭建SSM+redis_第1张图片

①Mybaties+SSM逆向工程

SSM逆向工程:dao层一键生成

a、导入pom依赖

在第二步已经将所有pom导入了!!所有后面都会省略该步骤!

b、创建配置文件

jdbc.properties

连接数据库相关参数

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/study(对应的库)?useUnicode=true&characterEncoding=UTF-8
jdbc.username=root (数据库账号名)
jdbc.password=root123(数据库账号密码)

mybatis.cfg

mybatis核心配置文件




    
    

    
        
    

    
    
        
    

    
        
        
        
    

    
    
        
            
            

            
            
            
            
            
                
                
                
                
            
        
    

    

    

注意:分页插件要配置在environment标签前面,否则会报错

generatorConfig.xml

逆向生成代码核心配置文件!

注意事项:

①需要修改jdbc驱动jar包位置

②修改model以及Mapper生成位置

③配置指定的表(生成相关到层,一张表对应一个实体类)




    
    

    
    

    
    
        
        
            
             
        

        
        

        
        
            
            
        

        
        
        
        
            
            
            
            
            
            
            
            
        

        
        
            
            
        

        
        
        
        
        
            
            
        

        
        
        
        
        
        
        
        
        
        
        
        
        

        

c、一键生成代码配置

注意:配置好之后运行成功后请将配置选项切走,以免粗心导致运行二次造成其他bug...

命令行:mybatis-generator:generate -e

快速搭建SSM+redis_第2张图片

然后在pom文件中右键运行即可  

 快速搭建SSM+redis_第3张图片

②spring

a、创建配置文件

Spring-Mybatis.xml

spring整合mybatis文件

注意事项:

①注册jdbc.properties文件的那行代码被注释了,导致下面需要调用该文件相关参数的代码报红,可忽略。

在整合redis时会提到为什么!

②修改spring注入bean的扫描范围com.zwf

③将所有指定了报名的代码改为自己的包名com.zwf



    
    
    
    
    



    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    
    
    
        
        
        
        
        
        
        
        
            
                
                    
                        
                            helperDialect=mysql
                        
                    
                
            
        

        
        
            
                
                true
                
                false
                
                true
            
        

    

    
    
    
        
        
        
        
    

    
        
    
    
    

spring.xml

spring核心配置文件(总文件)

注意:

多数据源导入配置,因为spring只能识别一个context:property-placeholder标签,在配置redis时也会产生一个,可能会导致识别覆盖之类的问题,因此在spring的总配置文件中进行配置,用逗号隔开!也就是spring-Mybatis.xml和spring-redis.xml文件中该标签被注释的原因!




    
    

    
    

    
    

c、我们配置的为注解开发的相关配置。

spring提供注解,可便利开发,提高开发效率,相比SSH项目,我们的dao层,service(biz)层,controller(web)层,不需要再创建相关的spring配置文件来配置相关的Bean再交给spring管理了,写注解就好!

下面是SSH项目配置的案例:每写完一个模块都要配置一个相关文件!繁琐,且易出错!




	
	
		
	
	
		
	

这里spring可以通过注解对各层进行bean注册然后再加以管理!

分别有哪些注解,在最后测试会写出!

③redis

a、创建配置文件

redis.properties

redis也是数据库(非关系数据库),需要相关连接参数

redis.hostName=192.168.102.128 #redis服务器ip
redis.port=6379 #端口号
redis.password=123456 #连接redis密码,在redis.config中设置
redis.timeout=10000
redis.maxIdle=300
redis.maxTotal=1000
redis.maxWaitMillis=1000
redis.minEvictableIdleTimeMillis=300000
redis.numTestsPerEvictionRun=1024
redis.timeBetweenEvictionRunsMillis=30000
redis.testOnBorrow=true
redis.testWhileIdle=true

spring-redis.xml




    


    
    
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
        
        
        
        
        
        
    

    
    
        
        
        
            
        
        
            
        
        
            
        
        
            
        
        
        
    

    
    
        
    

b、创建工具类

RedisCache.java

package com.zwf.util;


import org.apache.ibatis.cache.Cache;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;


public class RedisCache implements Cache //实现类
{
    private static final Logger logger = LoggerFactory.getLogger(RedisCache.class);

    private static RedisTemplate redisTemplate;

    private final String id;

    /**
     * The {@code ReadWriteLock}.
     */
    private final ReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    @Override
    public ReadWriteLock getReadWriteLock()
    {
        return this.readWriteLock;
    }

    public static void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisCache.redisTemplate = redisTemplate;
    }

    public RedisCache(final String id) {
        if (id == null) {
            throw new IllegalArgumentException("Cache instances require an ID");
        }
        logger.debug("MybatisRedisCache:id=" + id);
        this.id = id;
    }

    @Override
    public String getId() {
        return this.id;
    }

    @Override
    public void putObject(Object key, Object value) {
        try{
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>putObject: key="+key+",value="+value);
            if(null!=value) {
                redisTemplate.opsForValue().set(key.toString(), value, 60, TimeUnit.SECONDS);
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("redis保存数据异常!");
        }
    }

    @Override
    public Object getObject(Object key) {
        try{
            logger.info(">>>>>>>>>>>>>>>>>>>>>>>>getObject: key="+key);
            if(null!=key) {
                return redisTemplate.opsForValue().get(key.toString());
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("redis获取数据异常!");
        }
        return null;
    }

    @Override
    public Object removeObject(Object key) {
        try{
            if(null!=key) {
                return redisTemplate.expire(key.toString(), 1, TimeUnit.DAYS);
            }
        }catch (Exception e){
            e.printStackTrace();
            logger.error("redis获取数据异常!");
        }
        return null;
    }

    @Override
    public void clear() {
        Long size=redisTemplate.execute(new RedisCallback() {
            @Override
            public Long doInRedis(RedisConnection redisConnection) throws DataAccessException {
                Long size = redisConnection.dbSize();
                //连接清除数据
                redisConnection.flushDb();
                redisConnection.flushAll();
                return size;
            }
        });
        logger.info(">>>>>>>>>>>>>>>>>>>>>>>>clear: 清除了" + size + "个对象");
    }

    @Override
    public int getSize() {
        Long size = redisTemplate.execute(new RedisCallback() {
            @Override
            public Long doInRedis(RedisConnection connection)
                    throws DataAccessException {
                return connection.dbSize();
            }
        });
        return size.intValue();
    }
}

RedisCacheTransfer.java

package com.zwf.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;

public class RedisCacheTransfer {
    @Autowired
    public void setRedisTemplate(RedisTemplate redisTemplate) {
        RedisCache.setRedisTemplate(redisTemplate);
    }
}

顺便创建分页需要的PageBean工具类

PageBean.java(分页)

package com.zwf.util;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;

/**
 * 分页工具类
 *
 */
public class PageBean {

   private int page = 1;// 页码

   private int rows = 10;// 页大小

   private int total = 0;// 总记录数

   private boolean pagination = true;// 是否分页
   
   private String URL;//上一次请求的URL
   
   private Map m=new HashMap();//存放上一次请求携带的参数
   

   public String getURL() {
      return URL;
   }

   public void setURL(String uRL) {
      URL = uRL;
   }

   public Map getM() {
      return m;
   }

   public void setM(Map m) {
      this.m = m;
   }

   public PageBean() {
      super();
   }

   public int getPage() {
      return page;
   }

   public void setPage(int page) {
      this.page = page;
   }
   
   public int getRows() {
      return rows;
   }

   public void setRows(int rows) {
      this.rows = rows;
   }

   public int getTotal() {
      return total;
   }

   public void setTotal(int total) {
      this.total = total;
   }
   
   public boolean isPagination() {
      return pagination;
   }
   
   public void setPagination(boolean pagination) {
      this.pagination = pagination;
   }
   
   public void setPage(String page) {
      if(page!=null)this.page = Integer.parseInt(page);
   }
   
   public void setRows(String rows) {
      if(rows!=null)
      this.rows = Integer.parseInt(rows);
   }

   public void setTotal(String total) {
      if(total!=null)
      this.total = Integer.parseInt(total);
   }
   
   public void setPagination(String pagination) {
      if(pagination != null)
      this.pagination = Boolean.getBoolean(pagination);
   }
   
   /**
    * pageBean的初始化
    * @param req
    */
   public void init(HttpServletRequest req) {
      //初始化jsp界面传递过来的当前页
      this.setPage(req.getParameter("page"));
      //初始化jsp界面传递过来的页大小
      this.setRows(req.getParameter("rows"));
      //初始化jsp界面传递过来的是否分页参数
      this.setPagination(req.getParameter("pagination"));
      //初始化上一次请求路径
      this.setURL(req.getRequestURL().toString());
      //初始化上一次请求参数
      this.setM(req.getParameterMap());
   }

   /**
    * 获得起始记录的下标
    * 
    * @return
    */
   public int getStartIndex() {
      return (this.page - 1) * this.rows;
   }
   
   /**
    * 返回最大页数
    * @return
    */
   public int getMaxPage() {
      return this.total % this.rows == 0 ? this.total / this.rows : this.total / this.rows+1;
   }
   
   /**
    * 获得上一页页码    最小页码为1
    * @return
    */
   public int backPage() {
      return this.page - 1 == 0 ? 1 : this.page-1;
   }
   
   /**
    * 获得下一页页码    最大页码为 this.page
    * @return
    */
   public int nextPage() {
      return this.page + 1 > this.getMaxPage() ? this.getMaxPage() : this.page+1;
   }

   @Override
   public String toString() {
      return "PageBean [page=" + page + ", rows=" + rows + ", total=" + total + ", pagination=" + pagination
            + ", URL=" + URL + ", m=" + m + "]";
   }
   
}

c.开启缓存

该标签添加到对应的Mapper.xml文件中(配置在Mapper标签中的最上一行),添加到BookMapper.xml,那么调用BookMapper.java的查询方法会缓存查出来的数据!

d、详细缓存使用

请看相关文章,之后再做补充!

④SpringMVC

a、创建配置文件

spring-mvc.xml

注意该修改的地方都修改了



    
    
    
    

    
    
    
        
    
    
    

    
    
        
        
        
        
    

    
    

    

b、配置web.xml


    Archetype Created Web Application
    
        contextConfigLocation
        classpath:spring.xml
    
    
    
        org.springframework.web.context.ContextLoaderListener
    

    
    
        SpringMVC
        org.springframework.web.servlet.DispatcherServlet
        
        
            contextConfigLocation
            classpath:spring-mvc.xml
        
        1
        
        true
    
    
        SpringMVC
        /
    

c、配置Tomcat+部署

注意:

一定要将你要运行的项目进行部署,否则运行成功之后(没问题的条件下)浏览器输入路径调用方法根本不会进入到后台调用controller层调用方法(别问我怎么知道的!)!!!

快速搭建SSM+redis_第4张图片

 快速搭建SSM+redis_第5张图片

如果没有就点+号添加,请选择后缀有exploded的选项!

到这了就都整合完成了,接下来进行测试!!!

4、测试

上面有提到过分页插件,在查询方法前后都需要进行处理来组成分页方法,因此写一个切面类,所有需要分页的方法不用再定义前后了。

准备:

component包:

PagerAspect.java

分页切面类,所有service包下的xxPager方法都将会被切面类进行增强,达到分页效果!

package com.zwf.component;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.zwf.util.PageBean;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @author zwf
 * @site www.zwf.com
 * @company
 * @create 
 */
@Component
@Aspect
public class PagerAspect {

    @Around("execution(* *..*Service.*Pager(..))")
    public Object invoke(ProceedingJoinPoint args) throws Throwable {
        Object[] params = args.getArgs();
        PageBean pageBean = null;
        for (Object param : params) {
            if(param instanceof PageBean){
                pageBean = (PageBean)param;
                break;
            }
        }

        if(pageBean != null && pageBean.isPagination()) {
            PageHelper.startPage(pageBean.getPage(), pageBean.getRows());
        }

        Object list = args.proceed(params);

        if(null != pageBean && pageBean.isPagination()){
            PageInfo pageInfo = new PageInfo((List) list);
            pageBean.setTotal(pageInfo.getTotal()+"");
        }
        return list;
    }
}

通过逆向工程已经生成Dao层相关代码。

快速搭建SSM+redis_第6张图片

model包:

Book.java

package com.zwf.model;

public class Book {
    private Integer bid;

    private String bname;

    private Float price;

    public Book(Integer bid, String bname, Float price) {
        this.bid = bid;
        this.bname = bname;
        this.price = price;
    }

    public Book() {
        super();
    }

    public Integer getBid() {
        return bid;
    }

    public void setBid(Integer bid) {
        this.bid = bid;
    }

    public String getBname() {
        return bname;
    }

    public void setBname(String bname) {
        this.bname = bname;
    }

    public Float getPrice() {
        return price;
    }

    public void setPrice(Float price) {
        this.price = price;
    }
}

mapper包:

BookMapper.java

package com.zwf.mapper;

import com.zwf.model.Book;
import org.springframework.stereotype.Component;

import java.util.List;

@Repository
public interface BookMapper {
    int deleteByPrimaryKey(Integer bid);

    int insert(Book record);

    int insertSelective(Book record);

    Book selectByPrimaryKey(Integer bid);

    int updateByPrimaryKeySelective(Book record);

    int updateByPrimaryKey(Book record);
	
    /**
     * 书籍模糊查询(带分页)
     * @param book 根据前端条件创建的书籍类,用来进行模糊查询
     * @return 符合条件的书籍集合
     */
    List listPager2(Book book);
}

BookMapper.xml




  
  
    
      
      
      
    
  
  
    bid, bname, price
  
  
  
    delete from t_mvc_book
    where bid = #{bid,jdbcType=INTEGER}
  
  
    insert into t_mvc_book (bid, bname, price
      )
    values (#{bid,jdbcType=INTEGER}, #{bname,jdbcType=VARCHAR}, #{price,jdbcType=REAL}
      )
  
  
    insert into t_mvc_book
    
      
        bid,
      
      
        bname,
      
      
        price,
      
    
    
      
        #{bid,jdbcType=INTEGER},
      
      
        #{bname,jdbcType=VARCHAR},
      
      
        #{price,jdbcType=REAL},
      
    
  
  
    update t_mvc_book
    
      
        bname = #{bname,jdbcType=VARCHAR},
      
      
        price = #{price,jdbcType=REAL},
      
    
    where bid = #{bid,jdbcType=INTEGER}
  
  
    update t_mvc_book
    set bname = #{bname,jdbcType=VARCHAR},
      price = #{price,jdbcType=REAL}
    where bid = #{bid,jdbcType=INTEGER}
  
    
    
  

在BookMapper.java 中可以看到@Repository注解,对BookMapper.java进行注册,交给spring管理。其他层也有相关注解。

service包:

impl包:

BookServiceImpl.java   (实现类在impl包下)

package com.zwf.service.impl;

import com.zwf.mapper.BookMapper;
import com.zwf.model.Book;
import com.zwf.service.BookService;
import com.zwf.util.PageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class BookServiceImpl implements BookService {
    @Autowired
    private BookMapper bookMapper;

    @Override
    public int deleteByPrimaryKey(Integer bid) {
        return bookMapper.deleteByPrimaryKey(bid);
    }

    @Override
    public int insert(Book record) {
        return 0;
    }

    @Override
    public int insertSelective(Book record) {
        return 0;
    }

    @Override
    public Book selectByPrimaryKey(Integer bid) {
        return null;
    }

    @Override
    public int updateByPrimaryKeySelective(Book record) {
        return 0;
    }

    @Override
    public int updateByPrimaryKey(Book record) {
        return 0;
    }

    @Override
    public List listPager(Book book, PageBean pageBean) {
        return bookMapper.listPager2(book);
    }
}

BookService.java (接口在service包下)

package com.zwf.service;

import com.zwf.model.Book;
import com.zwf.util.PageBean;

import java.util.List;

public interface BookService {
    int deleteByPrimaryKey(Integer bid);

    int insert(Book record);

    int insertSelective(Book record);

    Book selectByPrimaryKey(Integer bid);

    int updateByPrimaryKeySelective(Book record);

    int updateByPrimaryKey(Book record);

    List listPager(Book book, PageBean pageBean);
}

controller包:

BookController.java

package com.zwf.controller;

import com.zwf.model.Book;
import com.zwf.service.BookService;
import com.zwf.util.PageBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import java.util.List;

@Controller
@RequestMapping("book")
public class BookController {

    @Autowired
    private BookService bookService;

    @ResponseBody
    @RequestMapping("getBookList")
    public List getBookList(){
        List books = bookService.listPager(new Book(1, "%圣墟%", 2f), new PageBean());
        books.forEach(System.out::println);
        return books;
    }

}

util

在上面提到的PageBean和缓存所需要的工具类都在工具包下

运行:

运行成功如下图所示:

快速搭建SSM+redis_第7张图片

调用listPager2方法:

 

注解总结:

mapper(dao)层:@Repository

service(biz)层:@Service

controller(web)层:

@Autowired:注册对象(让service中的mapper接口有初始值),由spring来完成!

①@Controller

②springMVC相关:@RequestMapping("xxx") :在类上可区分某某模块,在方法上,表示方法调用。

例:调用book模块中的listPager2方法,如上图所示!

5、结尾:

该篇主要是快速搭建SSM+redis环境,具体一些注解,配置文件等的学习请看相关文章!

你可能感兴趣的:(Spring,redis,maven,spring)