SpringBoot + MyBatis 项目实现思路
一、数据库表设计
连接数据库
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/demo?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: root
password: 123456
jpa:
hibernate:
ddl-auto: update
show-sql: true
server:
port: 8844
servlet:
context-path: /demo
二、实体类创建
entity 文件夹
实体类:Area.java
成员变量
import java.util.Date;
public class Area {
// 主键
private Integer areaId;
// 名称
private String areaName;
// 权重,越大越排前显示
private Integer priority;
//创建时间
private Date createTime;
//更新时间
private Date lastEditTime;
}
三、Dao层的实现 - 配置
pom的配置
<!--mybatis-->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>2.1.0</version>
</dependency>
<!--mysql-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<scope>runtime</scope>
</dependency>
<!--连接池-->
<dependency>
<groupId>com.mchange</groupId>
<artifactId>c3p0</artifactId>
<version>0.9.5.2</version>
</dependency>
mybatis-config的配置
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--配置全局属性-->
<settings>
<!--使用jdbc的getGenerateKeys获取数据库自增主键值-->
<setting name="useGeneratedKeys" value="true"/>
<!--使用列标签替换列别名 默认true-->
<setting name="useColumnLabel" value="true"/>
<!--开启驼峰命名转换:Table{create_time} -> Entity{CreateTime} -->
<setting name="mapUnderscoreToCamelCase" value="true"/>
</settings>
</configuration>
datasource和sessionfactorybean的配置
···config包
········· dao包
··············· DataSourceConfiguration.java
SessionFactoryConfiguration.java
package com.imooc.demo.config.dao;
import com.mchange.v2.c3p0.ComboPooledDataSource;
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 javax.validation.Valid;
import java.beans.PropertyVetoException;
//告诉这个类在相关的bean检索相应的配置
@Configuration
//配置mybatis mapper 的扫描路径
@MapperScan("com.imooc.demo.dao")
public class DataSourceConfiguration {
// 引入全局配置 yml
@Value("${jdbc.driver}")
private String jdbcDriver;
@Value("${jdbc.url}")
private String jdbcUrl;
@Value("${jdbc.username}")
private String jdbcUsername;
@Value("${jdbc.password}")
private String jdbcPassword;
@Bean(name = "dataSource")
public ComboPooledDataSource createDataSource() throws PropertyVetoException {
ComboPooledDataSource dataSource = new ComboPooledDataSource();
dataSource.setDriverClass(jdbcDriver);
dataSource.setJdbcUrl(jdbcUrl);
dataSource.setUser(jdbcUsername);
dataSource.setPassword(jdbcPassword);
//关闭连接后不自动commit
dataSource.setAutoCommitOnClose(false);
return dataSource;
}
}
···config包
········· dao包
··············· SessionFactoryConfiguration.java //提交commit
application.yml 全局配置变量
#Mybatis
mybatis_config_file: mybatis-config.xml
mapper_path: /mapper/**.xml
entity_package: com.imooc.demo.entity
import org.mybatis.spring.SqlSessionFactoryBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
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 javax.sql.DataSource;
import java.io.IOException;
@Configuration
public class SessionFactoryConfiguration {
// mybatis-config.xml 配置文件的路径
@Value("${mybatis_config_file}")
private String mybatisConfigFilePath;
// mybatis mapper 文件所在路基
@Value("${mapper_path}")
private String mapperPath;
// 实体类所在的package
@Value("${entity_package}")
private String entityPackage;
@Autowired
@Qualifier("dataSource") //Qualifier 别名
private DataSource dataSource;
@Bean(name = "sqlSessionFactory")
public SqlSessionFactoryBean createSqlSessionFactoryBean() throws IOException {
SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
sqlSessionFactoryBean.setConfigLocation(new ClassPathResource(mybatisConfigFilePath));
PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
String packageSearchPath = PathMatchingResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +mapperPath;
sqlSessionFactoryBean.setMapperLocations(resolver.getResources(packageSearchPath));
sqlSessionFactoryBean.setDataSource(dataSource);
sqlSessionFactoryBean.setTypeAliasesPackage(entityPackage);
return sqlSessionFactoryBean;
}
}
四、Dao层的实现 - 接口
创建dao包
dao包里面创建的都是接口 interface
创建的都是增删改查方法
AreaDao.class
package com.imooc.demo.dao;
import com.imooc.demo.entity.Area;
import java.util.List;
public interface AreaDao {
/*
* 列出区域列表
*
* @return areaList
* */
List<Area> queryArea();
/*
* 根据Id列出具体区域
*
* @param areaId
* @return area
* */
Area queryAreaById(int areaId);
/*
* 插入区域信息
*
* @param area
* @return
* */
int insertArea(Area area);
/*
* 更新区域信息
*
* @param area
* @return
* */
int updateArea(Area area);
/*
* 删除区域信息
*
* @param areaId
* @return
* */
int deleteArea(int areaId);
}
五、Dao层的实现 - mapper实现
创建mapper文件夹
<?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.imooc.demo.dao.AreaDao">
<select id="queryArea" resultType="com.imooc.demo.entity.Area">
SELECT area_id,area_name,priority,create_time,last_edit_time
FROM tb_area
ORDER BY priority
DESC
</select>
<select id="queryAreaById" resultType="com.imooc.demo.entity.Area">
SELECT area_id,area_name,priority,create_time,last_edit_time
FROM tb_area
WHERE
area_id = #{areaId}
</select>
<insert id="insertArea" useGeneratedKeys="true" keyProperty="areaId" keyColumn="area_id" parameterType="com.imooc.demo.entity.Area">
INSERT INTO
tb_area(area_name,priority,create_time,last_edit_time)
VALUES
(#{areaName},#{priority},#{createTime},#{lastEditTime})
</insert>
<update id="updateArea" parameterType="com.imooc.demo.entity.Area">
UPDATE tb_area
<set>
<if test="areaName!=null">area_name=#{areaName},</if>
<if test="priority!=null">priority=#{priority},</if>
<if test="lastEditTime!=null">last_edit_time=#{lastEditTime}</if>
</set>
WHERE area_id = #{areaId}
</update>
<!--area 有自动化生成工具可以生成-->
<delete id="deleteArea" >
DELETE FROM
tb_area
WHERE
area_id = #{areaId}
</delete>
</mapper>
六、Dao层的实现 -ut 单元测试
进入AreaDao接口Interface 文件内
widow 快捷键 ALT+Entey
创建好了对应包目录下的test
package com.imooc.demo.dao;
import com.imooc.demo.entity.Area;
import org.junit.Ignore;
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 java.util.Date;
import java.util.List;
import static org.junit.Assert.*;
@RunWith(SpringRunner.class)
@SpringBootTest
public class AreaDaoTest {
@Autowired
private AreaDao areaDao;
@Test
@Ignore
public void queryArea() throws Exception {
List<Area> areaList = areaDao.queryArea();
assertEquals(2,areaList.size());
}
@Test
@Ignore
public void queryAreaById() throws Exception {
Area area = areaDao.queryAreaById(1);
assertEquals("东苑",area.getAreaName());
}
@Test
@Ignore
public void insertArea() throws Exception {
Area area = new Area();
area.setAreaName("南苑");
area.setPriority(1);
int effectedNum = areaDao.insertArea(area);
assertEquals(1,effectedNum);
}
@Test
@Ignore
public void updateArea() throws Exception {
Area area = new Area();
area.setAreaName("西苑");
area.setPriority(3);
area.setLastEditTime(new Date());
int effectedNum = areaDao.updateArea(area);
assertEquals(1,effectedNum);
}
@Test
public void deleteArea() throws Exception {
int effectedNum = areaDao.deleteArea(3);
assertEquals(1,effectedNum);
}
}
七、service层的实现 - 配置
servie层:检查复杂的业务逻辑
package com.imooc.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;
@Override
public PlatformTransactionManager annotationDrivenTransactionManager() {
return new DataSourceTransactionManager(dataSource);
}
}
八、service层的实现 -接口
AreaService .class方法与dao层方法不一定一样的,可能覆盖几个dao层,这个是一个测试dao,是一样的,巧合
package com.imooc.demo.service;
import com.imooc.demo.entity.Area;
import java.util.List;
public interface AreaService {
/*
* 列出区域列表
*
* @return areaList
* */
List<Area> queryArea();
/*
* 根据Id列出具体区域
*
* @param areaId
* @return area
* */
Area queryAreaById(int areaId);
/*
* 插入区域信息
*
* @param area
* @return
* */
int insertArea(Area area);
/*
* 更新区域信息
*
* @param area
* @return
* */
int updateArea(Area area);
/*
* 删除区域信息
*
* @param areaId
* @return
* */
int deleteArea(int areaId);
}
九、service层的实现 - 实现类
package com.imooc.demo.service.impl;
import com.imooc.demo.dao.AreaDao;
import com.imooc.demo.entity.Area;
import com.imooc.demo.service.AreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import java.util.Date;
import java.util.List;
@Service
public class AreaServiceImpl implements AreaService {
@Autowired
private AreaDao areaDao;
@Override
public List<Area> queryArea() {
return areaDao.queryArea();
}
@Override
public Area queryAreaById(int areaId) {
return areaDao.queryAreaById(areaId);
}
@Transactional
// @Transactional(rollbackFor = Exception.class)
@Override
public boolean addArea(Area area) {
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("区域信息不能为空!");
}
}
@Override
public boolean deleteArea(int areaId) {
//空值判断,主要是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层的实现 - 业务controller方法的实现
新建web包,web就表示是Controller层
AreaController.class
import com.imooc.demo.entity.Area;
import com.imooc.demo.service.AreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/superadmin")
public class AreaController {
@Autowired
private AreaService areaService;
@RequestMapping(value = "/listarea",method = RequestMethod.GET)
private Map<String,Object> listArea(){
Map<String,Object> modelMap = new HashMap<String,Object>();
List<Area> list = areaService.getAreaList();
modelMap.put("areaList",list);
return modelMap;
}
}
package com.imooc.demo.web;
import com.imooc.demo.entity.Area;
import com.imooc.demo.service.AreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/superadmin")
public class AreaController {
@Autowired
private AreaService areaService;
@RequestMapping(value = "/listarea",method = RequestMethod.GET)
private Map<String,Object> listArea(){
Map<String,Object> modelMap = new HashMap<String,Object>();
List<Area> list = areaService.getAreaList();
modelMap.put("areaList",list);
return modelMap;
}
}
增删改查 完整方法 代码如下:
import com.imooc.demo.entity.Area;
import com.imooc.demo.service.AreaService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@RestController
@RequestMapping("/superadmin")
public class AreaController {
@Autowired
private AreaService areaService;
@RequestMapping(value = "/listarea",method = RequestMethod.GET)
private Map<String,Object> listArea(){
Map<String,Object> modelMap = new HashMap<String,Object>();
List<Area> list = areaService.getAreaList();
modelMap.put("areaList",list);
return modelMap;
}
@RequestMapping(value = "/getareabyid",method = RequestMethod.GET)
private Map<String,Object> getAreaById(Integer areaId){
Map<String,Object> modelMap = new HashMap<String,Object>();
Area area = areaService.getAreaListById(areaId);
modelMap.put("area",area);
return modelMap;
}
@RequestMapping(value = "/addarea",method = RequestMethod.POST)
private Map<String,Object> addArea(@RequestBody Area area){
Map<String,Object> modelMap = new HashMap<String,Object>();
modelMap.put("success",areaService.addArea(area));
return modelMap;
}
@RequestMapping(value = "/modifyarea",method = RequestMethod.POST)
private Map<String,Object> modifyArea(@RequestBody Area area) {
Map<String, Object> modelMap = new HashMap<String, Object>();
//修改区域信息
modelMap.put("success",areaService.modifyArea(area));
return modelMap;
}
@RequestMapping(value = "/removearea",method = RequestMethod.GET)
private Map<String,Object> removeArea(@Validated Integer areaId) {
Map<String, Object> modelMap = new HashMap<String, Object>();
//删除区域信息
modelMap.put("success",areaService.deleteArea(areaId));
return modelMap;
}
}
十一、Controller层的实现 - 统一异常处理功能的实现
新建handler包,处理相关的类
package com.imooc.demo.handler;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.Map;
@ControllerAdvice
public class GlobalExceptionHandler {
@ExceptionHandler(value = Exception.class)
@ResponseBody
private Map<String,Object> exceptionHandler(HttpServletRequest req,Exception e){
Map<String,Object> modelMap = new HashMap<String,Object>();
modelMap.put("success",false);
modelMap.put("errMsg",e.getMessage());
return modelMap;
}
}