springboot+mybatisplus示例开发
概述
用IDEA开发工具做一个springboot+mybatisplus的demo,以帮助学java的同学尽快的使用springboot+mybatisplus进行java开发。文档的从新建springboot项目开始,再到用mybatisplus进行数据表的增删改查及mybatisplus的代码生成。
新建Springboot项目
在IDEA上新建 Spring Initializr项目,Spring选项为以下选项(Developer Tools-Lombok , Web-Spring Web, Template Engines- Thymeleaf ,SQL- Mysql Driver),详情请见《Java代码Web示例.docx》文档。新建好的代码后,可以新建一个测试页面来测试以下效果,测试时用的页面模板框架为Thymeleaf,所以需要在application.properties配置文件中增加以下配置项。
----------------------------------------
#thymeleaf
spring.thymeleaf.encoding=UTF-8
#开发时关闭缓存,不然没法看到实时页面
spring.thymeleaf.cache=false
spring.thymeleaf.prefix=classpath:/templates
spring.thymeleaf.check-template-location=true
服务器的其它配置
#server
server.port=9001
server.error.path=/error
server.servlet.context-path=/xym
#热部署
spring.devtools.restart.enabled=true
#数据库相关配置 (引入了 mybatis的话就必须要写相关的配置)
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://182.168.10.45:3306/test?useUnicode=true&serverTimezone=Asia/Shanghai&characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=hzjg@123456
spring.datasource.max-idle=10
spring.datasource.max-wait=10000
spring.datasource.min-idle=5
spring.datasource.initial-size=5
----------------------------------------------------
然后新建一个控制器,及一个对应的模板页面,测试以下web项目是否配置成功。
控制器可以返回页面模板地址,也可以返回JSON数据;注意:模板中的文件文件名一定要小写。
控制器代码:controller/HomeController.java
-------------------------------------
/**
* 首页
*/
@Controller
@RequestMapping("/home")
public class HomeController {
/**
* 日志
*/
private static final Logger logger = LoggerFactory.getLogger(HomeController.class);
/**
* 首页 (控制器的页面写法)
* @param code
* @param model
* @return
*/
@RequestMapping("/index")
public String index(@RequestParam String code,Model model) {
try{
//传入值 code
String userName="许永明";
//给模板传值
model.addAttribute("username",userName);
model.addAttribute("code",code);
}
catch (Exception ex){
logger.error("首页异常",ex);
}
//对应模板中的路径
return "/home/index";
}
/**
* 机构单位数据列表 (方法写法)
* @param pageIndex 当前页
* @param pageSize 页大小
* @param lsdwh 隶属单位号
* @param dwmc 单位名称
* @return Mes结果
*/
@RequestMapping(value = "/getDataList",method = RequestMethod.POST)
@ResponseBody
public Map getDataList(@RequestParam int pageIndex, @RequestParam int pageSize, String dwmc, String lsdwh){
Map<String,Object> result=new HashMap<String,Object>();
try{
Map<String,Object> param=new HashMap<String,Object>();
if(!StringUtils.isEmptyOrWhitespace(lsdwh))
param.put("lsdwh",lsdwh);
if(!StringUtils.isEmptyOrWhitespace(dwmc))
param.put("dwmc",dwmc);
return result;
}
catch (Exception ex){
logger.error("机构单位数据列表发生异常",ex);
}
return result;
}
}
--------------------------------------------
模板页面代码:/resources/templates/home/index.html
----------------------------------------
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>测试系统首页</title>
<meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no"/>
<base th:href="${#httpServletRequest.getContextPath()+'/'}"/>
</head>
<body style="margin:0;padding:0">
<script type="text/javascript" th:inline="javascript">
var code = '${code}';
</script>
<div id="app" v-cloak>
<span th:text="'欢迎您!'+${username}"></span>
<br>
<span th:text="'code'+${code}"></span>
</div>
</body>
</html>
-------------------------------
最后运行,在浏览器中输入:http://localhost:9001/home/index?code=2222
查看页面是否成功。
用Mybatisplus建立增删改改查操作
MP用法参照官网:https://mybatis.plus/guide/quick-start.html#%E5%88%9D%E5%A7%8B%E5%8C%96%E5%B7%A5%E7%A8%8B 的使用说明。
准备user表及部分数据
配置
1、用Maven引入Mybatis Plus
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.4.0</version>
</dependency>
2、在 Spring Boot 启动类中添加 @MapperScan
注解,扫描 Mapper 文件夹
@MapperScan("com.xym.mybatisdemo.mapper")
@SpringBootApplication
public class MybatisdemoApplication {
public static void main(String[] args) {
SpringApplication.run(MybatisdemoApplication.class, args);
}
}
编码
编写实体类 User.java(此处使用了 Lombok 简化代码)
package com.xym.mybatisdemo.entity;
import lombok.Data;
/*
用户类
*/
@Data
public class User {
private Long id;
private String name;
private String password;
private String remark;
}
编写Mapper类 UserMapper.java
package com.xym.mybatisdemo.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.xym.mybatisdemo.entity.User;
public interface UserMapper extends BaseMapper<User> {
}
建立UserService类,一般路径为 service.UserService.java
----------------------------------------
public interface UserService extends IService<User> {
}
-----------------------------------------
建立UserServiceImpl实现类,一般路径为 service.impl.UserServiceImpl.java
------------------------------------------
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
}
开始使用
简单测试
建立测试页面,在test文件夹下,建立UserMapperTest 的测试文件。
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserMapperTest {
@Autowired
private UserMapper userMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<User> userList = userMapper.selectList(null);
Assert.assertEquals(4, userList.size());
userList.forEach(System.out::println);
}
}
引入junit、spring-boot-starter-test配置项,然后 光标在类名上,快捷键Alt+Enter 。
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
通过服务封装测试
建立UserService类,一般路径为 service.UserService.java
----------------------------------------
public interface UserService extends IService<User> {
}
-----------------------------------------
建立UserServiceImpl实现类,一般路径为 service.impl.UserServiceImpl.java
------------------------------------------
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper,User> implements UserService {
}
------------------------------------------
建立测试类 UserServiceImplTest,(Test)一般路径为 service.impl.UserServiceImpl.java
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceImplTest {
@Autowired
UserService userService;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<User> userList = userService.list();
Assert.assertEquals(4, userList.size());
userList.forEach(System.out::println);
}
}
保存 save
@Test
public void testSave(){
System.out.println(("----- add method test ------"));
log.info("----- add method test ------");
User obj=new User();
obj.setId(10001L);
obj.setName("测试save");
boolean result= userService.save(obj);
Assert.assertEquals(true,result);
System.out.println(("----- save 成功 ------"));
}
更新 updataById
@Test
public void testUpdateById(){
System.out.println(("----- testUpdateById method test ------"));
log.info("----- testUpdateById method test ------");
User obj=new User();
obj.setId(10001L);
obj.setName("测试ById");
Wrapper<User> userWrapper=new UpdateWrapper<>();
boolean result= userService.updateById(obj);
Assert.assertEquals(true,result);
System.out.println(("----- testUpdateById 成功 ------"));
}
条件更新 UpdateWrapper
@Test
public void testUpdateWrapper(){
System.out.println(("----- testUpdateWrapper method test ------"));
log.info("----- testUpdateWrapper method test ------");
UpdateWrapper<User> userWrapper=new UpdateWrapper<>();
//修改语句
//字段
userWrapper.set("remark","UpdateWrapper");
//语句
userWrapper.setSql("difference_amount = planned_amount - "+1);
//条件
userWrapper.eq("id",10001L);
boolean result= userService.update(userWrapper);
Assert.assertEquals(true,result);
System.out.println(("----- testUpdateWrapper 成功 ------"));
}
条件查询 list - QueryWrapper
@Test
public void testlist(){
System.out.println(("----- list -QueryWrapper method test ------"));
log.info("----- list- QueryWrapper method test ------");
QueryWrapper<User> querWrapper=new QueryWrapper<>();
querWrapper.eq("id",10001L);
//querWrapper.or();
//querWrapper.and(querWrapper);
List result= userService.list(querWrapper);
Assert.assertEquals(1,result.size());
System.out.println(("----- list -QueryWrapper 成功 ------"));
}
分页 Page
分页时需要用到分页插件
在pom.xml引入插件 mybatis-plus-extension
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-extension</artifactId>
<version>3.4.0</version>
</dependency>
配置Config
新建MybatisConfig 路径 config.MybatisConfig.java
/**
* MybatisPlus配置
*/
@EnableTransactionManagement
@Configuration
public class MybatisConfig {
/**
* 注册乐观锁插件
*
* @return OptimisticLockerInterceptor
*/
@Bean
public OptimisticLockerInterceptor optimisticLockerInterceptor() {
return new OptimisticLockerInterceptor();
}
/**
* 分页插件
*
* @return PaginationInterceptor
*/
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
测试代码
@Test
public void testPage(){
System.out.println(("----- Page method test ------"));
log.info("----- Page method test ------");
Page<User> userPage=new Page<>();
userPage.setCurrent(0);
userPage.setSize(2L);
QueryWrapper<User> querWrapper=new QueryWrapper<>();
//querWrapper.eq("id",10001L);
//querWrapper.or();
//querWrapper.and(querWrapper);
userService.page(userPage,querWrapper);
Assert.assertEquals(0,userPage.getTotal());
System.out.println(("----- list -QueryWrapper 成功 ------"));
}
动态SQL查询
在Mapper上注入SQL模板
// 分页查询
@Select("<script>" +
" select t.*" +
" from user t " +
" where <![CDATA[t.id > '2' ]]>" +
" <if test='name != null and name.trim() != ""'>" +
" AND t.name like CONCAT('%',#{name},'%')" +
" </if>" +
" </script>")
IPage<User> selectUserbyPage(Page<User> page, @Param("name") String name);
在Service的接口类上定义接口
IPage<User> selectUserbyPage(Page<User> page, @Param("name") String name);
在Service的实现类实现该方法
@Autowired
UserMapper userMapper;
@Override
public IPage<User> selectUserbyPage(Page<User> page, String name) {
userMapper.selectUserbyPage(page,name);
return page;
}
测试代码
@Test
public void testSQL(){
System.out.println(("----- Page - selectUserbyPage method test ------"));
log.info("----- Page -selectUserbyPage method test ------");
Page<User> userPage=new Page<>();
userPage.setCurrent(0);
userPage.setSize(2L);
userService.selectUserbyPage(userPage,"");
Assert.assertEquals(3,userPage.getTotal());
System.out.println(("----- list -selectUserbyPage 成功 ------"));
}
事务使用
配置Mybatis Plus的事务
在MybatisConfig类中加上 @EnableTransactionManagement 就可以了
增加事务异常类
必须是RuntimeException 异常事务才会滚,所有我们自己需要添加一个 继承RuntimeException 的类
@Getter
public class APIException extends RuntimeException{
private int code;
private String msg;
// 手动设置异常
public APIException(int statusCode, String message) {
// message用于用户设置抛出错误详情,例如:当前价格-5,小于0
super(message);
// 状态码
this.code = statusCode;
// 状态码配套的msg
this.msg = message;
}
// 默认异常使用APP_ERROR状态码
public APIException(String message) {
super(message);
this.code = 0;
this.msg = message;
}
}
在Service的接口类上定义接口
Boolean Add(User obj1,User obj2);
在Service的实现类实现该方法 @Transactional
@Transactional
@Override
public Boolean Add(User obj1, User obj2) {
int icount= userMapper.insert(obj1);
if(icount!=1){
throw new APIException(1,"添加数据失败");
}
userMapper.insert(obj2);
if(icount!=1){
throw new APIException(1,"添加数据失败");
}
return true;
}
测试代码
@Test
public void testAdd(){
System.out.println(("----- Add 事务 method test ------"));
log.info("----- Add 事务 method test ------");
User obj=new User();
obj.setId(10003L);
obj.setName("数据3");
User obj1=new User();
obj1.setId(10004L);
obj1.setName("数据2");
boolean b= userService.Add(obj,obj1);
Assert.assertEquals(true,b);
System.out.println(("----- Add 事务 成功 ------"));
}
代码生成
用EasyCode生成 Entitly类就行了,其它代码都拷贝过去手写好了。
安装EasyCode插件
连接数据库
在表中点右键选择Easycode生成代码
生成好的类用 @Data 修饰
/**
* (Employee)实体类
*
* @author makejava
* @since 2020-10-30 17:53:08
*/
@Data
public class Employee {
/**
* 记录号
*/
private String id;
/**
* 账号
*/
private String empno;
/**
* 姓名
*/
private String ename;
/**
* 手机
*/
private String mobilephone;
/**
* 部门
*/
private String department;
/**
* 邮箱
*/
private String emaile;
/**
* 性别(1男,2女)
*/
private Integer mgr;
/**
* 状态(1可用0停用)
*/
private Integer state;
/**
* 创建时间
*/
private Date createtime;
/**
* 更新时间
*/
private Date updatetime;
/**
* 密码
*/
private String passwords;
}