慕课网跟着翔仔学
快速搭建SpringBoot+Mybatis+小程序应用
分为后端SpringBoot+Mybatis后端开发和小程序前端开发
本门课程将学会:
本门课程的框架:
技术储备要求:
开始进击:
第一步:新建工程——Srping Initializr JDK1.8以上即可
编辑项目名称:
选择springboot框架: web+mybatis
选择路径:
点击完成创建。
创建好的目录结构如下:
打开DemoApplication这个类。里面的@SpringBootApplication这个标签说明DemoApplication这个类是Springboot的启动类
该类里面的main函数调用了SpringApplication.run()函数来启动我们这个Springboot项目。该DemoApplication类为启动类。
application.properties文件:
他存储的是,我们的一些程序里面用到的一些配置,包括我们去连接数据库的时候需要,连的是哪一个数据库,数据库的IP还有数据库的用户名密码等信息就存储在这里。如果我们去连redis时,也把redis的IP、密码存在这里。该application.properties文件还能保存一些我们业务里面用到的全局变量。
springboot用这些扁平化的配置去取代SSM里面的一些XML配置文件。
但是该课程用到的mybatis框架还是保留了使用xml配置文件的方式。其他的一些xml文件信息我们都保存在这里,用这些配置代替以前的xml文件配置。
pom.xml文件:
就是我们的maven配置文件啦。
其中的spring-boot-starter-parent
是maven独有的。他的其中一个功能是一个引用管理的功能,就是dependencies里面的version信息可以不用填写,直接继承该spring-boot-starter-parent
里面的版本
可以看到:spring-boot-starter-web
和spring-boot-starter-test
是不用写版本信息的。
pom.xml文件的另一个重要的作用是能够识别application.properties还有application.yml类型的文件进行配置。
新建一个controller类进行测试:
在Hello类里面写以下代码:
package com.ymimooc.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController //@RestController标签是由两个标签组成,表明我们这个类是一个controller
// 一个是@Controller 表示该类是一个controller 能够用来接收前台发送过来的请求 去做相应的数据处理、请求的响应
//两外一个标签是@ResponseBody 将我们的数据、内容或对象作为http响应正文返回
public class Hello {
@RequestMapping(value = "/hello", method = RequestMethod.GET) // 定义路由 告诉前端怎么访问到该方法 GRT的形式:既url直接传参的方式去接受请求
public String hello() { //编写hello方法去做前台的响应
//返回Hello SpringBoot!
return "Hello SpringBoot!";
}
}
编写完成后,启动项目测试一下:
如果报错:Error starting ApplicationContext. To display the conditions report re-run your application with ‘debug’ enabled.
查看这个网页:https://blog.csdn.net/weixin_39220472/article/details/81429241 或者自行百度。
运行成功。打开网页localhost:8080/hello
至此springboot部署web工程整体框架没有错误,接着往下进击。
在application.properties文件中添加:server.port=8082
更改web服务访问端口号为8082
使用 localhost:8082/hello 访问。没有开启热部署的话 需要重启服务器,然后再打开localhost:8082/hello 。
在application.properties文件中再添加:
#加入/demo前缀 server.servlet.context-path=/demo
访问成功。
至此完成SpringBoot框架的搭建。
在完成框架搭建之后我们来明确一下我们需要开发功能点— — —就是实现区域信息的增删改查。
接下来连接数据库。我用的是SQLyog,用什么都一样。
①创建数据库 自行创建一个名为demo的数据库
②进入demo创建表 有五个字段组成
CREATE TABLE `tb_area`(
`area_id` INT(2) NOT NULL AUTO_INCREMENT,
`area_name` VARCHAR(200) NOT NULL,
`priority` INT(2) NOT NULL DEFAULT '0',
`create_time` DATETIME DEFAULT NULL,
`last_edit_time` DATETIME DEFAULT NULL,
PRIMARY KEY(`area_id`),
UNIQUE KEY `UK_AREA`(`area_name`)
)ENGINE=INNODB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;
③添加数据
数据库准备好以后回到IDEA创建基于该数据库的实体类:
添加以下代码:
package com.ymimooc.demo.entity;
import java.util.Date;
/**
* 区域信息实体类
*/
public class Area {
// 主键ID
private Integer areaId;
// 名称
private String areaName;
// 权重,越大越排前显示
private Integer priority;
// 创建时间
private Date createTime;
// 更新时间
private Date lastEditTime;
public Integer getAreaId() {
return areaId;
}
public void setAreaId(Integer areaId) {
this.areaId = areaId;
}
public String getAreaName() {
return areaName;
}
public void setAreaName(String areaName) {
this.areaName = areaName;
}
public Integer getPriority() {
return priority;
}
public void setPriority(Integer priority) {
this.priority = priority;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
public Date getLastEditTime() {
return lastEditTime;
}
public void setLastEditTime(Date lastEditTime) {
this.lastEditTime = lastEditTime;
}
}
完成实体类的创建。
在完成了相关表的设计和实体类的创建之后,咱们自底向上进行开发。
首先我们先实现Dao层的增删改查,分为四个部分进行。
接下来做第一步进行相关的配置。
①做maven pom的相关配置
在pom中添加mysql数据库的依赖和连接池c3p0依赖。
添加完pom.xml为:
4.0.0
com.ymimooc
demo
0.0.1-SNAPSHOT
demo
Demo project for Spring Boot
org.springframework.boot
spring-boot-starter-parent
2.1.7.RELEASE
1.8
org.mybatis.spring.boot
mybatis-spring-boot-starter
2.1.0
org.springframework.boot
spring-boot-starter-web
org.springframework.boot
spring-boot-starter-test
test
mysql
mysql-connector-java
com.mchange
c3p0
0.9.5.4
org.springframework.boot
spring-boot-maven-plugin
②完成了pom的相关配置之后,我们紧接着完成mybatis的相关配置
在resources包下创建mybatis-config.xml文件
在mybatis-config.xml文件添加以下代码:
接来下我们来对springboot的Dao层做相应的配置:
①建个config.dao包 即对dao的config做配置。
在该包下新建一个DataSourceConfiguration配置类, SSM框架也好springboot框架也好,都需要创建一个DataSource去连接我们的数据库,为我们的数据库连接提供服务。
springboot用xml配置文件越少越好。springboot主要是在代码里面做配置。spring最关键的是IOC和AOP,
在DataSourceConfiguration中添加以下代码:
package com.ymimooc.demo.config.dao;
import java.beans.PropertyVetoException;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.mchange.v2.c3p0.ComboPooledDataSource;
/**
* 配置datasource到ioc容器里面
*/
@Configuration
//标签表明告诉spring容器需要来到这个类下面检索相关的Bean,在spring初始化的时候就会检索这个类
// 配置mybatis mapper的扫描路径
@MapperScan("com.ymimooc.demo.dao")
public class DataSourceConfiguration {
@Value("${jdbc.driver}") // 读取application.properties里面的配置信息 使用下一行的jdbcDriver变量保存
private String jdbcDriver;
@Value("${jdbc.url}")
private String jdbcUrl;
@Value("${jdbc.username}")
private String jdbcUsername;
@Value("${jdbc.password}")
private String jdbcPassword;
/**
* 生成与spring-dao.xml对应的bean dataSource
*/
@Bean(name = "dataSource") //用dataSource作为这个Bean的名字
public ComboPooledDataSource createDataSource() throws PropertyVetoException { //创建一个bean返回的是数据库的连接池即c3p0连接池
// 生成datasource实例
ComboPooledDataSource dataSource = new ComboPooledDataSource();
// 跟配置文件一样设置以下信息
// 驱动
dataSource.setDriverClass(jdbcDriver);
// 数据库连接URL
dataSource.setJdbcUrl(jdbcUrl);
// 设置用户名
dataSource.setUser(jdbcUsername);
// 设置用户密码
dataSource.setPassword(jdbcPassword);
// 配置c3p0连接池的私有属性
// 连接池最大线程数
dataSource.setMaxPoolSize(30);
// 连接池最小线程数
dataSource.setMinPoolSize(10);
// 关闭连接后不自动commit
dataSource.setAutoCommitOnClose(false);
// 连接超时时间
dataSource.setCheckoutTimeout(10000);
// 连接失败重试次数
dataSource.setAcquireRetryAttempts(2);
return dataSource;
}
}
然后再applica.properties文件中配置jdbcDriver、jdbcUrl、jdbcUsername、jdbcPassword等信息
在applica.properties文件中再添加以下代码:
#DataSource
#数据库驱动
jdbc.driver=com.mysql.jdbc.Driver
#数据库链接
jdbc.url=jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&useSSL=false
#数据库用户名
jdbc.username=root
#数据库密码
jdbc.password=root
完成了Dao sourceConfiguration的编写。
有了datasource springboot还需要有一个SessionFactory供我们做事务的提交。咱们再创建另外一个类:SessionFactoryConfiguration
添加以下代码:
package com.ymimooc.demo.config.dao;
import java.io.IOException;
import javax.sql.DataSource;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
@Configuration
public class SessionFactoryConfiguration {
// mybatis-config.xml配置文件的路径
private static String mybatisConfigFile;
@Value("${mybatis_config_file}")
public void setMybatisConfigFile(String mybatisConfigFile) {
SessionFactoryConfiguration.mybatisConfigFile = mybatisConfigFile;
}
// mybatis mapper文件所在路径
private static String mapperPath;
@Value("${mapper_path}")
public void setMapperPath(String mapperPath) {
SessionFactoryConfiguration.mapperPath = mapperPath;
}
// 实体类所在的package
@Value("${type_alias_package}")
private String typeAliasPackage;
@Autowired
private DataSource dataSource;
/**
* 创建sqlSessionFactoryBean 实例 并且设置configtion 设置mapper 映射路径 设置datasource数据源
*/
@Bean(name = "sqlSessionFactory")
public SqlSessionFactoryBean createSqlSessionFactoryBean() throws IOException {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
// 设置mybatis configuration 扫描路径
sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(mybatisConfigFile));
// 添加mapper 扫描路径
PathMatchingResourcePatternResolver pathMatchingResourcePatternResolver = new PathMatchingResourcePatternResolver();
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + mapperPath;
sqlSessionFactoryBean.setMapperLocations(pathMatchingResourcePatternResolver.getResources(packageSearchPath));
// 设置dataSource
sqlSessionFactoryBean.setDataSource(dataSource);
// 设置typeAlias 包扫描路径
sqlSessionFactoryBean.setTypeAliasesPackage(typeAliasPackage);
return sqlSessionFactoryBean;
}
}
在application.properties文件中再添加以下代码:
#Mybatis
mybatis_config_file=mybatis-config.xml
mapper_path=/mapper/**.xml
type_alias_package=com.ymimooc.demo.entity
在完成了dao基础配置之后,创建dao
然后创建接口:AreaDao 定义增删改查
添加以下代码:
package com.ymimooc.demo.dao;
import java.util.List;
import com.ymimooc.demo.entity.Area;
public interface AreaDao {
/**
* 列出区域列表
*/
List queryArea();
/**
* 根据Id列出具体区域
*/
Area queryAreaById(int areaId);
/**
* 插入区域信息
*/
int insertArea(Area area);
/**
* 更新区域信息
*/
int updateArea(Area area);
/**
* 删除区域信息
*/
int deleteArea(int areaId);
}
创建完Dao 接着创建该AreaDao接口对应的mapper文件。
在resources包下创建mapper包,并创建AreaDao.xml文件,如下:
在AreaDao.xml文件中添加以下代码:
INSERT INTO
tb_area(area_name,priority,
create_time,last_edit_time)
VALUES
(#{areaName},#{priority},
#{createTime},#{lastEditTime})
update tb_area
area_name=#{areaName},
priority=#{priority},
last_edit_time=#{lastEditTime}
where area_id=#{areaId}
DELETE FROM
tb_area
WHERE
area_id =
#{areaId}
接下来进行Service层的实现
主要分为一下三个部分:
1.配置部分 我们需要配置跟service层相关的一些spring的配置
2.编写service层的接口
3.接着编写这些接口的实现类
service层主要是用来整合我们复杂的业务逻辑的,比如说我们的dao层,里面的每个dao都会对它对应的表进行增删改查,我们的service层就是将这些dao增删改查,这些操作整合到一块,
①在config包下面创建一个service包下创建TransactionManagementConfiguration类
添加以下代码:
package com.ymimooc.demo.config.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import org.springframework.transaction.annotation.TransactionManagementConfigurer;
import javax.sql.DataSource;
@Configuration
@EnableTransactionManagement //开启事务的管理
public class TransactionManagementConfiguration implements TransactionManagementConfigurer { //继承一个接口 实现这个接口的方法
@Autowired
private DataSource dataSource; // Transaction需要一个成员变量 有了dataSource才能基于事物的管理
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
这样就完成了service层的配置,其实就是直接创建一个DataSourceTransactionManager这样的一个bean,同时注入dataSource的成员变量。
②接下来我们就去实现service层相关的接口
创建包service、并创建接口AreaService
添加以下代码:
package com.ymimooc.demo.service;
import java.util.List;
import com.ymimooc.demo.entity.Area;
public interface AreaService {
/**
* 获取区域列表
*
* @return
*/
List getAreaList();
/**
* 通过区域Id获取区域信息
*
* @param areaId
* @return
*/
Area getAreaById(int areaId);
/**
* 增加区域信息
*
* @param area
* @return
*/
boolean addArea(Area area);
/**
* 修改区域信息
*
* @param area
* @return
*/
boolean modifyArea(Area area);
/**
* 删除区域信息
*
* @param areaId
* @return
*/
boolean deleteArea(int areaId);
}
package com.ymimooc.demo.service.impl;
import java.util.Date;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import com.ymimooc.demo.dao.AreaDao;
import com.ymimooc.demo.entity.Area;
import com.ymimooc.demo.service.AreaService;
@Service
public class AreaServiceImpl implements AreaService {
@Autowired
private AreaDao areaDao;
@Override
public List getAreaList() {
// 返回所有的区域信息
return areaDao.queryArea();
}
@Override
public Area getAreaById(int areaId) {
return areaDao.queryAreaById(areaId);
}
@Transactional //加上事务控制 当抛出RuntimeException异常 事务就会回滚
@Override
public boolean addArea(Area area) {
// 空值判断,主要是判断areaName不为空
if (area.getAreaName() != null && !"".equals(area.getAreaName())) {
// 设置默认值
area.setCreateTime(new Date()); //设置当前时间
area.setLastEditTime(new Date());
try {
int effectedNum = areaDao.insertArea(area);
if (effectedNum > 0) {
return true;
} else {
throw new RuntimeException("添加区域信息失败!");
}
} catch (Exception e) {
throw new RuntimeException("添加区域信息失败:" + e.toString());
}
} else {
throw new RuntimeException("区域信息不能为空!");
}
}
@Transactional
@Override
public boolean modifyArea(Area area) {
// 空值判断,主要是areaId不为空
if (area.getAreaId() != null && area.getAreaId() > 0) {
// 设置默认值
area.setLastEditTime(new Date());
try {
// 更新区域信息
int effectedNum = areaDao.updateArea(area);
if (effectedNum > 0) {
return true;
} else {
throw new RuntimeException("更新区域信息失败!");
}
} catch (Exception e) {
throw new RuntimeException("更新区域信息失败:" + e.toString());
}
} else {
throw new RuntimeException("区域信息不能为空!");
}
}
@Transactional
@Override
public boolean deleteArea(int areaId) {
if (areaId > 0) {
try {
// 删除区域信息
int effectedNum = areaDao.deleteArea(areaId);
if (effectedNum > 0) {
return true;
} else {
throw new RuntimeException("删除区域信息失败!");
}
} catch (Exception e) {
throw new RuntimeException("删除区域信息失败:" + e.toString());
}
} else {
throw new RuntimeException("区域Id不能为空!");
}
}
}
接下来进行Controller层的实现
分为两个部分进行:
1.实现业务Controller方法,业务Controller方法就包含了Area的增删改查四部分
2.再编一写一个统一的异常处理类来对这个项目可能抛出的异常做统一的处理
创建web包,创建AreaController类 web就是controller层
在里面编写方法:添加以下代码:
package com.ymimooc.demo.web;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.ymimooc.demo.entity.Area;
import com.ymimooc.demo.service.AreaService;
@RestController //Controller 和 ResponseBody的组合 返回的不是页面 而是实际的body的值
@RequestMapping("/superadmin") //指定根路由
public class AreaController {
@Autowired //调service
private AreaService areaService;
/**
* 获取所有的区域信息
*
* @return
*/
@RequestMapping(value = "/listarea", method = RequestMethod.GET)
private Map listArea() {
Map modelMap = new HashMap();
List list = new ArrayList();
// 获取区域列表
list = areaService.getAreaList();
modelMap.put("areaList", list);
return modelMap;
}
/**
* 通过区域Id获取区域信息
*
* @return
*/
@RequestMapping(value = "/getareabyid", method = RequestMethod.GET)
private Map getAreaById(Integer areaId) {
Map modelMap = new HashMap();
// 获取区域信息
Area area = areaService.getAreaById(areaId);
modelMap.put("area", area);
return modelMap;
}
/**
* 添加区域信息
*
* @return
* @throws IOException
* @throws JsonMappingException
* @throws JsonParseException
*/
@RequestMapping(value = "/addarea", method = RequestMethod.POST)
private Map addArea(@RequestBody Area area) //前端传入json对象
throws JsonParseException, JsonMappingException, IOException {
Map modelMap = new HashMap();
// 添加区域信息
modelMap.put("success", areaService.addArea(area));
return modelMap;
}
/**
* 修改区域信息,主要修改名字
*
* @throws IOException
* @throws JsonMappingException
* @throws JsonParseException
*/
@RequestMapping(value = "/modifyarea", method = RequestMethod.POST)
private Map modifyArea(@RequestBody Area area)
throws JsonParseException, JsonMappingException, IOException {
Map modelMap = new HashMap();
// 修改区域信息
modelMap.put("success", areaService.modifyArea(area));
return modelMap;
}
@RequestMapping(value = "/removearea", method = RequestMethod.GET)
private Map removeArea(Integer areaId) {
Map modelMap = new HashMap();
// 修改区域信息
modelMap.put("success", areaService.deleteArea(areaId));
return modelMap;
}
}
再创建handler包,创建GlobalExceptionHandler类
添加以下代码:
package com.ymimooc.demo.handler;
import java.util.HashMap;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
/**
* 统一异常处理类
*
* @author xiangze
*
*/
@ControllerAdvice //跟前端做交互
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class) //处理所有的异常
@ResponseBody //不是返回http页面 而是返回错误信息 所以直接用ResponseBody这个标签
//编写异常处理方法
public Map exceptionHandler(HttpServletRequest req, Exception e) throws Exception {
Map modelMap = new HashMap();
modelMap.put("success", false);
modelMap.put("errMsg", e.getMessage());
return modelMap;
}
}