springboot+mybatis+redis+thymeleaf Web项目搭建 开箱即用

本文详细记录了手动搭建一个包含SpringBoot、Mybatis、Redis和Thymeleaf的Web项目的全过程。首先介绍了各技术框架的作用,接着分三部分阐述了SpringBoot基础设置、SpringBoot集成Mybatis实现数据访问、SpringBoot整合Redis进行缓存操作的步骤。项目源码已上传至GitHub和CSDN,可供读者参考学习。

手动搭建了一个springboot+mybatis+redis+thymeleaf的Web后台项目,因此写篇博客记录下搭建的完整过程。文章最后有完整代码地址

首先简单介绍下用到的技术框架及用途:

1.springboot框架  项目主体结构;

2.mybatis 持久层,本次与springboot结合采用的是传统的Xml形式,主要是为了sql语句的书写上更舒服些(个人观点);

3.redis 缓存数据库,为后期app开发做准备。

4.thymeleaf 前台模板引擎

第一部分:Springboot搭建

首先使用eclipse 下载sts插件  help-》Eclipse Marketplace-》选择Popular-》选择STS-》Installed,  

完成后 new -》Project   选择Spring Starter Project-》next

填写项目基本信息 Next

选择web组件 然后Finish 完成后 为项目创建下图样式的目录结构

完成后编辑pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<packaging>jar</packaging>
	<groupId>org.springframework</groupId>
	<artifactId>Springboot_lhm</artifactId>
	<version>0.1.0</version>

	<properties>
		<!-- 指定编码格式UTF-8 -->
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<!-- 指定java版本1.8 -->
		<java.version>1.8</java.version>
	</properties>
	
	<!--  Spring Boot 1.5 -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.4.RELEASE</version>
        <relativePath/>
    </parent>

    <dependencies>
    	
        <!-- 添加springboot web项目源生依赖 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <!-- 添加单元测试 -->
		<dependency>
        	<groupId>org.springframework.boot</groupId>
        	<artifactId>spring-boot-starter-test</artifactId>
        	<scope>test</scope>
    	</dependency> 
	</dependencies>
	
    <!-- 使用 maven 打jar包 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
	
	
	
</project>

Springboot的基本结构就搭建完了 我们在Application类中写个方法测试下

import org.springframework.boot.SpringApplication;  
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;  
import org.springframework.web.bind.annotation.RequestMapping;  
import org.springframework.web.bind.annotation.RestController;  
@RestController    
@EnableAutoConfiguration    
public class Application{  
  
    @RequestMapping("/test")    
    String home() {    
        return "Hello World!";    
    }   
    public static void main(String[] args) {  
        SpringApplication.run(Application.class, args);  
    }  
} 
启动项目,在Application类中run as -》java Aplication


打开游览器 输入 localhost:8080/test


这样第一部分的内容就完成了!!!


第二部分:Springboot+mybatis搭建

打开pom.xml,添加

<!-- mybatis -->
        <dependency>
		    <groupId>org.mybatis.spring.boot</groupId>
		    <artifactId>mybatis-spring-boot-starter</artifactId>
		    <version>1.1.1</version>
		</dependency>
		
        <!-- mysql -->
        <dependency>
        	<groupId>mysql</groupId>
        	<artifactId>mysql-connector-java</artifactId>
    	</dependency>
    	
    	<!--分页插件 -->
		<dependency>
			<groupId>com.github.pagehelper</groupId>
			<artifactId>pagehelper</artifactId>
			<version>4.1.6</version>
		</dependency>
然后开发配置文件 application.properties,设置mybatis的数据库链接

mybatis.type-aliases-package=com.lhm.entity
mybatis.mapper-locations: classpath:mapper/*.xml  

spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://127.0.0.1:3306/springboot_lhm?characterEncoding=utf8&useSSL=false&autoReconnect=true&failOverReadOnly=false&autoReconnectForPools=true
spring.datasource.username = root
spring.datasource.password = 123456789
完成后,因为我们会用到分页,因此我们一并配置,打开config文件夹 创建MybatisConf.java 类  

package com.lhm.config;

import java.util.Properties;  

import org.springframework.context.annotation.Bean;  
import org.springframework.context.annotation.Configuration;  
  
import com.github.pagehelper.PageHelper;  
  
/*  
 * 注册MyBatis分页插件PageHelper  
 */  
  
