一、MybatisPlus简化数据库交互
我们使用Mybatis发现需要在mapper.xml中写很多重复的简单CRUD(增删改查),使用MybatisPlus可以大大简化这部分代码,官方文档http://mp.baomidou.com/
二、引入MybatisPlus
先看一下我的项目结构,我们一步一步来编写这个Demo,我的Model对象是一个独立模块,所以请自行修改自己的实体对象
1、创建一个Maven项目引入spring boot,打开pom.xml增加以下引入,其中包括alibaba连接池druid、mysql数据库连接插件、mybatis-plus插件,切记不要引入mybatis及mybatis spring可能会有冲突
<dependencyManagement> <dependencies> <dependency> <!-- Import dependency management from Spring Boot --> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>2.0.3.RELEASE</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--import druid--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--import mysql connector--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.9</version> </dependency> <!--import mybatis plus 它会自动引入mybatis及mybatis spring切勿重复引用以免冲突--> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>2.3</version> </dependency> </dependencies>
2、建立resources文件夹并创建application.yml配置文件,增加以下配置,主要数据库连接、mapper.xml、model实体的位置需要自己调整
#设置提供的服务名 spring: application: name: javademo-tyh-service-base #配置数据库 datasource: driver-class-name: com.mysql.jdbc.Driver type: com.alibaba.druid.pool.DruidDataSource url: jdbc:mysql://10.11.12.237:3306/tyh_test?useUnicode=true&characterEncoding=utf8 username: root password: root #设置自己启动的端口 server: port: 12000 #mybatis plus mybatis-plus: #指明mapper.xml扫描位置(classpath* 代表编译后类文件根目录) mapper-locations: classpath*:/mapper/**Mapper.xml #指明实体扫描(多个package用逗号或者分号分隔) typeAliasesPackage: javademo.tyh.model.base;javademo.tyh.model.hotel; global-config: #主键类型 0:数据库ID自增, 1:用户输入ID,2:全局唯一ID (数字类型唯一ID), 3:全局唯一ID UUID id-type: 0 #字段策略(拼接sql时用于判断属性值是否拼接) 0:忽略判断,1:非NULL判断,2:非空判断 field-strategy: 2 #驼峰下划线转换含查询column及返回column(column下划线命名create_time,返回java实体是驼峰命名createTime,开启后自动转换否则保留原样) db-column-underline: true #是否动态刷新mapper refresh-mapper: false #数据库大写命名下划线转换 #capital-mode: true
3、在resources文件夹下创建mapper文件夹用于存放所有的mapper.xml文件,创建UserMapper.xml文件编写一个自定义sql
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org/DTD Mapper 3.0" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <!-- 指明当前xml对应的Mapper --> <mapper namespace="javademo.tyh.service.base.mapper.UserMapper"> <select id="listCount" resultType="Integer"> select count(*) from user_info; </select> </mapper>
4、打开main方法所在类,修改代码指明扫描mapper接口所在包的位置
import org.mybatis.spring.annotation.MapperScan; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @MapperScan("javademo.tyh.service.base.mapper")//标记扫描的mapper位置 public class AppServiceBase { public static void main( String[] args ) { SpringApplication.run(AppServiceBase.class,args); } }
5、创建config文件夹用于存放mybatisplus的插件配置,目前只需要一个分页插件
import com.baomidou.mybatisplus.plugins.PaginationInterceptor; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class MybatisPlusConfig { // 分页拦截器 @Bean public PaginationInterceptor paginationInterceptor(){ return new PaginationInterceptor(); } }
6、创建mapper文件夹用于存放底层与xml的关联mapper接口,要继承BaseMapper并传递一个Model对象当作泛型,再写一个自定义方法
import com.baomidou.mybatisplus.mapper.BaseMapper; import javademo.tyh.model.base.UserModel; import org.springframework.stereotype.Component; @Component public interface UserMapper extends BaseMapper<UserModel> { //自定义方法 int listCount(); }
7、创建service文件夹用于存放业务操作逻辑,此时自动注入mapper后可以调用很多mybatis plus提供的方法,基本的CRUD都不需要单独写了
import com.baomidou.mybatisplus.mapper.EntityWrapper; import javademo.tyh.model.base.UserModel; import javademo.tyh.service.base.mapper.UserMapper; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import java.util.List; @Service public class UserService { @Autowired UserMapper mapper; public int insert(UserModel model) { return mapper.insert(model); } public int delete(int id) { return mapper.deleteById(id); } public int update(UserModel model) { //更新全部字段,但可以跟application.yml中的field-strategy字段策略相配合,不更新为null或为空的字段 return mapper.updateById(model); //更新全部字段,且不可为NULL //return mapper.updateAllColumnById(model); } public UserModel get(int id) { return mapper.selectById(id); } public List<UserModel> list() { EntityWrapper ew = new EntityWrapper(); ew.where("1={0}", 1); return mapper.selectList(ew); } //调用自定义方法 public int listCount(){ return mapper.listCount(); } }
8、创建controller文件夹用于接收请求和测试
import javademo.tyh.model.base.UserModel; import javademo.tyh.service.base.service.UserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cloud.client.discovery.DiscoveryClient; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import java.time.LocalDateTime; import java.util.List; @Controller @RequestMapping("/user") public class UserController { @Autowired private DiscoveryClient client; @Autowired UserService service; @ResponseBody @RequestMapping("/insert") public int insert() { UserModel model = new UserModel(); model.setUsername("taiyonghai"); model.setPassword("111111"); model.setSex(1); model.setAge(30); model.setCreateTime(LocalDateTime.now()); return service.insert(model); } @ResponseBody @RequestMapping("/delete") public int delete(int id) { return service.delete(id); } @ResponseBody @RequestMapping("/update") public int update() { UserModel model = new UserModel(); model.setId(1); model.setUsername("taiyonghai"+LocalDateTime.now()); model.setPassword("111111"); model.setSex(1); model.setAge(30); return service.update(model); } @ResponseBody @RequestMapping("/get") public UserModel get(int id) { return service.get(id); } @ResponseBody @RequestMapping("/list") public List<UserModel> list() { List<UserModel> list = service.list(); return list; } @ResponseBody @RequestMapping("/listCount") public int listCount() { return service.listCount(); } }
9、标记Model实体的注解,我就不粘贴get/set方法了自己生成吧
import com.baomidou.mybatisplus.annotations.TableField; import com.baomidou.mybatisplus.annotations.TableId; import com.baomidou.mybatisplus.annotations.TableName; import com.baomidou.mybatisplus.enums.IdType; import java.io.Serializable; import java.time.LocalDateTime; //标记表名(此注解为必须,下面的字段注解可选) @TableName("user_info") public class UserModel implements Serializable { //标记数据表主键 @TableId(value = "id", type = IdType.AUTO) private int id; private String username; private String password; private int sex; private int age; private LocalDateTime createTime; //标记数据表中不存在的字段 @TableField(exist = false) private String showName; //标记数据表中的column名 @TableField("username") private String showUsername; }
由于我的模块Model是独立的所以需要对Model模块增加pom.xml引用,由于不需要跟spring boot自动注入有什么关系所以直接只引用基本的即可
<dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>2.3</version> </dependency>
OK ,到此我们的MybatisPlus就引入完成,运行http://localhost:12000/user/list测试一下效果,官方文档中推荐使用IService及ServiceImpl的接口及实现类的方式,这部分可以简化,简化后的效果就是这个Demo的样子
注意:由于两个模块需要mybatis plus我有个父级pom.xml,而pom.xml文件有上下级继承关系,如果父级有用到xxx-xxx-boot-starter的组件引用,子模块中却没有相应的配置注入则会提示错误,要在main()方法对应的类中增加注解来解决
@EnableAutoConfiguration(exclude = DataSourceAutoConfiguration.class)//禁止tomcat DataSource注入到spring boot中 @SpringBootApplication public class AppEureka { public static void main( String[] args ) { SpringApplication.run(AppEureka.class, args); } }