mybatis入门

  1. 1. xml方式实现:
  2. 2. 注解方式实现:

注:基于Mysql8版本


目录结构

jdbc.properties

1
2
3
4
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/library?useUnicode=true&characterEncoding=utf-8&serverTimezone=Asia/Shanghai
jdbc.user=root
jdbc.password=111

log4j日志配置 log4j.properties

1
2
3
4
5
6
7
8
9
10
11
12
13
### direct log messages to stdout ###
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=%d{yyyy-MM-dd HH:mm:ss} %m%n
### direct messages to file mylog.log ###
### log4j.appender.file=org.apache.log4j.FileAppender
### log4j.appender.file.File=d:mylog.log
### log4j.appender.file.layout=org.apache.log4j.PatternLayout
### log4j.appender.file.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %m%n
### set log levels - for more verbose logging change 'debug?info?warn?error' ###
### log4j.rootLogger=debug,stdout,file
log4j.rootLogger=debug,stdout

注:以上是控制台输出日志,注释的为文件日志

mybatis-config.xml

mybatis配置文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd"> <!-- 约束声明 -->

<!-- mybatis的全局配置文件 -->
<configuration>
<!-- 引入jdbc.properties文件 -->
<properties resource="jdbc.properties"></properties>


<!-- 定义类别名 -->
<typeAliases>
<package name="com.xxxx.pojo"/>
</typeAliases>

<!-- 配置数据源相关属性和事务 配置mybatis的开发环境 -->
<environments default="development">
<!-- 可以配置多个数据源环境,默认使用default中的值 -->
<environment id="development">
<!-- transactionManager标签的type属性有两种取值:
JDBC:全部使用jdbc的事务管理
MANAGED:不使用事务管理,也从不提交-->

<!-- 使用jdbc的事务管理 -->
<transactionManager type="JDBC"/>

<!-- 配置数据源即连接池:dataSource标签的type属性有三种取值:
POOLED:使用Mybatis自带的数据库连接池
UNPOOLED:不使用任何数据库连接池
JNDI:jndi形式使用数据库连接 已过时 -->

<!-- 配置数据源,并使用自带数据库连接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>


<!-- 导入mapper.xml映射文件,可配置多个 -->
<mappers>
<!-- 自动加载com.xxxx.dao包下,所有与接口名称一致的映射文件。(package标签可写多个)-->
<package name="com.xxxx.dao"/>
</mappers>
</configuration>

工具类 MybatisUtils.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
package com.xxxx.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;

static {
String resource = "mybatis-config.xml";

try {
// 1.使用mybatis的第一步 --- 获取SqlSessionFactory实例对象
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
} catch (IOException e) {
e.printStackTrace();
}
}

/**
* 既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例
* SqlSession 提供了在数据库执行 SQL 命令所需的所有方法
* 你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。
*/
public static SqlSession getSqlSession() {
//通过SqlSessionFactory打开数据库会话
return sqlSessionFactory.openSession();
}
}

创建实体类 Book.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package com.xxxx.pojo;
import java.sql.Date;