@Configuration  
public class MybatisConf {  
        @Bean  
        public PageHelper pageHelper() {  
            PageHelper pageHelper = new PageHelper();  
            Properties p = new Properties();  
            p.setProperty("offsetAsPageNum", "true");  
            p.setProperty("rowBoundsWithCount", "true");  
            p.setProperty("reasonable", "true");  
            pageHelper.setProperties(p);  
            return pageHelper;  
        }  
} 
完成后,我们需要写一个实例类用于定义我们自己的分页格式,在pojo文件夹下新建MyPage.java类

package com.lhm.pojo;

import java.util.List;

import com.github.pagehelper.Page;

public class MyPage<T> {
	
	public MyPage(){
		
	}

	public MyPage(Page<T> page) {
		int pageNum = page.getPageNum();
		int pageSize = page.getPageSize();
		long total = page.getTotal();
		int pages = page.getPages();
		this.pageNo = pageNum;
		this.pageSize = pageSize;
		this.total = total;
		this.totalPage = pages;
		this.list = page.getResult();
	}

	/**
	 * 
	 */
	private int pageNo;

	private int pageSize;

	private long total;

	private int totalPage;

	private List<T> list;

	public int getPageNo() {
		return pageNo;
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	public int getPageSize() {
		return pageSize;
	}

	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}

	public long getTotal() {
		return total;
	}

	public void setTotal(long total) {
		this.total = total;
	}

	public int getTotalPage() {
		return totalPage;
	}

	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}

	public List<T> getList() {
		return list;
	}

	public void setList(List<T> list) {
		this.list = list;
	}

}

这是Springboot+mybatis分页就算完成了,下面我们写一个类测试mybatis的正常使用。

在entity文件夹下新建User.java类

package com.lhm.entity;

import java.io.Serializable;

public class User implements Serializable{
	/** 
	* @Fields serialVersionUID : 实体类版本序列化号
	*/ 
	private static final long serialVersionUID = 1L;
	private int id;
	private String name;
	public int getId() {
		return id;
	}
	public void setId(int id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}

}

在controller文件夹下 创建类IndexController.java

package com.lhm.controller;

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.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageInfo;
import com.lhm.entity.User;

import com.lhm.service.UserService;





/** 
* @ClassName: IndexController 
* @Description: springboot web 登陆首页 
* @author liuheming 
* @date 2017年10月2日 上午10:42:04 
*  
*/
@Controller
public class IndexController {
@Autowired
private UserService userService; 	
	/** 
	* @Title: PageUserSelect 
	* @Description: 分页查询 
	* @param pageNum 页数
	* @param Size 单页条数
	* @return PageInfo<User>  
	* @throws 
	*/
	@RequestMapping("/PageUserSelect")
  	@ResponseBody
  	public PageInfo<User> PageUserSelect(
  				@RequestParam(value="pageNum",defaultValue="1")int pageNum,
			    @RequestParam(value="Size",defaultValue="5")int Size
		    ){
		Page<User> persons = userService.findByPage(pageNum, Size);
		PageInfo<User> pageInfo = new PageInfo<User>(persons);
				return pageInfo;
  	}
	
	 
}

在service文件夹下新建UserService.java

package com.lhm.service;

import com.github.pagehelper.Page;
import com.lhm.entity.User;

public interface UserService {
	public Page<User> findByPage(int pageNum, int size);
}

在impl文件夹下新建UserServiceImpl.java类并实现UserService

package com.lhm.service.impl;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.lhm.entity.User;
import com.lhm.mapper.UserMapper;
import com.lhm.service.UserService;
@Service
public class UserServiceImpl implements UserService{
	@Autowired
	private UserMapper userMapper;
	
