柚子快報(bào)邀請(qǐng)碼778899分享:數(shù)據(jù)庫(kù) MyBatis 詳解
柚子快報(bào)邀請(qǐng)碼778899分享:數(shù)據(jù)庫(kù) MyBatis 詳解
MyBatis查詢(xún)數(shù)據(jù)庫(kù)
MyBatis 是什么?
MyBatis 是更簡(jiǎn)單完成程序和數(shù)據(jù)庫(kù)交互的?具,也就是更簡(jiǎn)單的操作和讀取數(shù)據(jù)庫(kù)?具。 MyBatis 是?款優(yōu)秀的持久層框架,它?持?定義 SQL、存儲(chǔ)過(guò)程以及?級(jí)映射。MyBatis 去除了? 乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的?作。MyBatis 可以通過(guò)簡(jiǎn)單的 XML 或注解來(lái)配置 和映射原始類(lèi)型、接?和 Java POJO(Plain Old Java Objects,普通?式 Java 對(duì)象)為數(shù)據(jù)庫(kù)中的記錄。
JDBC 的操作流程:
創(chuàng)建數(shù)據(jù)庫(kù)連接池 DataSource通過(guò) DataSource 獲取數(shù)據(jù)庫(kù)連接 Connection編寫(xiě)要執(zhí)?帶 ? 占位符的 SQL 語(yǔ)句通過(guò) Connection 及 SQL 創(chuàng)建操作命令對(duì)象 Statement替換占位符:指定要替換的數(shù)據(jù)庫(kù)字段類(lèi)型,占位符索引及要替換的值 6. 使? Statement 執(zhí)? SQL 語(yǔ)句查詢(xún)操作:返回結(jié)果集 ResultSet,更新操作:返回更新的數(shù)量處理結(jié)果集釋放資源
對(duì)于 JDBC 來(lái)說(shuō),整個(gè)操作?常的繁瑣,我們不但要拼接每?個(gè)參 數(shù),?且還要按照模板代碼的?式,?步步的操作數(shù)據(jù)庫(kù),并且在每次操作完,還要?動(dòng)關(guān)閉連接等, ?所有的這些操作步驟都需要在每個(gè)?法中重復(fù)書(shū)寫(xiě)。
MyBatis 在整個(gè)框架中的定位,框架交互流程圖:
MyBatis 也是?個(gè) ORM 框架,ORM(Object Relational Mapping),即對(duì)象關(guān)系映射。在?向 >對(duì)象編程語(yǔ)?中,將關(guān)系型數(shù)據(jù)庫(kù)中的數(shù)據(jù)與對(duì)象建?起映射關(guān)系,進(jìn)??動(dòng)的完成數(shù)據(jù)與對(duì)象 >的互相轉(zhuǎn)換:
將輸?數(shù)據(jù)(即傳?對(duì)象)+SQL 映射成原? SQL將結(jié)果集映射為返回對(duì)象,即輸出對(duì)象 ORM 把數(shù)據(jù)庫(kù)映射為對(duì)象: 數(shù)據(jù)庫(kù)表(table)–> 類(lèi)(class) 記錄(record,?數(shù)據(jù))–> 對(duì)象(object) 字段(field) --> 對(duì)象的屬性(attribute) ?般的 ORM 框架,會(huì)將數(shù)據(jù)庫(kù)模型的每張表都映射為?個(gè) Java 類(lèi)。也就是說(shuō)使? MyBatis 可以像操作對(duì)象?樣來(lái)操作數(shù)據(jù)庫(kù)中的表,可以實(shí)現(xiàn)對(duì)象和數(shù)據(jù)庫(kù)表之間 的轉(zhuǎn)換。
MyBatis的基本使用
創(chuàng)建數(shù)據(jù)庫(kù)和表
-- 創(chuàng)建數(shù)據(jù)庫(kù)
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;
-- 使?數(shù)據(jù)數(shù)據(jù) use mycnblog;
-- 創(chuàng)建表[?戶(hù)表]
drop table if exists userinfo;
create table userinfo(
id int primary key auto_increment,
username varchar(100) not null,
password varchar(32) not null,
photo varchar(500) default '',
createtime datetime default now(),
updatetime datetime default now(),
`state` int default 1
) default charset 'utf8mb4';
-- 創(chuàng)建?章表
drop table if exists articleinfo;
create table articleinfo(
id int primary key auto_increment,
title varchar(100) not null,
content text not null,
createtime datetime default now(),
updatetime datetime default now(),
uid int not null,
rcount int not null default 1,
`state` int default 1
)default charset 'utf8mb4';
-- 創(chuàng)建視頻表
drop table if exists videoinfo;
create table videoinfo(
vid int primary key,
`title` varchar(250),
`url` varchar(1000),
createtime datetime default now(),
updatetime datetime default now(),
uid int
)default charset 'utf8mb4';
-- 添加?個(gè)?戶(hù)信息
INSERT INTO `mycnblog`.`userinfo` (`id`, `username`, `password`, `photo`, `createtime`, `updatetime`, `state`) VALUES
(1, 'admin', 'admin', '', '2021-12-06 17:10:48', '2021-12-06 17:10:48', 1)
;
-- ?章添加測(cè)試數(shù)據(jù)
insert into articleinfo(title,content,uid)
values('Java','Java正?',1);
-- 添加視頻
insert into videoinfo(vid,title,url,uid) values(1,'java title','http://ww w.baidu.com',1);
添加MyBatis框架?持
?項(xiàng)?添加MyBatis
添加框架?持:
使?EditStarters插件快速添加:
新項(xiàng)?添加MyBatis 新項(xiàng)?創(chuàng)建 Spring Boot 項(xiàng)?的時(shí)候添加引?就可以了。
配置連接字符串和MyBatis
配置連接字符串 在application.yml 添加如下內(nèi)容:
如果使? mysql-connector-java 是 5.x 之前的使?的是“com.mysql.jdbc.Driver”,如果是?于 5.x 使?的是“com.mysql.cj.jdbc.Driver”
# 數(shù)據(jù)庫(kù)連接配置
spring:
datasource:
url: jdbc:mysql://localhost:3306/mycnblog?characterEncoding=utf8&useSSL =false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver
配置 MyBatis 中的 XML 路徑
# 配置 mybatis xml 的?件路徑,在 resources/mapper 創(chuàng)建所有表的 xml ?件 mybatis:
mapper-locations: classpath:mapper/**Mapper.xml
添加業(yè)務(wù)代碼
后端開(kāi)發(fā)的工程思路:
添加實(shí)體類(lèi)
import lombok.Data;
import java.util.Date;
@Data
public class User {
private Integer id;
private String username;
private String password;
private String photo;
private Date createTime;
private Date updateTime;
}
添加 mapper 接?
import org.apache.ibatis.annotations.Mapper; import java.util.List;
@Mapper
public interface UserMapper {
public List
}
添加 UserMapper.xml
UserMapper.xml 查詢(xún)所有?戶(hù)的具體實(shí)現(xiàn) SQL:
select * from userinfo
名,包括全包名.類(lèi)名。
id:是和 Interface(接?)中定義的?法名稱(chēng)?樣的,表示對(duì)接?的具體實(shí)現(xiàn)?法。
resultType:是返回的數(shù)據(jù)類(lèi)型,也就是開(kāi)頭我們定義的實(shí)體類(lèi)。
添加 Service
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
import java.util.List;
@Service
public class UserService {
@Resource
private UserMapper userMapper;
public List
return userMapper.getAll();
}
}
添加 Controller
import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;
import java.util.List;
@RestController
@RequestMapping("/u")
public class UserController {
@Resource
private UserService userService;
@RequestMapping("/getall")
public List
return userService.getAll();
}
}
使? postman 測(cè)試
增、刪、改操作
增加操作
controller 實(shí)現(xiàn)代碼:
@RequestMapping(value = "/add",method = RequestMethod.POST) public Integer add(@RequestBody User user){
return userService.getAdd(user);
}
mapper interface:
Integer add(User user);
mapper.xml
insert into userinfo(username,password,photo,state)
values(#{username},#{password},#{photo},1)
Postman 添加訪問(wèn): 默認(rèn)情況下返回的是受影響的?數(shù)。
{"username":"mysql","password":"mysql","photo":"img.png"}
返回?增 id
controller 實(shí)現(xiàn)代碼:
@RequestMapping(value = "/add2", method = RequestMethod.POST) public Integer add2(@RequestBody User user) {
userService.getAdd2(user);
return user.getId();
}
mapper 接?:
@Mapper
public interface UserMapper {
// 添加,返回?增id
void add2(User user);
}
mapper.xml 實(shí)現(xiàn)如下:
insert into userinfo(username,password,photo,state)
values(#{username},#{password},#{photo},1)
useGeneratedKeys:這會(huì)令 MyBatis 使? JDBC 的 getGeneratedKeys ?法來(lái)取出由數(shù)據(jù) 庫(kù)內(nèi)部?成的主鍵(?如:像 MySQL 和 SQL Server 這樣的關(guān)系型數(shù)據(jù)庫(kù)管理系統(tǒng)的?動(dòng) 遞增字段),默認(rèn)值:false。keyColumn:設(shè)置?成鍵值在表中的列名,在某些數(shù)據(jù)庫(kù)(像 PostgreSQL)中,當(dāng)主鍵列 不是表中的第?列的時(shí)候,是必須設(shè)置的。如果?成列不??個(gè),可以?逗號(hào)分隔多個(gè)屬性 名稱(chēng)。keyProperty:指定能夠唯?識(shí)別對(duì)象的屬性,MyBatis 會(huì)使? getGeneratedKeys 的返回 值或 insert 語(yǔ)句的 selectKey ?元素設(shè)置它的值,默認(rèn)值:未設(shè)置(unset)。如果?成列 不??個(gè),可以?逗號(hào)分隔多個(gè)屬性名稱(chēng)。
postman 返回結(jié)果:
修改?戶(hù)操作
controller:
/**
* 修改操作
*
* @param id
* @param name
* @return
*/
@RequestMapping("/update")
public Integer update(Integer id, String name) {
return userService.update(id, name);
}
mapper.xml 實(shí)現(xiàn)代碼:
update userinfo set username=#{name} where id=#{id}
刪除?戶(hù)操作
delete from userinfo where id=#{id}
查詢(xún)操作詳解
參數(shù)占位符 #{} 和 ${}
#{}:預(yù)編譯處理。${}:字符直接替換。
預(yù)編譯處理是指:MyBatis 在處理#{}時(shí),會(huì)將 SQL 中的 #{} 替換為?號(hào),使? PreparedStatement 的 set ?法來(lái)賦值。直接替換:是MyBatis 在處理 ${} 時(shí),就是把 ${} 替換成變量的值。
使? ${sort} 可以實(shí)現(xiàn)排序查詢(xún),?使? #{sort} 就不能實(shí)現(xiàn)排序查詢(xún)了,因?yàn)楫?dāng)使? #{sort} 查詢(xún)時(shí), 如果傳遞的值為 String 則會(huì)加單引號(hào),就會(huì)導(dǎo)致 sql 錯(cuò)誤。
SQL 注?問(wèn)題
select * from userinfo where username='${name}' and password='${pwd}'
sql 注?代碼:“’ or 1='1”
單表查詢(xún)
?于查詢(xún)的字段,盡量使? #{} 預(yù)查詢(xún)的?式。 Controller 實(shí)現(xiàn)代碼如下:
@RequestMapping("/getuser")
public User getUserById(Integer id) {
return userService.getUserById(id);
}
Mapper.xml 實(shí)現(xiàn)代碼如下:
select * from userinfo where id=#{id}
like 查詢(xún)
like 使? #{} 報(bào)錯(cuò),相當(dāng)于: select * from userinfo where username like ‘%‘username’%’。
select * from userinfo where username like '%#{username}%';
使? mysql 的內(nèi)置函數(shù) concat() 來(lái)處理:
select * from userinfo where username like concat('%',#{usernam e},'%');
多表查詢(xún)
返回值類(lèi)型
如果是增、刪、改返回搜影響的?數(shù),那么在 mapper.xml 中是可以不設(shè)置返回的類(lèi)型的。
查詢(xún)不設(shè)置返回類(lèi)型會(huì)報(bào)錯(cuò): controller 代碼:
@RequestMapping("/getname")
public String getNameById(Integer id) {
return userService.getNameById(id);
}
mapper.xml 實(shí)現(xiàn)代碼:
select username from userinfo where id=#{id}
訪問(wèn)接?執(zhí)?結(jié)果顯示運(yùn)?了?個(gè)查詢(xún)但沒(méi)有找到結(jié)果映射:
查詢(xún)標(biāo)簽來(lái)說(shuō)?少需要兩個(gè)屬性: id 屬性:?于標(biāo)識(shí)實(shí)現(xiàn)接?中的那個(gè)?法; 結(jié)果映射屬性:
結(jié)果映射有兩種實(shí)現(xiàn)標(biāo)簽: 和 。
resultType
絕?數(shù)查詢(xún)場(chǎng)景可以使? resultType 進(jìn)?返回,使??便,直接定義到某個(gè)實(shí)體類(lèi)即可。
select username from userinfo where id=#{id}
resultMap
字段名稱(chēng)和程序中的屬性名不同的情況,可使? resultMap 配置映射; ?對(duì)?和?對(duì)多關(guān)系可以使? resultMap 映射并查詢(xún)數(shù)據(jù)。
字段名和屬性名不同的情況 程序中的屬性: mapper.xml 代碼:
select * from userinfo where id=#{id}
使用resultType查詢(xún)的結(jié)果: 使用resultMap查詢(xún): mapper.xml:
select * from userinfo where id=#{id}
查詢(xún)結(jié)果:
多表查詢(xún)
在多表查詢(xún)時(shí),如果使? resultType 標(biāo)簽,在?個(gè)類(lèi)中包含了另?個(gè)對(duì)象是查詢(xún)不出來(lái)被包含的對(duì)象的 實(shí)體類(lèi):
@Data
public class ArticleInfo {
private Integer id;
private String title;
private String content;
private LocalDateTime createtime;
private LocalDateTime updatetime;
private Integer rcount;
// 包含了 userinfo 對(duì)象
private UserInfo user;
}
程序的執(zhí)?結(jié)果:
?對(duì)?的表映射
?對(duì)?映射要使? 標(biāo)簽,具體實(shí)現(xiàn)(?篇?章只對(duì)應(yīng)?個(gè)作者):
resultMap="com.example.demo.mapper.UserMapper.BaseMap" columnPrefix="u_">
select a.*,u.username u_username from articleinfo a
left join userinfo u on a.uid=u.id
柚子快報(bào)邀請(qǐng)碼778899分享:數(shù)據(jù)庫(kù) MyBatis 詳解
精彩鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場(chǎng)。
轉(zhuǎn)載請(qǐng)注明,如有侵權(quán),聯(lián)系刪除。