柚子快報邀請碼778899分享:Mybatis基本使用
學習資源: b站:遇見狂神說 鏈接:https://www.bilibili.com/video/BV1NE411Q7Nx/?spm_id_from=333.999.0.0
使用環(huán)境:
jdk1.8mysql5.7maven3.8
1、第一個Mybatis程序
1.1、搭建數據庫
CREATE DATABASE `mybatis`
CREATE TABLE `user` (
`id` INT(20) NOT NULL PRIMARY KEY,
`name` VARCHAR(30) DEFAULT NULL,
`pwd` VARCHAR(30) DEFAULT NULL
)ENGINE=INNODB DEFAULT CHARSET=utf8;
INSERT INTO `user` VALUES
(1,'jack','123'),
(2,'tom','123'),
(3,'smith','123')
1.2、使用idea創(chuàng)建一個maven項目
導入依賴:
1.3、編寫mybatis核心配置文件
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
1.4、創(chuàng)建工具類,獲取sqlSessionFactory對象
package com.yang.utils;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.IOException;
import java.io.InputStream;
public class MybatisUtils {
private static SqlSessionFactory sqlSessionFactory = null;
static {
String resource = "mybatis-config.xml";
try {
// 獲取sqlSessionFactory對象
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 從sqlSessionFactory對象獲取sqlSession實例
* sqlSession:執(zhí)行sql語句的對象
*/
public static SqlSession getSqlSession(){
return sqlSessionFactory.openSession();
}
}
1.5、編寫測試代碼
實體類:
package com.yang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User {
private int id;
private String name;
private String pwd;
}
接口:
package com.yang.dao;
import com.yang.pojo.User;
import java.util.List;
public interface UserMapper {
List
}
接口對應的mapper.xml:
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
select * from user
在mybatis核心配置文件中(configuration標簽內)注冊mapper:
測試:
package com.yang.dao;
import com.yang.pojo.User;
import com.yang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class UserDaoTest {
@Test
public void test(){
// 1獲取sqlSession實例
SqlSession sqlSession = MybatisUtils.getSqlSession();
// 2執(zhí)行sql
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List
for (User user : userList) {
System.out.println(user);
}
}
}
注意:如果mapper.xml定義在resources目錄之外,需要在pom.xml下配置
1.6、總結
步驟:
maven項目下使用mybatis需要在resources目錄下創(chuàng)建一個mybatis的核心配置文件創(chuàng)建數據庫對應的實體類編寫接口接口對應的mapper配置文件中注冊mapper測試
注意點:
注意每一個接口對應一個mapper.xml文件,接口和接口中的方法,在mapper.xml文件中對應在mybatis核心配置文件中注冊對應的mapper使其生效mapper.xml不在resources目錄下創(chuàng)建時,需要處理配置文件之外的載失敗的問題
2、增刪改查
在UserMapper接口下添加方法:
// 根據id查詢用戶
User getUserById(int id);
// 添加一個用戶
int addUser(User user);
// 修改用戶信息
int updateUser(User user);
// 根據id刪除用戶
int deleteUser(int id);
對應的mapper:
select * from user where id = #{id}
insert into user values(#{id},#{name},#{pwd})
update user set name=#{name},pwd=#{pwd} where id=#{id}
delete from user where id=#{id}
測試:
/**
* 刪除用戶
*/
@Test
public void test05(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.deleteUser(4);
sqlSession.commit();
sqlSession.close();
}
/**
* 修改用戶信息
*/
@Test
public void test04(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.updateUser(new User(3,"smith","123"));
sqlSession.commit();
sqlSession.close();
}
/**
* 增加一個用戶
*/
@Test
public void test03(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.addUser(new User(4,"milan","123"));
sqlSession.commit();
sqlSession.close();
}
/**
* 查詢單個用戶
*/
@Test
public void test02(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.getUserById(2);
System.out.println(user);
sqlSession.commit();
sqlSession.close();
}
注意:
傳遞的參數類型是基本數據類型時,可以省略parameterType不寫增刪改操作返回類型都是int,可以省略resultType不寫增刪改操作必須提交事務,否者不成功
3、核心配置文件引入外部配置文件
resources目錄下創(chuàng)建外部配置文件:
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/mybatis?useSSL=true&useUnicode=true&charsetEncoding=UTF-8"
username=root
password=root
核心配置文件中引入外部配置文件:
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
注意:
可以在核心配置文件中引入外部配置文件可以在核心配置文件中增加一些屬性如果核心配置文件和外部配置文件中有共同屬性字段,優(yōu)先使用外部配置文件的
4、別名替代全類名
方式1指定別名(指定具體類):
方式2指定別名(掃描包):
使用方式2指定別名,不適用默認別名情況下,需要單獨設置別名時使用注解@Alias(“別名”)的方式:
package com.yang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import org.apache.ibatis.type.Alias;
@Data
@AllArgsConstructor
@NoArgsConstructor
@Alias("testUser") // 設置別名為testUser
public class User {
private int id;
private String name;
private String pwd;
}
5、映射器
方式1:指定接口對應的mapper配置文件綁定
方式2:接口全類名綁定
方式3:掃描包綁定
注意:使用時需要注意接口和mapper的存放位置
6、生命周期和作用域
6.1、SqlSessionFactoryBuilder
一旦創(chuàng)建了 SqlSessionFactory,就不再需要SqlSessionFactoryBuilder實例因此 SqlSessionFactoryBuilder 實例的最佳作用域是方法作用域(也就是局部方法變量)
6.2、SqlSessionFactory
SqlSessionFactory 一旦被創(chuàng)建就應該在應用的運行期間一直存在使用 SqlSessionFactory 在應用運行期間盡量不要重復創(chuàng)建多次因此 SqlSessionFactory 的最佳作用域是應用作用域
6.3、SqlSession
每個線程都應該有它自己的 SqlSession 實例SqlSession不能被共享,所以它的最佳的作用域是請求或方法作用域每次收到 HTTP 請求,就可以打開一個 SqlSession,返回一個響應后,就關閉它
7、resultMap結果集映射
實體類屬性名為password,數據庫列名為pwd,使用resultMap解決:
select * from user where id = #{id}
8、日志
8.1、mybatis核心配置文件中設置標準的日志實現(xiàn):
在核心配置文件中設置:
8.2、Log4j日志實現(xiàn)
通過Log4j日志可以輸出日志到控制臺,以及指定文件中可以指定輸出日志的格式定義日志信息的級別可以精確控制日志的生成通過配置文件配置,不需要修改程序原有代碼
1、導入log4j依賴:
2、resources目錄下新建log4j.properties配置文件:
### 設置
log4j.rootLogger = debug,stdout,D,E
### 輸出信息到控制臺
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target = System.out
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern = [%-5p] %d{yyyy-MM-dd HH:mm:ss,SSS} method:%l%n%m%n
### 輸出DEBUG 級別以上的日志到=./log/debug.log
log4j.appender.D = org.apache.log4j.DailyRollingFileAppender
log4j.appender.D.File = ./log/debug.log
log4j.appender.D.Append = true
log4j.appender.D.Threshold = DEBUG
log4j.appender.D.layout = org.apache.log4j.PatternLayout
log4j.appender.D.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 輸出ERROR 級別以上的日志到=./log/error.log
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =./log/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
3、編寫測試類:
package com.yang.dao;
import org.apache.log4j.Logger;
import org.junit.Test;
public class Log4jTest {
private static final Logger logger = Logger.getLogger(Log4jTest.class);
@Test
public void testLog4j(){
// 記錄debug級別的信息
logger.debug("This is debug message.");
// 記錄info級別的信息
logger.info("This is info message.");
// 記錄error級別的信息
logger.error("This is error message.");
}
}
4、查看控制臺輸出以及項目路徑下生成目錄和文件記錄的內容
9、Mybatis實現(xiàn)分頁
接口中添加方法:
/**
* 分頁查詢
*/
List
mapper中添加分頁查詢語句:
select * from user limit #{startIndex},#{pageSize}
測試代碼:
@Test
public void test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
// 使用map封裝
Map
map.put("startIndex",0);
map.put("pageSize",3);
List
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
補充:
parameterType接收類型,對應的取值類型
普通類型 int,double …,取值為_int …包裝類型Integer,Double …,取值為 integer … 當parameterType接受的類型是Map,取值時需要和Map的key對應
9、Mybatis注解開發(fā)
Mybatis注解開發(fā)的底層邏輯是使用反射加載接口的結構,進而獲取接口方法(返回類型,泛型,參數等)
使用注解來映射簡單語句會使代碼顯得更加簡潔如果是一些很復雜的操作,最好用 XML 來映射語句簡單的sql語句可以使用注解的方式實現(xiàn),遇到一些復雜的sql語句,盡量使用xml語句的映射方式
接口代碼:
package com.yang.dao;
import com.yang.pojo.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
public interface UserMapper {
@Select("select * from user")
List
}
核心配置文件中配置:
測試:
package com.yang;
import com.yang.dao.UserMapper;
import com.yang.pojo.User;
import com.yang.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;
public class TestUser {
@Test
public void testQueryUsers(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List
for (User user : userList) {
System.out.println(user);
}
sqlSession.close();
}
}
使用注解開發(fā)簡單的CRUD操作:
// 根據id查詢用戶
@Select("select * from user where id = #{uid}")
User getUserById(@Param("uid") Integer id);
// 添加用戶
@Insert("insert into user values (#{id},#{name},#{password})")
int addUser(User user);
// 修改用戶信息
@Update("update user set name=#{name},pwd=#{password} where id=#{id}")
int updateUser(User user);
// 刪除用戶
@Delete("delete from user where id=#{uid}")
int deleteUser(@Param("uid") Integer id);
@Param注解的基本使用說明
傳入單個基本數據類型時,可以不指定@Param注解,默認值為參數名傳入多個基本參數類型時,需要給每個基本類型的參數使用@Param注解執(zhí)行sql預編譯的參數對應的是@Param注解的值,而不是參數名包裝類型不需要指定@Param注解
10、復雜結果集映射
添加數據庫測試數據:
CREATE TABLE `teacher` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `teacher` VALUES(1,'李老師')
CREATE TABLE `student` (
`id` INT(10) NOT NULL,
`name` VARCHAR(30) DEFAULT NULL,
`tid` INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
INSERT INTO `student` VALUES ('1','小明','1');
INSERT INTO `student` VALUES ('2','小強','1');
INSERT INTO `student` VALUES ('3','小紅','1');
INSERT INTO `student` VALUES ('4','小李','1');
INSERT INTO `student` VALUES ('5','小王','1');
teacher對應實體類:
package com.yang.pojo;
import lombok.Data;
@Data
public class Teacher {
private Integer id;
private String name;
}
student對應實體類:
package com.yang.pojo;
import lombok.Data;
@Data
public class Student {
private Integer id;
private String name;
}
10.1、對一關系
這里以一個學生對應一個老師的形式舉例
Student實體中添加對象屬性:
// 一個學生關聯(lián)一個老師
private Teacher teacher;
StudentMapper.xml:
select s.id sid,s.name sname,t.id tid,t.name tname
from student s
join teacher t
on s.tid = t.id
注意:
對象類型屬性關系映射使用association和javaTypeproperty屬性對應的是實體類屬性column屬性對應的是查詢結果返回的列名因為查詢結果時使用了別名的方式,所以屬性column取值為別名的方式
10.2、對多關系
這里以一個老師對應多個學生的形式舉例
Teacher實體類中添加集合類型屬性:
// 一個老師對應多個學生
private List
TeacherMapper.xml:
SELECT t.id tid,t.name tname,s.id sid,s.name sname
FROM `teacher` t
JOIN `student` s
ON t.id = s.tid
where tid = #{tid}
測試:
@Test
public void testTeacher(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper teacherMapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = teacherMapper.queryById(1);
System.out.println(teacher);
sqlSession.close();
}
注意:
集合類型的屬性關系映射與對象類型屬性關系映射不同集合類型的屬性關系映射是使用collection和ofTypeofType指定的類型為集合的泛型類型
總結
當處理簡單的普通類型的映射關系時,使用resultType處理復雜類型(對象、集合)的映射關系時,需要使用結果集映射resultMap處理結果集映射的關系時,需要注意屬性名和列名的問題
11、動態(tài)SQL
在數據庫層面增加一些邏輯,根據條件動態(tài)生成不同的sql語句
數據庫準備:
CREATE TABLE `blog` (
`id` VARCHAR(50) NOT NULL COMMENT '博客id',
`title` VARCHAR(100) NOT NULL COMMENT '博客標題',
`author` VARCHAR(30) NOT NULL COMMENT '博客作者',
`create_time` DATETIME NOT NULL COMMENT '創(chuàng)建時間',
`views` INT(30) NOT NULL COMMENT '瀏覽量'
)ENGINE=INNODB DEFAULT CHARSET=utf8
核心配置文件:
創(chuàng)建新的工具類:
package com.yang.utils;
import java.util.UUID;
public class IdUtils {
/**
* 返回一個隨機的string類型的id
*/
public static String getId(){
return UUID.randomUUID().toString().replace("-","");
}
}
實體類:
package com.yang.pojo;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.Date;
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Blog {
private String id;
private String title;
private String author;
private Date createTime;
private Integer views;
}
接口:
package com.yang.dao;
import com.yang.pojo.Blog;
public interface BlogMapper {
int addBlog(Blog blog);
}
接口對應mapper:
insert into blog values (#{id},#{title},#{author},#{createTime},#{views})
插入數據:
@Test
public void insertTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
blogMapper.addBlog(new Blog(IdUtils.getId(),"Mybatis如此簡單","jack",new Date(),8888));
blogMapper.addBlog(new Blog(IdUtils.getId(),"Spring如此簡單","tom",new Date(),7777));
blogMapper.addBlog(new Blog(IdUtils.getId(),"SpringMVC如此簡單","smith",new Date(),4444));
blogMapper.addBlog(new Blog(IdUtils.getId(),"SpringBoot如此簡單","milan",new Date(),5555));
sqlSession.commit();
sqlSession.close();
}
11.1、if
使用if動態(tài)拼接 SQL 最常見情景是根據條件包含 where 子句的一部分
接口:
List
mapper:
select * from blog where 1 = 1
and title=#{title}
and author=#{author}
測試:
@Test
public void queryBlogTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
HashMap
map.put("author","tom");
List
for (Blog blog : blogList) {
System.out.println(blog);
}
sqlSession.close();
}
通過傳入Map,對指定內容進行篩選,使用if標簽拼接sql實現(xiàn)不同的查詢結果
11.2、where
where只會在至少一個子元素返回SQL子句的情況下才插入 “WHERE” 子句。而且,若子句的開頭為 “AND” 或 “OR”,where元素也會將它們去除,避免了sql語句拼接錯誤
去除mapper中的 where 1 = 1:
select * from blog
and title=#{title}
and author=#{author}
11.3、choose、when、otherwise
當我們只是想從多個條件中選擇一個使用。針對這種情況,MyBatis 提供了 choose 元素,它有點像 java中的 switch 語句
mapper:
select * from blog
title = #{title}
and author = #{author}
and views = #{views}
測試:
@Test
public void queryBlogTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
HashMap
map.put("title","SpringBoot如此簡單");
map.put("author","tom");
map.put("views",8888);
List
for (Blog blog : blogList) {
System.out.println(blog);
}
sqlSession.close();
}
當第一個條件滿足時,下面的sql語句將不在拼接
11.4、set
set會動態(tài)地在行首插入 SET 關鍵字,并會刪掉額外的逗號(這些逗號是在使用條件語句給列賦值時引入的)
接口中添加方法 :
int updateBlog(Map
mapper:
update blog
title=#{title},
author=#{author}
where id=#{id}
測試:
@Test
public void updateBlogTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map
map.put("title","Mybatis如此簡單");
map.put("author","jack");
map.put("id","751e59e0a6934e509ab40f49d1a6a117");
blogMapper.updateBlog(map);
sqlSession.commit();
sqlSession.close();
}
使用set時,當前面的條件滿足,后面的條件不滿足時,會自動去除多余的逗號,保證sql語句的正確
注意:當沒有條件滿足時,使用set,會導致sql語句拼接錯誤
11.5、sql片段
把sql語句中的公共部分提取,方便復用
title = #{title}
and author = #{author}
and views = #{views}
select * from blog
include標簽相當于將sql標簽的內容插入到where標簽內,當下次有同樣需求時,sql片段可以實現(xiàn)復用,建議使用時,sql片段內不包含where標簽
11.6、foreach
可以將任何可迭代對象(如 List、Set 等)、Map 對象或者數組對象作為集合參數傳遞給 foreach。當使用可迭代對象或者數組時,index 是當前迭代的序號,item 的值是本次迭代獲取到的元素。當使用 Map 對象(或者 Map.Entry 對象的集合)時,index 是鍵,item 是值
接口:
List
mapper:
select * from blog
id=#{id}
collection是需要遍歷的集合item是集合中的每一個值open表示在開頭拼接close表示在結尾拼接separator每一個值之間的分隔符,比如:where (item1 or item2 …)
測試:
@Test
public void queryBlogsForeachTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
BlogMapper blogMapper = sqlSession.getMapper(BlogMapper.class);
Map
ArrayList
ids.add("751e59e0a6934e509ab40f49d1a6a117");
ids.add("b7e24d13123e445cbdb6ef9230496eff");
ids.add("5e6d4acc336342df9939033eb5c898c5");
// 將list集合放入map集合中
map.put("ids",ids);
List
for (Blog blog : blogList) {
System.out.println(blog);
}
sqlSession.close();
}
柚子快報邀請碼778899分享:Mybatis基本使用
推薦文章
本文內容根據網絡資料整理,出于傳遞更多信息之目的,不代表金鑰匙跨境贊同其觀點和立場。
轉載請注明,如有侵權,聯(lián)系刪除。