	@Override
	public Page<User> findByPage(int pageNum, int size) {
		PageHelper.startPage(pageNum, size);
		return userMapper.findByPage();
	}

}

在mapper文件夹下新建UserMapper.java类

package com.lhm.mapper;

import org.apache.ibatis.annotations.Param;

import com.github.pagehelper.Page;
import com.lhm.entity.User;

public interface UserMapper {
	public Page<User> findByPage();
}

在resources/mapper下 新建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.lhm.mapper.UserMapper">   
	<resultMap id="User" type="com.lhm.entity.User" >  
        <result property="id" column="id" /> 
		<result property="name" column="name" />  
    </resultMap>      
    <select id="findByPage"  resultType="User">  
        select * from user 
    </select>  
</mapper>  

自此我们就可以启动项目了,注意一点我们需要在Application类中添加注解@MapperScan
package com;

import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ApplicationContext;

import org.springframework.data.redis.core.StringRedisTemplate;

@SpringBootApplication
@MapperScan("com.lhm.mapper")//对mapper包扫描
public class Application {
	
	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
		
		
		
	}	
 
}
启动完成后 输入 http://localhost:8080/PageUserSelect?pageNum=1&Size=5


这样我们就得到了JSon格式的分数据,自此第二部分也就完成了。

第三部分:Springboot+redis搭建

开始前我们需要搭建redis环境,这点不在此介绍了

打开Pom.xml  添加代码

<!-- redis -->	
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-redis</artifactId>
			<version>1.4.1.RELEASE</version>			
		</dependency>
完成后,打开配置文件application.properties 添加配置
# REDIS (RedisProperties)
# Redis数据库索引(默认为0)
spring.redis.database=0  
# Redis服务器地址
spring.redis.host=127.0.0.1
# Redis服务器连接端口
spring.redis.port=6379  
# Redis服务器连接密码(默认为空)
spring.redis.password=  
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.pool.max-active=8  
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.pool.max-wait=0  
# 连接池中的最大空闲连接
spring.redis.pool.max-idle=8  
# 连接池中的最小空闲连接
spring.redis.pool.min-idle=0  
# 连接超时时间(毫秒)
spring.redis.timeout=5000 
完成后打开redis文件夹,新建BaseRedisTemplate.java,这个类的作用创建redis操作模板 方面后期业务调用Redis数据

package com.lhm.redis;

import java.lang.reflect.ParameterizedType;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

import org.springframework.data.redis.connection.DefaultStringRedisConnection;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;
/** 
* @ClassName: RedisService 
* @Description: redis服务 
* @author liuheming 
* @date 2017年10月9日 下午5:29:29 
*  
*/
public abstract class BaseRedisTemplate<HV> extends RedisTemplate<String, HV> {

	private Class<HV> hvClass;

	private String dbname;

