1. MybatisPlus
1.1 業務需求
Mybatis缺點:
- 1.Mybatis操作數據庫的過程中,需要編輯大量的sql語句.無論該sql是否複雜或者簡單.
- 2.Mybatis操作時在xml配置文件中需要額外記憶單獨的標籤.
需求:能否實現單表操作的CRUD的全自動的實現.能否實現真正的ORM映射?
1.2ORM
要求:利用面向對象的方式操作數據庫 特點: 1.操作數據庫的面向對象.
userMapper.insert(user對象); ------->自己編輯sql語句
2.查詢數據庫的面向對象.
userMapper.selectByWhere(user對象); ------>動態的生成Sql------>自動實現結果集封裝.
1.3ORM實現單表操作原理
要求:實現單表的自動的CRUD操作 例子:
<code> User user = new Uesr();
• user.setId(xx).setName(xx).setAge(xx).setSex(xx);
• userMapper.insertUser(user);
/<code>
框架內部實現過程:
核心:數據庫只能識別sql語句.框架需要將對象轉化為sql.
核心配置:
1.User對象與數據庫的表 一一映射!
解決方法: 自定義註解標識表與對象的關係
2.User對象的屬性與數據表中的字段一一映射!
解決方法:自定義註解完成屬性與字段的映射
3.將CURD的方法進行統一的定義.形成工具API接口
解決方法:利用公共的mapper接口 BaseMapper,在其中定義幾乎所有的單表的CURD操作.
4.將接口方法按照數據庫方式轉化為特定的sql語句.
1.用戶的調用 userMapper.insert(user)
2.拼接特定的sql:
insert into 表名(字段名......) values(屬性值......);
一般利用反射技術,可以通過對象或者有關對象的全部信息(註解,屬性,屬性值)
1.4 MybatisPlus介紹(MP)
MyBatis-Plus(簡稱 MP)是一個 MyBatis 的增強工具,在 MyBatis 的基礎上只做增強不做改變,為簡化開發、提高效率而生。
1.5 MybatisPlus特性
- 無侵入:只做增強不做改變,引入它不會對現有工程產生影響,如絲般順滑
- 損耗小:啟動即會自動注入基本 CURD,性能基本無損耗,直接面向對象操作
- 強大的 CRUD 操作:內置通用 Mapper、通用 Service,僅僅通過少量配置即可實現單表大部分 CRUD 操作,更有強大的條件構造器,滿足各類使用需求
- 支持 Lambda 形式調用:通過 Lambda 表達式,方便的編寫各類查詢條件,無需再擔心字段寫錯
- 支持主鍵自動生成:支持多達 4 種主鍵策略(內含分佈式唯一 ID 生成器 - Sequence),可自由配置,完美解決主鍵問題
- 支持 ActiveRecord 模式:支持 ActiveRecord 形式調用,實體類只需繼承 Model 類即可進行強大的 CRUD 操作
- 支持自定義全局通用操作:支持全局通用方法注入( Write once, use anywhere )
- 內置代碼生成器:採用代碼或者 Maven 插件可快速生成 Mapper 、 Model 、 Service 、 Controller 層代碼,支持模板引擎,更有超多自定義配置等您來使用
- 內置分頁插件:基於 MyBatis 物理分頁,開發者無需關心具體操作,配置好插件之後,寫分頁等同於普通 List 查詢
- 分頁插件支持多種數據庫:支持 MySQL、MariaDB、Oracle、DB2、H2、HSQL、SQLite、Postgre、SQLServer 等多種數據庫
- 內置性能分析插件:可輸出 Sql 語句以及其執行時間,建議開發測試時啟用該功能,能快速揪出慢查詢
- 內置全局攔截插件:提供全表 delete 、 update 操作智能分析阻斷,也可自定義攔截規則,預防誤操作
1.6 MybatisPlus的實際入門操作
1.6.1導入jar包
==最主要的jar包==
<code>
<dependency>
<groupid>com.baomidou/<groupid>
<artifactid>mybatis-plus-boot-starter/<artifactid>
<version>3.2.0/<version>
/<dependency>
/<code>
==本次所需的其餘jar包==
<code> <dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-web/<artifactid>
/<dependency>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-starter-test/<artifactid>
<scope>test/<scope>
/<dependency>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-configuration-processor/<artifactid>
<optional>true/<optional>
/<dependency>
<dependency>
<groupid>org.projectlombok/<groupid>
<artifactid>lombok/<artifactid>
/<dependency>
<dependency>
<groupid>org.springframework.boot/<groupid>
<artifactid>spring-boot-devtools/<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-jdbc/<artifactid>
/<dependency>
/<code>
注意如果沒有lombok插件可以在 https://blog.csdn.net/XING_Gou/article/details/104316560中安裝Lombok插件
<code>package com.jt.demo.pojo;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;
import lombok.experimental.Accessors;
@Data
@Accessors(chain=true) //鏈式加載
@TableName //標識對象與表之間的關聯關係
public class User {
//簡化步驟:如果屬性的名稱與映射的名稱一致,則可以省略不寫
@TableId(type=IdType.AUTO) //定義主鍵 主鍵自增
private Integer id;
//對象的屬性與表中的字段.
//@TableField(value="name")
private String name;
private Integer age;
private String sex;
}
/<code>
數據庫
<code>DROP DATABASE IF EXISTS `jtdb`;
CREATE DATABASE `jtdb` DEFAULT CHARACTER SET utf8;
USE `jtdb`;
/*Table structure for table `user` */
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` char(40) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` char(40) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `cc` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=53 DEFAULT CHARSET=utf8;
/*Data for the table `user` */
insert into `user`(`id`,`name`,`age`,`sex`) values (1,'黑熊精',4000,'男'),(2,'鯉魚精',5000,'男'),(3,'金角大王',3000,'男'),(4,'銀角大王',4000,'男'),(5,'唐僧',30,'男'),(6,'悟空',501,'男'),(7,'白龍驢',2000,'男'),(8,'八戒',502,'男'),(9,'沙悟淨',503,'男'),(11,'小喬',17,'女'),(12,'貂蟬',18,'女'),(16,'黃月英',18,'女'),(17,'孫尚香',18,'女'),(18,'甄姬c',20,'女'),(21,'孫尚香D',18,'女'),(22,'劉備',40,'男'),(23,'陸遜',33,'男'),(24,'陸遜',33,'男'),(25,'關羽',40,'男'),(27,'阿科',20,'女'),(31,'王昭君',19,'女'),(38,'貂蟬',18,'女'),(39,'西施',18,'女'),(40,'嚴真煌',16,'女'),(41,'白骨精',18,'女'),(43,'小喬',19,'男'),(44,'大喬',19,'女'),(46,'不知火舞',18,'女'),(49,'小蘭蘭',18,'男'),(50,'柳鵬林',18,'男'),(51,'妲己',18,'男'),(52,'如花',17,'男');
/<code>
6.3 繼承共同的API接口
<code>public interface UserMapper extends BaseMapper<user>{...}
/<user>/<code>
<code>server:
port: 8090 #標識端口號信息
servlet:
context-path: /
spring:
datasource:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://127.0.0.1:3306/jtdb?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=utf8&autoReconnect=true&allowMultiQueries=true
username: root
password: root
#SpringBoot整合Mybatis-plus配置信息
mybatis-plus:
#定義別名包 只要定義了別名包,則程序中resultType可以省略包路徑
type-aliases-package: com.jt.demo.pojo
#配置文件的資源加載路徑
mapper-locations: classpath:/mybatis/mappers/*.xml
#開啟駝峰映射
configuration:
map-underscore-to-camel-case: true
/<code>
6.5 入門案例測試
<code>@RunWith(SpringRunner.class) //注意測試文件的位置 必須在主文件加載包路徑下
@SpringBootTest
public class TestMP {
//注入mapper接口
@Autowired
private UserMapper userMapper;
/**
* 1.入門案例
* 要求:查詢全部的用戶信息 不需要寫where條件
* 注意事項:利用MP的方法和自己的接口方法 名稱不能重複.
*
* 參數說明:queryWrapper 動態生成sql語句中的where條件
*/
@Test
public void test01() {
List<user> userList = userMapper.selectList(null);
System.out.println(userList);
}
}
/<user>/<code>
1.7Mybatis案例
1.selectBatchIds
<code> /**
* 練習1: 查詢id信息為1,3,4,5,6用戶數據
* sql: select * from user where id in (1,2,3,4,5,6);
* 思考:id可以利用數組進行接收 利用數組查詢數據
*/
@Test
public void test02() {
List<integer> idList = new ArrayList<integer>();
idList.add(1);
idList.add(3);
idList.add(4);
idList.add(5);
idList.add(6);
//以對象的方式進行數據庫操作
List<user> userList = userMapper.selectBatchIds(idList);
System.out.println(userList);
}
/<user>/<integer>/<integer>/<code>
2. selectByMap
說明:根據字段查詢用戶信息
<code> /**
* 練習2: 根據name="黑熊精" age="3000"查詢數據信息
* SelectByMap:根據具體的字段查詢用戶信息.
* sql語句: select * from user where name="黑熊精" and age=3000
* 規則:默認使用and連接符.
*/
@Test
public void test03() {
Map<string> map = new HashMap<>();
//key="字段名稱" value="字段值"
map.put("name", "黑熊精");
map.put("age", 3000);
List<user> userList = userMapper.selectByMap(map);
System.out.println(userList);
}
/<user>/<string>/<code>
3. 條件構造器查詢
<code>/**
* 4.name屬性中包含"精"的數據,並且為女性
* sql: SELECT * FROM USER WHERE NAME LIKE "%精%" AND sex = "女"
* queryWrapper: 條件構造器
* 作用 動態拼接sql的where條件
* 邏輯運算符: >gt ,=ge, <= le /<code>
*/
@Test
public void test04() {
QueryWrapper<user> queryWrapper = new QueryWrapper<>();
queryWrapper.like("name", "精")
.eq("sex", "女");
List<user> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/<user>/<user>
4. Between-and
<code> /**
* 查詢年齡在18-35之間的女性用戶.
* sql: SELECT * FROM USER WHERE age BETWEEN 18 AND 35 AND sex ="女";
*/
@Test
public void test05() {
QueryWrapper<user> queryWrapper = new QueryWrapper<>();
queryWrapper.between("age", 18, 35)
.eq("sex", "女");
List<user> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/<user>/<user>/<code>
5. order by
<code>/**
* 條件: 查詢年齡大於100歲的,並且按照年齡降序排列,
* 如果年齡相同按照Id降序排列.
* sql:SELECT * FROM USER WHERE age > 100 ORDER BY age DESC,id DESC;
*/
@Test
public void test06() {
QueryWrapper<user> queryWrapper = new QueryWrapper<>();
queryWrapper.gt("age", 100)
.orderByDesc("age","id");
List<user> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/<user>/<user>/<code>
6. like練習
<code>/**
* 條件: 查詢名稱以"喬"結尾的,並且性別為女,並且age小於30歲.按照年齡降序排列.
* SQL:
* SELECT * FROM USER WHERE (NAME LIKE "%喬" AND sex="女"
AND age < 30) ORDER BY age DESC;
*/
@Test
public void test07(){
QueryWrapper<user> queryWrapper = new QueryWrapper<>();
queryWrapper.likeLeft("name","喬")
.eq("sex", "女")
.lt("age", 30)
.orderByDesc("age");
List<user> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/<user>/<user>/<code>
7.inSql
說明:適用於子查詢
<code>/**
* 查詢age < 100歲的用戶,並且性別與name="孫尚香"的性別相同的的用戶數據.
* 分析: age<100 sex=男/女
* sql:SELECT * FROM USER WHERE age < 100 AND
sex in(
SELECT sex FROM USER WHERE NAME = "孫尚香"
)
*/
@Test
public void test08(){
QueryWrapper<user> queryWrapper = new QueryWrapper<>();
queryWrapper.lt("age",100)
.inSql("sex", "select sex from user where name ='孫尚香'");
List<user> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/<user>/<user>/<code>
8.select
<code>/**
* 需求: 有時可能不需要查詢全部的數據庫的表字段
* 查詢age為18歲的用戶的名稱和id.
* select:挑選字段的屬性.
* 查詢結果:User(id=12, name=貂蟬, age=null, sex=null)
*/
@Test
public void test09() {
QueryWrapper<user> queryWrapper = new QueryWrapper<>();
queryWrapper.select("name","id")
.eq("age", 18);
List<user> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/<user>/<user>/<code>
9.condition
<code>/**
* 條件判斷
* 以name和sex不為null的數據當做where條件.
* condition作用:
* 判斷參數是否拼接為where條件
* 結果true, 動態拼接參數
* 結果false, 參數不會動態拼接
* 應用場景:
* 接收前臺的參數時,參數可能為null或者其他的數值類型時
* 需要添加判斷.
* 業務需求:
* 如果age>18時,才能查詢年齡
*/
@Test
public void test10() {
String name = null;
int age = 18;
QueryWrapper<user> queryWrapper = new QueryWrapper<>();
//name屬性的值,不為null時,才會拼接where條件
queryWrapper.eq(!StringUtils.isEmpty(name), "name", name);
queryWrapper.eq(age>18, "age", age);
List<user> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/<user>/<user>/<code>
10. 根據對象查詢
<code>/**
* 根據對象查詢數據庫
* 條件:根據對象中不為null的屬性充當where條件
* 需求:查詢age=18的用戶信息 性別=女
* 說明:利用對象的方式查詢時,邏輯運算符都是"="號
*/
@Test
public void test11() {
User user = new User();
user.setAge(18)
.setSex("女");
QueryWrapper<user> queryWrapper = new QueryWrapper<>(user);
List<user> userList = userMapper.selectList(queryWrapper);
System.out.println(userList);
}
/<user>/<user>/<code>
11. selectObjs
說明:只查詢主鍵信息(第一列)數據
<code>/**
* 需求:只查詢主鍵的信息.
* 類比: select
* sql: SELECT id FROM USER where age >18
*/
@Test
public void test12() {
QueryWrapper<user> queryWrapper2 = new QueryWrapper<user>();
queryWrapper2.select("id");
//查詢的List<user>對象信息
userMapper.selectList(queryWrapper2);
QueryWrapper<user> queryWrapper = new QueryWrapper<user>();
queryWrapper.gt("age", 18);
//只查詢主鍵信息
List<object> idList = userMapper.selectObjs(queryWrapper);
System.out.println(idList);
}
/<object>/<user>/<user>/<user>/<user>/<user>/<code>
12.selectMaps
說明:獲取任意字段的數據信息
<code>/**
* 獲取任意的字段信息
* 需求:查詢用戶信息 只想獲取id和name的值.不想獲取age/sex
* sql: select id,name from user where age > 18;
*/
@Test
public void test13() {
QueryWrapper<user> queryWrapper = new QueryWrapper<user>();
queryWrapper.select("id","name")
.gt("age", 18);
//獲取全部的對象信息
List<user> userList = userMapper.selectList(queryWrapper);
//獲取字段的信息
List/<user>/<user>/<user>/<code>
13. 新增用戶
<code>@Test
public void test14() {
User user = new User();
user.setName("外國人永久居住權")
.setSex("男")
.setAge(30);
userMapper.insert(user);
}
/<code>
14.刪除用戶
<code>/**
* 刪除用戶信息
*/
@Test
public void test15() {
QueryWrapper<user> queryWrapper = new QueryWrapper<user>();
queryWrapper.eq("name", "外國人永久居住權");
//根據多個條件 刪除用戶數據.
userMapper.delete(queryWrapper);
//根據集合中的數據.批量刪除用戶信息
Integer[] ids = {2000,2001};
List<integer> idList = Arrays.asList(ids);
userMapper.deleteBatchIds(idList);
//id 代表主鍵信息 根據主鍵進行刪除.
userMapper.deleteById(2000);
//挑選字段和屬性進行刪除.
Map<string> columnMap = new HashMap<string>();
columnMap.put("name", "疫情");
userMapper.deleteByMap(columnMap);
}
/<string>/<string>/<integer>/<user>/<user>/<code>
15. 修改操作
<code> /**
* 更新操作
* updateById: 根據主鍵信息修改數據.
* 主鍵信息必須添加充當where條件,
* 根據對象中不為null的數據,充當set條件.
* sql: update user set name="xx",age=xxx,sex=xx where id=23
*
* update方法說明:
* 參數1:entity 修改後的數據結果
* 參數2:updateWrapper 修改的條件構造器
* 案例:
* 將楊穎改為范冰冰 修改年齡/性別
* sql : update user set name="xxxx",age=xxx,sex=xxx
* where name = "楊穎";
*
*/
@Test
public void test16() {
User user = new User();
user.setId(23).setName("潘鳳").setAge(35).setSex("男");
userMapper.updateById(user);
User user2 = new User();
user2.setName("范冰冰").setAge(40).setSex("女");
UpdateWrapper<user> updateWrapper = new UpdateWrapper<>();
updateWrapper.eq("name", "楊穎");
userMapper.update(user2, updateWrapper);
}
作者: 其樂m
原文:https://my.oschina.net/u/4115134/blog/3190296
/<user>/<code>
閱讀更多 泡泡糖就是糖 的文章