本文是《MyBatis初級實戰》系列的第二篇,前文《 》我們知道了如何在SpringBoot中集成MyBatis,本篇就一起來練習基本功:增刪改查;
本篇要練習的內容如下:
全文由以下部分組成:
<!-- swagger-ui --><dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> <version>2.5.0</version></dependency><dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.6</version></dependency>
<?xml version=&34; encoding=&34;?><project xmlns=&34; xmlns:xsi=&34; xsi:schemaLocation=&34;> <modelVersion>4.0.0</modelVersion> <parent> <groupId>com.bolingcavalry</groupId> <artifactId>mybatis</artifactId> <version>1.0-SNAPSHOT</version> <relativePath>../pom.xml</relativePath> </parent> <groupId>com.bolingcavalry</groupId> <artifactId>curd</artifactId> <version>0.0.1-SNAPSHOT</version> <name>curd</name> <description>Demo project for Mybatis CURD in Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger2</artifactId> </dependency> <!-- swagger-ui --> <dependency> <groupId>io.springfox</groupId> <artifactId>springfox-swagger-ui</artifactId> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build></project>
package com.bolingcavalry.curd;import org.mybatis.spring.annotation.MapperScan;import org.springframework.boot.SpringApplication;import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication@MapperScan(&34;)public class CurdApplication { public static void main(String[] args) { SpringApplication.run(CurdApplication.class, args); }}
package com.bolingcavalry.curd;import springfox.documentation.service.Contact;import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import springfox.documentation.builders.ApiInfoBuilder;import springfox.documentation.builders.PathSelectors;import springfox.documentation.builders.RequestHandlerSelectors;import springfox.documentation.service.ApiInfo;import springfox.documentation.service.Tag;import springfox.documentation.spi.DocumentationType;import springfox.documentation.spring.web.plugins.Docket;import springfox.documentation.swagger2.annotations.EnableSwagger2;@Configuration@EnableSwagger2public class SwaggerConfig { @Bean public Docket createRestApi() { return new Docket(DocumentationType.SWAGGER_2) .apiInfo(apiInfo()) .tags(new Tag(&34;, &34;), new Tag(&34;, &34;)) .select() // 當前包路徑 .apis(RequestHandlerSelectors.basePackage(&34;)) .paths(PathSelectors.any()) .build(); } //構建 api文檔的詳細信息函數,注意這裡的註解引用的是哪個 private ApiInfo apiInfo() { return new ApiInfoBuilder() //頁面標題 .title(&34;) //創建人 .contact(new Contact(&34;, &34;, &34;)) //版本號 .version(&34;) //描述 .description(&34;) .build(); }}
server: port: 8080spring: mybatis配置mybatis: 映射文件所在位置 mapper-locations: classpath:mappers/*Mapper.xml34;用戶實體類&34;用戶ID&34;用戶名&34;用戶地址&34;User{&34;id=&34;, name=&34; + name + &39;&34;, age=&39;}&34;日誌實體類&34;日誌ID&34;用戶ID&34;日誌內容&34;創建時間&34;Log{&34;id=&34;, userId=&34;, action=&34; + action + &39;&34;, createTime=&39;}&34;日誌實體類(含用戶表的欄位)&34;用戶名&34;LogExtend{&34;id=&34;, userId=&34;, userName=&34; + getUserName() + &39;&34;, action=&34; + getAction() + &39;&34;, createTime=&39;}&34;1.0&34;UTF-8&34;-//mybatis.org//DTD Mapper 3.0//EN&34;http://mybatis.org/dtd/mybatis-3-mapper.dtd&34;com.bolingcavalry.curd.mapper.UserMapper&34;sel&34;int&34;user&{id} </select> <!--新增單條記錄--> <insert id=&34; useGeneratedKeys=&34; keyProperty=&34;> insert into user (id, name, age) values ({name}, 34;insertBatch&34;true&34;id&34;users&34;user&34;,&{user.id}, {user.age}) </foreach> </insert> <!--按照名稱查找--> <select id=&34; parameterType=&34; resultType=&34;> select id, name, age from user where name like concat(&39;, 39;%&34;delete&{id} </delete> <!--刪除所有數據--> <delete id=&34;> delete from user </delete> <!--更新--> <update id=&34;> update user set name = {age} where id = 34;totalCount&34;java.lang.Integer&34;1.0&34;UTF-8&34;-//mybatis.org//DTD Mapper 3.0//EN&34;http://mybatis.org/dtd/mybatis-3-mapper.dtd&34;com.bolingcavalry.curd.mapper.LogMapper&34;logExtendResultMap&34;logExtend&34;id&34;id&34;user_id&34;INTEGER&34;userId&34;action&34;VARCHAR&34;action&34;create_time&34;TIMESTAMP&34;createTime&34;user_name&34;TIMESTAMP&34;userName&34;insertWithFields&34;true&34;id&34;log&{id}, {action}, 34;selExtend&34;int&34;logExtendResultMap&{id} </select></mapper>
package com.bolingcavalry.curd.mapper;import com.bolingcavalry.curd.entity.LogExtend;import com.bolingcavalry.curd.entity.User;import org.springframework.stereotype.Repository;import java.util.List;@Repositorypublic interface UserMapper { User sel(int id); int insertWithFields(User user); int insertBatch(List<User> users); int clearAll(); List<User> findByName(String name); int update(User user); int delete(int id); int totalCount(); LogExtend selExtend(int id);}
package com.bolingcavalry.curd.mapper;import com.bolingcavalry.curd.entity.Log;import com.bolingcavalry.curd.entity.LogExtend;import org.springframework.stereotype.Repository;@Repositorypublic interface LogMapper { Log sel(int id); LogExtend selExtend(int id); int insertWithFields(Log log);}
package com.bolingcavalry.curd.service;import com.bolingcavalry.curd.entity.User;import com.bolingcavalry.curd.mapper.UserMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;import java.util.List;@Servicepublic class UserService { @Autowired UserMapper userMapper; public User sel(int id) { return userMapper.sel(id); } public User insertWithFields(User user) { userMapper.insertWithFields(user); return user; } public List<User> insertBatch(List<User> users) { userMapper.insertBatch(users); return users; } public int clearAll() { return userMapper.clearAll(); } public List<User> findByName(String name) { return userMapper.findByName(name); } public int update(User user) { return userMapper.update(user); } public int delete(int id) { return userMapper.delete(id); } public int totalCount() { return userMapper.totalCount(); }}
package com.bolingcavalry.curd.service;import com.bolingcavalry.curd.entity.Log;import com.bolingcavalry.curd.entity.LogExtend;import com.bolingcavalry.curd.entity.User;import com.bolingcavalry.curd.mapper.LogMapper;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.stereotype.Service;@Servicepublic class LogService { @Autowired LogMapper logMapper; public Log sel(int id){ return logMapper.sel(id); } public LogExtend selExtend(int id) { return logMapper.selExtend(id); } public Log insertWithFields(Log log) { logMapper.insertWithFields(log); return log; }}
package com.bolingcavalry.curd.controller;import com.bolingcavalry.curd.entity.User;import com.bolingcavalry.curd.service.UserService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiImplicitParam;import io.swagger.annotations.ApiOperation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;import java.util.ArrayList;import java.util.List;@RestController@RequestMapping(&34;)@Api(tags = {&34;})public class UserController { @Autowired private UserService userService; @ApiOperation(value = &34;, notes=&34;) @RequestMapping(value = &34;,method = RequestMethod.PUT) public User create(@RequestBody User user) { return userService.insertWithFields(user); } @ApiOperation(value = &34;, notes=&34;) @RequestMapping(value = &34;, method = RequestMethod.PUT) public List<User> insertBatch(@RequestBody List<User> users) { return userService.insertBatch(users); } @ApiOperation(value = &34;, notes=&34;) @ApiImplicitParam(name = &34;, value = &34;, paramType = &34;, required = true, dataType = &34;) @RequestMapping(value = &34;, method = RequestMethod.DELETE) public int delete(@PathVariable int id){ return userService.delete(id); } @ApiOperation(value = &34;, notes=&34;) @RequestMapping(value = &34;, method = RequestMethod.DELETE) public int clearAll(){ return userService.clearAll(); } @ApiOperation(value = &34;, notes=&34;) @RequestMapping(value = &34;, method = RequestMethod.POST) public int update(@RequestBody User user){ return userService.update(user); } @ApiOperation(value = &34;, notes=&34;) @ApiImplicitParam(name = &34;, value = &34;, paramType = &34;, required = true, dataType = &34;) @RequestMapping(value = &34;, method = RequestMethod.GET) public List<User> findByName(@PathVariable(&34;) String name){ return userService.findByName(name); } @ApiOperation(value = &34;, notes=&34;) @ApiImplicitParam(name = &34;, value = &34;, paramType = &34;, required = true, dataType = &34;) @RequestMapping(value = &34;, method = RequestMethod.GET) public User GetUser(@PathVariable int id){ return userService.sel(id); } @ApiOperation(value = &34;, notes=&34;) @RequestMapping(value = &34;, method = RequestMethod.GET) public int totalcount(){ return userService.totalCount(); }}
package com.bolingcavalry.curd.controller;import com.bolingcavalry.curd.entity.Log;import com.bolingcavalry.curd.entity.LogExtend;import com.bolingcavalry.curd.service.LogService;import io.swagger.annotations.Api;import io.swagger.annotations.ApiImplicitParam;import io.swagger.annotations.ApiOperation;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.*;@RestController@RequestMapping(&34;)@Api(tags = {&34;})public class LogController { @Autowired private LogService logService; @ApiOperation(value = &34;, notes=&34;) @ApiImplicitParam(name = &34;, value = &34;, paramType = &34;, required = true, dataType = &34;) @RequestMapping(value = &34;, method = RequestMethod.GET) public LogExtend logExtend(@PathVariable int id){ return logService.selExtend(id); } @ApiOperation(value = &34;, notes=&34;) @RequestMapping(value = &34;,method = RequestMethod.PUT) public Log create(@RequestBody Log log) { return logService.insertWithFields(log); }}
package com.bolingcavalry.curd.controller;import com.bolingcavalry.curd.entity.User;import com.google.gson.Gson;import com.google.gson.JsonArray;import com.google.gson.JsonParser;import org.junit.Ignore;import org.junit.jupiter.api.*;import org.junit.runner.RunWith;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;import org.springframework.boot.test.context.SpringBootTest;import org.springframework.http.MediaType;import org.springframework.test.context.junit4.SpringRunner;import org.springframework.test.web.servlet.MockMvc;import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;import java.util.List;import java.util.UUID;import static org.hamcrest.Matchers.hasSize;import static org.hamcrest.Matchers.is;import static org.hamcrest.core.IsEqual.equalTo;import static org.springframework.test.web.servlet.result.MockMvcResultHandlers.print;import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;@RunWith(SpringRunner.class)@SpringBootTest@AutoConfigureMockMvc@TestMethodOrder(MethodOrderer.OrderAnnotation.class)class UserControllerTest { @Autowired private MockMvc mvc; // user表的name欄位,這裡為了保證測試時新增和刪除的記錄是同一條,用UUID作為用戶名 static String testName; @BeforeAll static void init() { testName = UUID.randomUUID().toString().replaceAll(&34;,&34;);; } @Test @Order(1) void insertWithFields() throws Exception { String jsonStr = &34;name\&34;&34;\&34;age\&34;; mvc.perform( MockMvcRequestBuilders.put(&34;) .contentType(MediaType.APPLICATION_JSON) .content(jsonStr) .accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath(&34;, is(testName))) .andDo(print()) .andReturn() .getResponse() .getContentAsString(); } @Test @Order(2) void findByName() throws Exception { mvc.perform(MockMvcRequestBuilders.get(&34;+ testName).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath(&34;, hasSize(1))) .andDo(print()); } @Test @Order(3) void delete() throws Exception { // 先根據名稱查出記錄 String responseString = mvc.perform(MockMvcRequestBuilders.get(&34;+ testName).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(jsonPath(&34;, hasSize(1))) .andDo(print()) .andReturn() .getResponse() .getContentAsString(); // 反序列化得到數組 JsonArray jsonArray = JsonParser.parseString(responseString).getAsJsonArray(); // 反序列化得到user實例 User user = new Gson().fromJson(jsonArray.get(0), User.class); // 執行刪除 mvc.perform(MockMvcRequestBuilders.delete(&34;+ user.getId()).accept(MediaType.APPLICATION_JSON)) .andExpect(status().isOk()) .andExpect(content().string(equalTo(&34;))) .andDo(print()); }}
至此,MyBatis的基本增刪改查和簡單的聯表操作的實戰就完成了,接下來的文章咱們會繼續探索MyBatis的基本操作;