	@SuppressWarnings("unchecked")
	private Class<HV> getHVClass() {
		if (hvClass == null) {
			hvClass = (Class<HV>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
			dbname = hvClass.getName() + "_";
		}
		return hvClass;
	}

	/**
	 * Constructs a new <code>StringRedisTemplate</code> instance ready to be
	 * used.
	 * 
	 * @param connectionFactory
	 *            connection factory for creating new connections
	 */
	public BaseRedisTemplate(RedisConnectionFactory connectionFactory) {
		if (getHVClass() == null) {
			throw new IllegalArgumentException("获取泛型class失败");
		}
		RedisSerializer<String> stringSerializer = new StringRedisSerializer();
		setKeySerializer(stringSerializer);
		setValueSerializer(new Jackson2JsonRedisSerializer<HV>(getHVClass()));
		setHashKeySerializer(stringSerializer);
		setHashValueSerializer(new Jackson2JsonRedisSerializer<HV>(getHVClass()));
		setConnectionFactory(connectionFactory);
		afterPropertiesSet();
	}

	protected RedisConnection preProcessConnection(RedisConnection connection, boolean existingConnection) {
		return new DefaultStringRedisConnection(connection);
	}

	/**
	 * map存放操作
	 * 
	 * @param table
	 * @param key
	 * @param hv
	 */
	protected void putMap(String table, String key, HV hv) {
		this.opsForHash().put(getTable(table), key, hv);
	}

	/**
	 * map取操作
	 * 
	 * @param table
	 * @param key
	 * @return
	 */
	@SuppressWarnings("unchecked")
	protected HV getMap(String table, String key) {
		return (HV) this.opsForHash().get(getTable(table), key);
	}

	protected void set(String key, HV hv) {
		this.opsForValue().set(getTable(key), hv);
	}

	protected HV get(String key) {
		HV hv = this.opsForValue().get(getTable(key));
		return hv;
	}
	
	@SuppressWarnings("unchecked")
	protected Map<String,HV> entriesMap(String key){
		Map<Object, Object> entries = this.opsForHash().entries(getTable(key));
		Map<String,HV> entriesMap = new HashMap<String,HV>();
		Iterator<Object> iterator = entries.keySet().iterator();
		while(iterator.hasNext()){
			Object next = iterator.next();
			String mapKey = (String)next;
			HV hv = (HV)entries.get(next);
			entriesMap.put(mapKey, hv);
		}
		return entriesMap;
	}
	
	protected long removeMapKey(String table,Object... keys){
		return this.opsForHash().delete(getTable(table), keys);
	}
	
	protected long removeMapKeyByStringKey(String key1,String key2){
		return this.opsForHash().delete(key1, key2);
	}
	
	protected void putAllMap(String table,Map<String,HV> map){
		this.opsForHash().putAll(getTable(table), map);
	}

	protected long leftPush(String key, HV hv) {
		return this.opsForList().leftPush(getTable(key), hv);
	}

	protected long rightPush(String key, HV hv) {
		return this.opsForList().rightPush(getTable(key), hv);
	}

	protected HV leftPop(String key) {
		return this.opsForList().leftPop(getTable(key));
	}

	protected HV rightPop(String key) {
		return this.opsForList().rightPop(getTable(key));
	}

	/**
	 * 中心轴左侧插入
	 * 
	 * @param key
	 * @param pivot
	 *            中心轴的值, 左侧插入
	 * @param value
	 */
	protected long leftPush(String key, HV pivot, HV value) {
		return this.opsForList().leftPush(getTable(key), pivot, value);
	}

	/**
	 * 中心轴右侧插入
	 * 
	 * @param key
	 * @param pivot
	 *            中心轴的值, 左侧插入
	 * @param value
	 */
	protected long rightPush(String key, HV pivot, HV value) {
		return this.opsForList().rightPush(getTable(key), pivot, value);
	}

	/**
	 * 有序列表 在某个索引值下直接覆盖值
	 * 
	 * @param key
	 * @param index
	 * @param value
	 */
	protected void setList(String key, long index, HV value) {
		this.opsForList().set(getTable(key), index, value);
	}

	/**
	 * 获取列表中的地index个索引的值
	 * 
	 * @param key
	 * @param index
	 * @return
	 */
	protected HV indexList(String key, long index) {
		return this.opsForList().index(getTable(key), index);
	}

	/**
	 * 列表总长度
	 * 
	 * @param key
	 * @return
	 */
	protected long sizeList(String key) {
		return this.opsForList().size(getTable(key));
	}

	/**
	 * Removes the first count occurrences of elements equal to value from the
	 * list stored at key. The count argument influences the operation in the
	 * following ways: 
	 * count > 0: Remove elements equal to value moving from
	 * head to tail. 
	 * count < 0: Remove elements equal to value moving from tail
	 * to head. count = 0: 
	 * Remove all elements equal to value. For example, LREM
	 * list -2 "hello" will remove the last two occurrences of "hello" in the
	 * list stored at list. Note that non-existing keys are treated like empty
	 * lists, so when key does not exist, the command will always return 0.
	 * 
	 * @param key
	 * @param count
	 * @param hv
	 * @return
	 */
	protected long removeList(String key, long count, HV hv) {
		return this.opsForList().remove(getTable(key), count, hv);
	}
	
	protected long addSet(String key, HV[] values){
		return this.opsForSet().add(getTable(key), values);
	}
	
	protected Set<HV> membersSet(String key){
		Set<HV> members = this.opsForSet().members(getTable(key));
		return members;
	}
	
	protected long sizeSet(String key){
		return this.opsForSet().size(getTable(key));
	}
	
	protected boolean isMemberSet(String key,HV hv){
		return this.opsForSet().isMember(getTable(key), hv);
	}
	
	protected long removeSet(String key,HV[] values){
		return this.opsForSet().remove(getTable(key), values);
	}
	/**
	 * 取一个,少一个
	 * @param key
	 * @return
	 */
	protected HV popSet(String key){
		return this.opsForSet().pop(getTable(key));
	}

	protected Set<HV> distinctRandomMembersSet(String key,long distinctCount){
		return this.opsForSet().distinctRandomMembers(getTable(key), distinctCount);
	}

	private String getTable(String table) {
		return dbname + table;
	}

}
以上 我们就完成了Springboot+redis的搭建

下面我们写个方法测试,在common文件夹下RedisConstants.java类 用于设定公共变量

package com.lhm.common;


public class RedisConstants {
	/** 
	 * 用户表 User
	 **/
	public static final String User = "user";

}

在redis文件夹下新建user文件夹及子文件UserRedis.java类

package com.lhm.redis.user;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.stereotype.Service;

import com.lhm.common.RedisConstants;
import com.lhm.entity.User;
import com.lhm.redis.BaseRedisTemplate;


@Service
public class UserRedis extends BaseRedisTemplate<User> {

