柚子快報(bào)邀請碼778899分享:數(shù)據(jù)庫 MyBatis 詳解
柚子快報(bào)邀請碼778899分享:數(shù)據(jù)庫 MyBatis 詳解
MyBatis查詢數(shù)據(jù)庫
MyBatis 是什么?
MyBatis 是更簡單完成程序和數(shù)據(jù)庫交互的?具,也就是更簡單的操作和讀取數(shù)據(jù)庫?具。 MyBatis 是?款優(yōu)秀的持久層框架,它?持?定義 SQL、存儲(chǔ)過程以及?級映射。MyBatis 去除了? 乎所有的 JDBC 代碼以及設(shè)置參數(shù)和獲取結(jié)果集的?作。MyBatis 可以通過簡單的 XML 或注解來配置 和映射原始類型、接?和 Java POJO(Plain Old Java Objects,普通?式 Java 對象)為數(shù)據(jù)庫中的記錄。
JDBC 的操作流程:
創(chuàng)建數(shù)據(jù)庫連接池 DataSource通過 DataSource 獲取數(shù)據(jù)庫連接 Connection編寫要執(zhí)?帶 ? 占位符的 SQL 語句通過 Connection 及 SQL 創(chuàng)建操作命令對象 Statement替換占位符:指定要替換的數(shù)據(jù)庫字段類型,占位符索引及要替換的值 6. 使? Statement 執(zhí)? SQL 語句查詢操作:返回結(jié)果集 ResultSet,更新操作:返回更新的數(shù)量處理結(jié)果集釋放資源
對于 JDBC 來說,整個(gè)操作?常的繁瑣,我們不但要拼接每?個(gè)參 數(shù),?且還要按照模板代碼的?式,?步步的操作數(shù)據(jù)庫,并且在每次操作完,還要?動(dòng)關(guān)閉連接等, ?所有的這些操作步驟都需要在每個(gè)?法中重復(fù)書寫。
MyBatis 在整個(gè)框架中的定位,框架交互流程圖:
MyBatis 也是?個(gè) ORM 框架,ORM(Object Relational Mapping),即對象關(guān)系映射。在?向 >對象編程語?中,將關(guān)系型數(shù)據(jù)庫中的數(shù)據(jù)與對象建?起映射關(guān)系,進(jìn)??動(dòng)的完成數(shù)據(jù)與對象 >的互相轉(zhuǎn)換:
將輸?數(shù)據(jù)(即傳?對象)+SQL 映射成原? SQL將結(jié)果集映射為返回對象,即輸出對象 ORM 把數(shù)據(jù)庫映射為對象: 數(shù)據(jù)庫表(table)–> 類(class) 記錄(record,?數(shù)據(jù))–> 對象(object) 字段(field) --> 對象的屬性(attribute) ?般的 ORM 框架,會(huì)將數(shù)據(jù)庫模型的每張表都映射為?個(gè) Java 類。也就是說使? MyBatis 可以像操作對象?樣來操作數(shù)據(jù)庫中的表,可以實(shí)現(xiàn)對象和數(shù)據(jù)庫表之間 的轉(zhuǎn)換。
MyBatis的基本使用
創(chuàng)建數(shù)據(jù)庫和表
-- 創(chuàng)建數(shù)據(jù)庫
drop database if exists mycnblog;
create database mycnblog DEFAULT CHARACTER SET utf8mb4;
-- 使?數(shù)據(jù)數(shù)據(jù) use mycnblog;
-- 創(chuàng)建表[?戶表]
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è)?戶信息
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)
;
-- ?章添加測試數(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ù)庫連接配置
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ù)代碼
后端開發(fā)的工程思路:
添加實(shí)體類
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 查詢所有?戶的具體實(shí)現(xiàn) SQL:
select * from userinfo
名,包括全包名.類名。
id:是和 Interface(接?)中定義的?法名稱?樣的,表示對接?的具體實(shí)現(xiàn)?法。
resultType:是返回的數(shù)據(jù)類型,也就是開頭我們定義的實(shí)體類。
添加 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 測試
增、刪、改操作
增加操作
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 添加訪問: 默認(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 ?法來取出由數(shù)據(jù) 庫內(nèi)部?成的主鍵(?如:像 MySQL 和 SQL Server 這樣的關(guān)系型數(shù)據(jù)庫管理系統(tǒng)的?動(dòng) 遞增字段),默認(rèn)值:false。keyColumn:設(shè)置?成鍵值在表中的列名,在某些數(shù)據(jù)庫(像 PostgreSQL)中,當(dāng)主鍵列 不是表中的第?列的時(shí)候,是必須設(shè)置的。如果?成列不??個(gè),可以?逗號分隔多個(gè)屬性 名稱。keyProperty:指定能夠唯?識別對象的屬性,MyBatis 會(huì)使? getGeneratedKeys 的返回 值或 insert 語句的 selectKey ?元素設(shè)置它的值,默認(rèn)值:未設(shè)置(unset)。如果?成列 不??個(gè),可以?逗號分隔多個(gè)屬性名稱。
postman 返回結(jié)果:
修改?戶操作
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}
刪除?戶操作
delete from userinfo where id=#{id}
查詢操作詳解
參數(shù)占位符 #{} 和 ${}
#{}:預(yù)編譯處理。${}:字符直接替換。
預(yù)編譯處理是指:MyBatis 在處理#{}時(shí),會(huì)將 SQL 中的 #{} 替換為?號,使? PreparedStatement 的 set ?法來賦值。直接替換:是MyBatis 在處理 ${} 時(shí),就是把 ${} 替換成變量的值。
使? ${sort} 可以實(shí)現(xiàn)排序查詢,?使? #{sort} 就不能實(shí)現(xiàn)排序查詢了,因?yàn)楫?dāng)使? #{sort} 查詢時(shí), 如果傳遞的值為 String 則會(huì)加單引號,就會(huì)導(dǎo)致 sql 錯(cuò)誤。
SQL 注?問題
select * from userinfo where username='${name}' and password='${pwd}'
sql 注?代碼:“’ or 1='1”
單表查詢
?于查詢的字段,盡量使? #{} 預(yù)查詢的?式。 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 查詢
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() 來處理:
select * from userinfo where username like concat('%',#{usernam e},'%');
多表查詢
返回值類型
如果是增、刪、改返回搜影響的?數(shù),那么在 mapper.xml 中是可以不設(shè)置返回的類型的。
查詢不設(shè)置返回類型會(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}
訪問接?執(zhí)?結(jié)果顯示運(yùn)?了?個(gè)查詢但沒有找到結(jié)果映射:
查詢標(biāo)簽來說?少需要兩個(gè)屬性: id 屬性:?于標(biāo)識實(shí)現(xiàn)接?中的那個(gè)?法; 結(jié)果映射屬性:
結(jié)果映射有兩種實(shí)現(xiàn)標(biāo)簽: 和 。
resultType
絕?數(shù)查詢場景可以使? resultType 進(jìn)?返回,使??便,直接定義到某個(gè)實(shí)體類即可。
select username from userinfo where id=#{id}
resultMap
字段名稱和程序中的屬性名不同的情況,可使? resultMap 配置映射; ?對?和?對多關(guān)系可以使? resultMap 映射并查詢數(shù)據(jù)。
字段名和屬性名不同的情況 程序中的屬性: mapper.xml 代碼:
select * from userinfo where id=#{id}
使用resultType查詢的結(jié)果: 使用resultMap查詢: mapper.xml:
select * from userinfo where id=#{id}
查詢結(jié)果:
多表查詢
在多表查詢時(shí),如果使? resultType 標(biāo)簽,在?個(gè)類中包含了另?個(gè)對象是查詢不出來被包含的對象的 實(shí)體類:
@Data
public class ArticleInfo {
private Integer id;
private String title;
private String content;
private LocalDateTime createtime;
private LocalDateTime updatetime;
private Integer rcount;
// 包含了 userinfo 對象
private UserInfo user;
}
程序的執(zhí)?結(jié)果:
?對?的表映射
?對?映射要使? 標(biāo)簽,具體實(shí)現(xiàn)(?篇?章只對應(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)邀請碼778899分享:數(shù)據(jù)庫 MyBatis 詳解
精彩鏈接
本文內(nèi)容根據(jù)網(wǎng)絡(luò)資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點(diǎn)和立場。
轉(zhuǎn)載請注明,如有侵權(quán),聯(lián)系刪除。