技術(shù)分享 | 數(shù)據(jù)持久化技術(shù)(Java)
本文節(jié)選自霍格沃茲測試學(xué)院內(nèi)部教材
本章介紹 Web 后端開發(fā)中數(shù)據(jù)持久化技術(shù) TKMyBatis。
TKMyBatis簡介
TKMybatis 是基于 Mybatis 框架開發(fā)的一個工具,內(nèi)部實(shí)現(xiàn)了對單表的基本數(shù)據(jù)操作,只需要簡單繼承 TKMybatis 提供的接口,就能夠?qū)崿F(xiàn)無需編寫任何 sql 即能完成單表操作。
下面簡單介紹下 MyBatis , MyBatis 是一款優(yōu)秀的持久層框架,它支持自定義 SQL、存儲過程以及高級映射。MyBatis 免除了幾乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的工作。MyBatis 可以通過簡單的 XML 或注解來配置和映射原始類型、接口和 Java POJO(Plain Old Java Objects,普通老式 Java 對象)為數(shù)據(jù)庫中的記錄。
詳細(xì)內(nèi)容請參考?mybatis – MyBatis 3 | 簡介
TKMyBatis快速開始
Maven依賴
<dependency>
? ? ? ? ? ?<groupId>org.mybatis.spring.boot</groupId>
? ? ? ? ? ?<artifactId>mybatis-spring-boot-starter</artifactId>
? ? ? ? ? ?<version>2.1.0</version>
? ? ? ?</dependency>
? ? ? ?<dependency>
? ? ? ? ? ?<groupId>tk.mybatis</groupId>
? ? ? ? ? ?<artifactId>mapper</artifactId>
? ? ? ? ? ?<version>4.0.3</version>
? ? ? ?</dependency>
? ? ? ?<dependency>
? ? ? ? ? ?<groupId>tk.mybatis</groupId>
? ? ? ? ? ?<artifactId>mapper-spring-boot-starter</artifactId>
? ? ? ? ? ?<version>2.0.3</version>
? ? ? ?</dependency>
? ? ? ?<dependency>
? ? ? ? ? ?<groupId>mysql</groupId>
? ? ? ? ? ?<artifactId>mysql-connector-java</artifactId>
? ? ? ? ? ?<scope>runtime</scope>
? ? ? ?</dependency>
在啟動類中配置 MapperScan 掃描
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import tk.mybatis.spring.annotation.MapperScan;
@SpringBootApplication
@MapperScan("com.hogwartsmini.demo.dao")
public class DemoApplication {
? ?public static void main(String[] args) {
? ? ? ?SpringApplication.run(DemoApplication.class, args);
? ?}
}
實(shí)體類中使用
在實(shí)體類中,常用的注解和意義為:
Table:描述數(shù)據(jù)庫表信息,主要屬性有 name(表名)、schema、catalog、uniqueConstraints 等。
Id:指定表主鍵字段,沒有屬性值。
Column:描述數(shù)據(jù)庫字段信息,主要屬性有 name(字段名)、columnDefinition、insertable、length、nullable(是否可為空)、precision、scale、table、unique、updatable 等。
ColumnType:描述數(shù)據(jù)庫字段類型,可對一些特殊類型作配置,進(jìn)行特殊處理,主要屬性有 jdbcType、column、typeHandler 等。
dao 中使用
創(chuàng)建業(yè)務(wù) Mapper 公共接口
首先創(chuàng)建一個公共接口,繼承 Mapper, MySqlMapper, IdsMapper 三個類,用于后續(xù)業(yè)務(wù) Mapper 接口直接實(shí)現(xiàn)。
import tk.mybatis.mapper.common.IdsMapper;
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
public interface MySqlExtensionMapper<T> extends Mapper<T>, MySqlMapper<T>, IdsMapper<T> {
}
創(chuàng)建業(yè)務(wù) Mapper 接口
創(chuàng)建 HogwartsTestUserMapper.java 接口
import com.hogwartsmini.demo.common.MySqlExtensionMapper;
import com.hogwartsmini.demo.entity.HogwartsTestUser;
import org.springframework.stereotype.Repository;
@Repository
public interface HogwartsTestUserMapper extends MySqlExtensionMapper<HogwartsTestUser> {
}
Service 層中使用
新增操作
類型說明Mapper.insert(record)保存一個實(shí)體,null 的屬性也會保存,不會使用數(shù)據(jù)庫默認(rèn)值Mapper.insertSelective(record)保存一個實(shí)體,忽略空值,即沒提交的值會使用使用數(shù)據(jù)庫默認(rèn)值Mapper.insertUseGeneratedKeys(record)保存一個實(shí)體,會自動填入在數(shù)據(jù)庫中生成的 id 值。注意使用此方法插入數(shù)據(jù)時,如果 id 字段不是 AUTO_INCREMENT ,則不會生成新的 id
刪除
類型說明Mapper.delete(record)根據(jù)實(shí)體屬性作為條件進(jìn)行刪除,查詢條件使用等號Mapper.deleteByExample(example)根據(jù) Example 條件刪除數(shù)據(jù)Mapper.deleteByPrimaryKey(key)根據(jù)主鍵字段進(jìn)行刪除,方法參數(shù)必須包含完整的主鍵屬性
修改
類型說明Mapper.updateByExample(record,example)根據(jù) Example 條件更新實(shí)體record 包含的全部屬性,null 值會被更新Mapper.updateByExampleSelective(record, example)根據(jù) Example 條件更新實(shí)體record 包含的不是 null 的屬性值Mapper.updateByPrimaryKey(record)根據(jù)主鍵更新實(shí)體全部字段,null 值會被更新Mapper.updateByPrimaryKeySelective(record)根據(jù)主鍵更新屬性不為 null 的值
查詢
類型說明Mapper.select(record)根據(jù)實(shí)體中的屬性值進(jìn)行查詢,查詢條件使用等號Mapper.selectAll()查詢?nèi)拷Y(jié)果Mapper.selectByExample(example)根據(jù) Example 條件進(jìn)行查詢Mapper.selectByPrimaryKey(key)根據(jù)主鍵字段進(jìn)行查詢,方法參數(shù)必須包含完整的主鍵屬性,查詢條件使用等號Mapper.selectCount(record)根據(jù)實(shí)體中的屬性查詢總數(shù),查詢條件使用等號Mapper.selectCountByExample(example)根據(jù) Example 條件進(jìn)行查詢總數(shù)Mapper.selectByExample(example)根據(jù) Example 條件進(jìn)行查詢Mapper.selectOne(record)根據(jù)實(shí)體中的屬性進(jìn)行查詢,只能有一個返回值,有多個結(jié)果是拋出異常,查詢條件使用等號。但是如果存在某個屬性為 int,則會初始化為 0??赡苡绊懙綄?shí)際使用
Spring Boot 配置文件
spring:
?application:
? ?name: aitest
?#數(shù)據(jù)庫配置信息
?datasource:
? ?url: jdbc:mysql://localhost:3306/aitest_mini?allowMultiQueries=true&useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
? ?username: hogwarts
? ?password: db@hogwarts
? ?driver-class-name: com.mysql.cj.jdbc.Driver
mybatis:
?mapper-locations: classpath:mapper/*.xml
?type-aliases-package: com.hogwartstest.aitestmini.entity
?configuration:
? ?mapUnderscoreToCamelCase: true
logging:
?level:
? ?com.hogwartstest.aitestmini.dao: debug #打印sql
示例表結(jié)構(gòu)
CREATE TABLE `hogwarts_test_user` (
?`id` int NOT NULL AUTO_INCREMENT COMMENT '主鍵',
?`user_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '用戶名',
?`password` varchar(32) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL COMMENT '密碼',
?`email` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '郵箱',
?`auto_create_case_job_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '自動生成用例job名稱 不為空時表示已經(jīng)創(chuàng)建job',
?`start_test_job_name` varchar(50) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT '執(zhí)行測試job名稱 不為空時表示已經(jīng)創(chuàng)建job',
?`default_jenkins_id` int DEFAULT NULL COMMENT '默認(rèn)Jenkins服務(wù)器',
?`create_time` datetime NOT NULL COMMENT '創(chuàng)建時間',
?`update_time` datetime NOT NULL COMMENT '更新時間',
?PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT='用戶表';
Controller 代碼
import com.hogwartsmini.demo.entity.HogwartsTestUser;
import com.hogwartsmini.demo.service.HogwartsTestUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import java.util.List;
/**
* @Author tlibn
* @Date 2020/7/16 17:14
**/
@Api(tags = "霍格沃茲測試學(xué)院-用戶管理模塊")
@RestController
@RequestMapping("hogwartsUser")
public class HogwartsTestUserDbController {
? ?@Autowired
? ?private HogwartsTestUserService hogwartsTestUserService;
? ?@ApiOperation("用戶注冊")
? ?@PostMapping("register")
? ?public HogwartsTestUser register(
? ? ? ? ? ?@RequestBody HogwartsTestUser hogwartsTestUser){
? ? ? ?return hogwartsTestUserService.save(hogwartsTestUser);
? ?}
? ?@ApiOperation("用戶信息修改接口")
? ?@PutMapping()
? ?public HogwartsTestUser updateUserInfo(
? ? ? ? ? ?@RequestBody HogwartsTestUser hogwartsTestUser){
? ? ? ?return hogwartsTestUserService.update(hogwartsTestUser);
? ?}
? ?@ApiOperation("根據(jù)用戶id刪除用戶信息")
? ?@DeleteMapping("{userId}")
? ?public Integer delete(@PathVariable("userId") Integer userId){
? ? ? ?return hogwartsTestUserService.delete(userId);
? ?}
? ?@ApiOperation("根據(jù)用戶名查詢")
? ?@GetMapping("byName")
? ?public List<HogwartsTestUser> getByName(
? ? ? ? ? ?@RequestParam("userName") String userName){
? ? ? ?HogwartsTestUser hogwartsTestUser = new HogwartsTestUser();
? ? ? ?hogwartsTestUser.setUserName(userName);
? ? ? ?return hogwartsTestUserService.getByName(hogwartsTestUser);
? ?}
HogwartsTestUserService 代碼
import com.hogwartsmini.demo.entity.HogwartsTestUser;
import java.util.List;
public interface HogwartsTestUserService {
? ?/**
? ? * ?保存
? ? * @param hogwartsTestUser
? ? * @return
? ? */
? ?HogwartsTestUser save(HogwartsTestUser hogwartsTestUser);
? ?/**
? ? * ?更新
? ? * @param hogwartsTestUser
? ? * @return
? ? */
? ?HogwartsTestUser update(HogwartsTestUser hogwartsTestUser);
? ?/**
? ? * ?根據(jù)用戶名查詢
? ? * @param hogwartsTestUser
? ? * @return
? ? */
? ?List<HogwartsTestUser> getByName(HogwartsTestUser hogwartsTestUser);
? ?/**
? ? * ?根據(jù)用戶id刪除用戶信息
? ? * @param userId
? ? * @return
? ? */
? ?Integer delete(Integer userId);
}
HogwartsTestUserServiceImpl 代碼
import com.hogwartsmini.demo.dao.HogwartsTestUserMapper;
import com.hogwartsmini.demo.entity.HogwartsTestUser;
import com.hogwartsmini.demo.service.HogwartsTestUserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.Date;
import java.util.List;
/**
* @Author tlibn
* @Date 2020/7/17 11:03
**/
@Service
public class HogwartsTestUserServiceImpl implements HogwartsTestUserService {
? ?@Autowired
? ?private HogwartsTestUserMapper hogwartsTestUserMapper;
? ?/**
? ? * 保存
? ? *
? ? * @param hogwartsTestUser
? ? * @return
? ? */
? ?@Override
? ?public HogwartsTestUser save(HogwartsTestUser hogwartsTestUser) {
? ? ? ?hogwartsTestUser.setCreateTime(new Date());
? ? ? ?hogwartsTestUser.setUpdateTime(new Date());
? ? ? ?hogwartsTestUserMapper.insertUseGeneratedKeys(hogwartsTestUser);
? ? ? ?return hogwartsTestUser;
? ?}
? ?/**
? ? * 更新
? ? *
? ? * @param hogwartsTestUser
? ? * @return
? ? */
? ?@Override
? ?public HogwartsTestUser update(HogwartsTestUser hogwartsTestUser) {
? ? ? ?hogwartsTestUser.setCreateTime(new Date());
? ? ? ?hogwartsTestUser.setUpdateTime(new Date());
? ? ? ?hogwartsTestUserMapper.updateByPrimaryKeySelective(hogwartsTestUser);
? ? ? ?return hogwartsTestUser;
? ?}
? ?/**
? ? * 根據(jù)用戶名查詢
? ? *
? ? * @param hogwartsTestUser
? ? * @return
? ? */
? ?@Override
? ?public List<HogwartsTestUser> getByName(HogwartsTestUser hogwartsTestUser) {
? ? ? ?List<HogwartsTestUser> hogwartsTestUserList = hogwartsTestUserMapper.select(hogwartsTestUser);
? ? ? ?return hogwartsTestUserList;
? ?}
? ?/**
? ? * 根據(jù)用戶id刪除用戶信息
? ? *
? ? * @param userId
? ? * @return
? ? */
? ?@Override
? ?public Integer delete(Integer userId) {
? ? ? ?HogwartsTestUser hogwartsTestUser = new HogwartsTestUser();
? ? ? ?hogwartsTestUser.setId(userId);
? ? ? ?hogwartsTestUserMapper.delete(hogwartsTestUser);
? ? ? ?return userId;
? ?}
}
使用 Postman 測試增刪改查
新增
POST?http://127.0.0.1:8081/hogwartsUser/register
請求參數(shù)
{
?"userName": "霍格沃茲test123",
?"password": "test123"
}
響應(yīng)參數(shù)
{
?"id": 15,
?"userName": "霍格沃茲test123",
?"password": "test123",
?"email": null,
?"autoCreateCaseJobName": null,
?"startTestJobName": null,
?"defaultJenkinsId": null,
?"createTime": "2021-04-14T09:37:58.358+00:00",
?"updateTime": "2021-04-14T09:37:58.358+00:00"
}
查詢
GET?http://127.0.0.1:8081/hogwartsUser/byName?userName=霍格沃茲test123
請求參數(shù)
見請求地址中 userName =霍格沃茲test123
響應(yīng)參數(shù)
[
?{
? ?"id": 15,
? ?"userName": "霍格沃茲test123",
? ?"password": "test123",
? ?"email": null,
? ?"autoCreateCaseJobName": null,
? ?"startTestJobName": null,
? ?"defaultJenkinsId": null,
? ?"createTime": "2021-04-14T09:37:58.000+00:00",
? ?"updateTime": "2021-04-14T09:37:58.000+00:00"
?}
]
修改
PUT?http://127.0.0.1:8081/hogwartsUser
請求參數(shù)
{
?"id": 15,
?"userName": "霍格沃茲test12345",
?"password": "test123"
}
響應(yīng)參數(shù)
{
?"id": 15,
?"userName": "霍格沃茲test12345",
?"password": "test123",
?"email": null,
?"autoCreateCaseJobName": null,
?"startTestJobName": null,
?"defaultJenkinsId": null,
?"createTime": "2021-04-14T09:43:45.018+00:00",
?"updateTime": "2021-04-14T09:43:45.018+00:00"
}
刪除
DELETE?http://127.0.0.1:8081/hogwartsUser/15
請求參數(shù)
見請求地址中15
響應(yīng)參數(shù)
15
數(shù)據(jù)持久化技術(shù)就先講到這里啦~大家要多練習(xí)哦,才能學(xué)的更扎實(shí)。
可以互相分享哦