	@Autowired
	public UserRedis(RedisConnectionFactory connectionFactory) {
		super(connectionFactory);
	}
	
	
	/**
	 * @param table 表名
	 * @param key	用户id
	 * 
	 */
	public void addUser(String key, User User) {
		putMap(RedisConstants.User, key, User);
	}
	
	/**
	 * @param key	用户id
	 * @return 存在true 不存在false
	 */
	public boolean isExist(String key) {
		
		User sr = this.getUser(key);
		
		return sr==null?false:true;
	}
	
	/**
	 * @param table 表名
	 * @param key 用户id
	 * @return
	 */
	public User getUser(String key){
		return getMap(RedisConstants.User,key);
	}
	
	/**
	 * @param table 表名
	 */
	public void delUserTable(String table) {
		delete(table);
	}
}
完成后,我们通过单元测试的形式测试以上方法在test/java/com/lhm/redis/user路径下新建测试类UserRedisTest.java

package com.lhm.redis.user;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;

import org.springframework.test.context.junit4.SpringRunner;

import com.lhm.entity.User;
import com.lhm.mapper.UserMapper;
import com.lhm.redis.user.UserRedis;

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserRedisTest {
    @Autowired
    private UserRedis userRedis;
    @Autowired
	private UserMapper userMapper;

    @Test
	public void addUser() {
    	User u=new User();
	u.setId(1);
	u.setName("lhm");
    	userRedis.addUser("1",u);
	}
    @Test
	public void isExist() {		
    	boolean b=userRedis.isExist("1");
    	System.out.println(b);
	}
    @Test
	public void getUser() {
    	User user=userRedis.getUser("1");
    	System.out.println(user.getName());
	}
    @Test
    public void delUserTable() {
    	userRedis.delUserTable("user");
	}

}

启动项目  然后依次运行单元测试方法


自此Springboot+reids搭建就完成了。


项目完整代码已经上传git 有兴趣的同学可以结合代码+本文章 自己动手搭建系统  https://github.com/liuheming/springboot_mybatis_redis_thymeleaf.git  或http://download.csdn.net/download/becausesy/10017144

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值