public class Book {
private Integer book_id; // 图书编号
private String name; //书名
private String author; //作者
private String publish; //出版社
private String introduction; //简介
private String language; //语言
private double price; //价钱
private Date pub_date; //出版日期
private Integer class_id; //书籍类别
private Integer number; //书籍数量

public Book() {
}

public Book(Integer book_id, String name, String author, String publish, String introduction, String language, double price, Date pub_date, Integer class_id, Integer number) {
this.book_id = book_id;
this.name = name;
this.author = author;
this.publish = publish;
this.introduction = introduction;
this.language = language;
this.price = price;
this.pub_date = pub_date;
this.class_id = class_id;
this.number = number;
}

get/set、toString() 方法

数据库表 book_info

插入数据sql语句

sql语句展开
1
2
3
4
5
6
7
8
9
10
11
12
13
14
INSERT INTO `book_info` VALUES (1, '大雪中的山庄', '东野圭吾 ', '北京十月文艺出版社', '东野圭吾长篇小说杰作,中文简体首次出版。 一出没有剧本的舞台剧,为什么能让七个演员赌上全部人生.东野圭吾就是有这样过人的本领,能从充满悬念的案子写出荡气回肠的情感,在极其周密曲折的同时写出人性的黑暗与美丽。 一家与外界隔绝的民宿里,七个演员被要求住满四天,接受导演的考验,但不断有人失踪。难道这并非正常排练,而是有人布下陷阱要杀他们。 那时候我开始喜欢上戏剧和音乐,《大雪中的山庄》一书的灵感就来源于此。我相信这次的诡计肯定会让人大吃一惊。——东野圭吾', '中文', 35.00, '2017-6-1', 9, 1);
INSERT INTO `book_info` VALUES (2, '三生三世 十里桃花', '唐七公子 ', '沈阳出版社', '三生三世,她和他,是否注定背负一段纠缠的姻缘?\r\n三生三世,她和他,是否终能互许一个生生世世的承诺?', '中文', 26.80, '2009-1-6', 7, 1);
INSERT INTO `book_info` VALUES (3, '何以笙箫默', '顾漫 ', '朝华出版社', '一段年少时的爱恋,牵出一生的纠缠。大学时代的赵默笙阳光灿烂,对法学系大才子何以琛一见倾心,开朗直率的她拔足倒追,终于使才气出众的他为她停留驻足。然而,不善表达的他终于使她在一次伤心之下远走他乡……', '中文', 15.00, '2007-4-3', 7, 1);
INSERT INTO `book_info` VALUES (4, '11处特工皇妃', '潇湘冬儿', '江苏文艺出版社', '《11处特工皇妃(套装上中下册)》内容简介:她是国安局军情十一处惊才绝艳的王牌军师——收集情报、策划部署、进不友好国家布置暗杀任务……她运筹帷幄之中,决胜于千里之外,堪称军情局大厦的定海神针。', '中文', 74.80, '2011-5-5', 7, 1);
INSERT INTO `book_info` VALUES (5, '人类简史', '[以色列] 尤瓦尔·赫拉利 ', '中信出版社', '十万年前,地球上至少有六种不同的人\r\n但今日,世界舞台为什么只剩下了我们自己?\r\n从只能啃食虎狼吃剩的残骨的猿人,到跃居食物链顶端的智人,\r\n从雪维洞穴壁上的原始人手印,到阿姆斯壮踩上月球的脚印,\r\n从认知革命、农业革命,到科学革命、生物科技革命,\r\n我们如何登上世界舞台成为万物之灵的?\r\n从公元前1776年的《汉摩拉比法典》,到1776年的美国独立宣言,\r\n从帝国主义、资本主义,到自由主义、消费主义,\r\n从兽欲,到物欲,从兽性、人性,到神性,\r\n我们了解自己吗?我们过得更快乐吗?\r\n我们究竟希望自己得到什么、变成什么?', '英文', 68.00, '2014-11-1', 11, 1);
INSERT INTO `book_info` VALUES (6, '明朝那些事儿(1-9)', '当年明月 ', '中国海关出版社', '《明朝那些事儿》讲述从1344年到1644年,明朝三百年间的历史。作品以史料为基础,以年代和具体人物为主线,运用小说的笔法,对明朝十七帝和其他王公权贵和小人物的命运进行全景展示,尤其对官场政治、战争、帝王心术着墨最多。作品也是一部明朝政治经济制度、人伦道德的演义。', '中文', 358.20, '2009-4-6', 11, 1);
INSERT INTO `book_info` VALUES (7, '经济学原理(上下)', '[美] 曼昆 ', '机械工业出版社', '此《经济学原理》的第3版把较多篇幅用于应用与政策,较少篇幅用于正规的经济理论。书中主要从供给与需求、企业行为与消费者选择理论、长期经济增长与短期经济波动以及宏观经济政策等角度深入浅出地剖析了经济学家们的世界观。', '英文', 88.00, '2003-8-5', 6, 1);
INSERT INTO `book_info` VALUES (8, '方向', '马克-安托万·马修 ', '后浪丨北京联合出版公司', '《方向》即便在马修的作品中也算得最独特的:不着一字,尽得风流。原作本无一字,标题只是一个→,出版时才加了个书名Sens——既可以指“方向”,也可以指“意义”。 《方向》没有“字”,但有自己的语言——请读者在尽情释放想象力和独立思考之余,破解作者的密码,听听作者对荒诞的看法。', '中文', 99.80, '2017-4-1', 9, 1);
INSERT INTO `book_info` VALUES (9, '画的秘密', '马克-安托万·马修 ', '北京联合出版公司·后浪出版公司', '一本关于友情的疗伤图像小说,直击人内心最为隐秘的情感。 一部追寻艺术的纸上悬疑电影,揭示命运宇宙中奇诡的真相。 ★ 《画的秘密》荣获欧洲第二大漫画节“瑞士谢尔漫画节最佳作品奖”。 作者曾两度夺得安古兰国际漫画节重要奖项。 ★ 《画的秘密》是一部罕见的、结合了拼贴、镜像、3D等叙事手法的实验型漫画作品。作者巧妙地调度光线、纬度、时间、记忆,在一个悬念重重又温情治愈的故事中,注入了一个有关命运的哲学议题。', '中文', 60.00, '2016-1-1', 9, 0);
INSERT INTO `book_info` VALUES (10, '造彩虹的人', '东野圭吾 ', '北京十月文艺出版社', '其实每个人身上都会发光,但只有纯粹渴求光芒的人才能看到。 从那一刻起,人生会发生奇妙的转折。功一高中退学后无所事事,加入暴走族消极度日;政史备战高考却无法集中精神,几近崩溃;辉美因家庭不和对生活失去勇气,决定自杀。面对糟糕的人生,他们无所适从,直到一天夜里,一道如同彩虹的光闯进视野。 凝视着那道光,原本几乎要耗尽的气力,源源不断地涌了出来。一切又开始充满希望。打起精神来,不能输。到这儿来呀,快来呀——那道光低声呼唤着。 他们追逐着呼唤,到达一座楼顶,看到一个人正用七彩绚烂的光束演奏出奇妙的旋律。 他们没想到,这一晚看到的彩虹,会让自己的人生彻底转...', '中文', 39.50, '2017-6-1', 9, 1);
INSERT INTO `book_info` VALUES (11, '控方证人', '阿加莎·克里斯蒂 ', '新星出版社', '经典同名话剧六十年常演不衰; 比利•怀尔德执导同名电影,获奥斯卡金像奖六项提名! 阿加莎对神秘事物的向往大约来自于一种女性祖先的遗传,在足不出户的生活里,生出对世界又好奇又恐惧的幻想。 ——王安忆 伦纳德•沃尔被控谋杀富婆艾米丽以图染指其巨额遗产,他却一再表明自己的无辜。伦纳德的妻子是唯一能够证明他无罪的证人,却以控方证人的身份出庭指证其确实犯有谋杀罪。伦纳德几乎陷入绝境,直到一个神秘女人的出现…… 墙上的犬形图案;召唤死亡的收音机;蓝色瓷罐的秘密;一只疯狂的灰猫……十一篇神秘的怪谈,最可怕的不是“幽灵”,而是你心中的魔鬼。', '中文', 35.00, '2017-5-1', 9, 1);
INSERT INTO `book_info` VALUES (12, '少有人走的路', 'M·斯科特·派克 ', '吉林文史出版社', '这本书处处透露出沟通与理解的意味,它跨越时代限制,帮助我们探索爱的本质,引导我们过上崭新,宁静而丰富的生活;它帮助我们学习爱,也学习独立;它教诲我们成为更称职的、更有理解心的父母。归根到底,它告诉我们怎样找到真正的自我。 正如开篇所言:人生苦难重重。M·斯科特·派克让我们更加清楚:人生是一场艰辛之旅,心智成熟的旅程相当漫长。但是,他没有让我们感到恐惧,相反,他带领我们去经历一系列艰难乃至痛苦的转变,最终达到自我认知的更高境界。', '中文', 26.00, '2007-1-1', 9, 1);
INSERT INTO `book_info` VALUES (13, '追寻生命的意义', '[奥] 维克多·弗兰克 ', '新华出版社', '《追寻生命的意义》是一个人面对巨大的苦难时,用来拯救自己的内在世界,同时也是一个关于每个人存在的价值和能者多劳们生存的社会所应担负职责的思考。本书对于每一个想要了解我们这个时代的人来说,都是一部必不可少的读物。这是一部令人鼓舞的杰作……他是一个不可思议的人,任何人都可以从他无比痛苦的经历中,获得拯救自己的经验……高度推荐。', '中文', 12.00, '2003-1-1', 9, 0);
INSERT INTO `book_info` VALUES (14, '秘密花园', '乔汉娜·贝斯福 ', '北京联合出版公司', '欢迎来到秘密花园! 在这个笔墨编织出的美丽世界中漫步吧 涂上你喜爱的颜色,为花园带来生机和活力 发现隐藏其中的各类小生物,与它们共舞 激活创造力,描绘那些未完成的仙踪秘境 各个年龄段的艺术家和“园丁”都可以来尝试喔!', '中文', 42.00, '2015-6-1', 9, 1);

创建接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package com.xxxx.dao;

import com.xxxx.pojo.Book;
import org.apache.ibatis.annotations.Select;
import java.util.List;

public interface BookDao {
// XML的语句映射方式
public List<Book> getBooksAll(); //获取所有书籍信息

// 基于注解的语句映射方式
@Select("select * from book_info where book_id=#{book_id}")
public Book getBookByID(int id);
}

xml方式实现:

BookDao.xml映射文件(只示例了其中一个方法, 另一个使用了注解)

1
2
3
4
5
6
7
8
9
10
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.xxxx.dao.BookDao">
<select id="getBooksAll" resultType="Book">
select * from book_info
</select>
</mapper>

测试:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
package com.xxxx.dao;

import com.xxxx.pojo.Book;
import com.xxxx.utils.JsonModel;
import com.xxxx.utils.JsonUtil;
import com.xxxx.utils.MybatisUtils;
import org.apache.ibatis.session.SqlSession;
import org.junit.Test;
import java.util.List;

public class BookDaoTest {
@Test
public void test() {
// 1. 获得SqlSession
SqlSession session = MybatisUtils.getSqlSession();
// 2. 获得mapper,执行sql
BookDao mapper = session.getMapper(BookDao.class);
List<Book> list = mapper.getBooksAll();
JsonModel<List<Book>> book = new JsonModel<>();
book.setStatus(1);
book.setMsg("success");
book.setData(list);
book.setTotal(list.size());
System.out.println(JsonUtil.toJsonString(book));
session.close();
}

@Test
public void test1() {
SqlSession session = MybatisUtils.getSqlSession();
BookDao mapper = session.getMapper(BookDao.class);
Book book = mapper.getBookByID(1); // 查询id为1的书籍信息
System.out.println(book);
session.close();
}
}

运行结果:

注解方式实现:

创建实体类 Emp.java

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.xxxx.pojo;

import org.apache.ibatis.type.Alias;

@Alias("emp")
public class Emp {
private Integer empno;
private String ename;
private String job;
private String hiredate;
private Double sal;
private Integer deptno;

get/set、toString() 方法
}

接口上通过注解编写sql

1
2
@Select("select * from test")
public List<Emp> listEmpAll();

测试

1
2
3
4
5
6
7
8
@Test
public void test2() {
SqlSession session = MybatisUtils.getSqlSession();
BookDao mapper = session.getMapper(BookDao.class);
List<Emp> list = mapper.listEmpAll();
System.out.println(list);
session.close();
}

测试结果: