第一章:前言
- 注解开发虽然不如 XML 开发那样,可以完全做到代码和配置文件分离,但是其开发灵活快速的特性,使得在企业开发中的地位日益显著,而 Mybatis 作为时下最流行的持久层框架,掌握 Mybatis 注解开发势在必行。
第二章:环境准备
-- ----------------------------
-- Table structure for account
-- ----------------------------
DROP TABLE IF EXISTS `account`;
CREATE TABLE `account` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`user_id` int(11) NULL DEFAULT NULL COMMENT '外键',
`money` double NULL DEFAULT NULL COMMENT '存款',
PRIMARY KEY (`id`) USING BTREE,
INDEX `fk_user_id`(`user_id`) USING BTREE,
CONSTRAINT `fk_user_id` FOREIGN KEY (`user_id`) REFERENCES `user` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of account
-- ----------------------------
INSERT INTO `account` VALUES (1, 1, 5000);
INSERT INTO `account` VALUES (2, 2, 2000);
INSERT INTO `account` VALUES (3, 3, 3000);
-- ----------------------------
-- Table structure for course
-- ----------------------------
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '课程名称',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES (1, '语文');
INSERT INTO `course` VALUES (2, '数学');
INSERT INTO `course` VALUES (3, '英语');
-- ----------------------------
-- Table structure for student
-- ----------------------------
DROP TABLE IF EXISTS `student`;
CREATE TABLE `student` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '学生姓名',
`age` int(11) NULL DEFAULT NULL COMMENT '学生年龄',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student
-- ----------------------------
INSERT INTO `student` VALUES (1, '张三', 20);
INSERT INTO `student` VALUES (2, '李四', 25);
-- ----------------------------
-- Table structure for student_course
-- ----------------------------
DROP TABLE IF EXISTS `student_course`;
CREATE TABLE `student_course` (
`sid` int(11) NULL DEFAULT NULL COMMENT '外键,指向学生表的主键',
`cid` int(11) NULL DEFAULT NULL COMMENT '外键,指向课程表的主键',
INDEX `fk_sid`(`sid`) USING BTREE,
INDEX `fk_cid`(`cid`) USING BTREE,
CONSTRAINT `fk_cid` FOREIGN KEY (`cid`) REFERENCES `course` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `fk_sid` FOREIGN KEY (`sid`) REFERENCES `student` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of student_course
-- ----------------------------
INSERT INTO `student_course` VALUES (1, 1);
INSERT INTO `student_course` VALUES (1, 2);
INSERT INTO `student_course` VALUES (1, 3);
INSERT INTO `student_course` VALUES (2, 3);
-- ----------------------------
-- Table structure for user
-- ----------------------------
DROP TABLE IF EXISTS `user`;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`username` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '用户名',
`birthday` datetime(0) NULL DEFAULT NULL COMMENT '生日',
`gender` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '性别',
`address` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL COMMENT '地址',
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 4 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of user
-- ----------------------------
INSERT INTO `user` VALUES (1, '张三', '2021-11-02 10:43:06', '男', '江苏苏州');
INSERT INTO `user` VALUES (2, '李四', '2021-10-26 10:43:24', '女', '江苏南京');
INSERT INTO `user` VALUES (3, '王五', '2021-10-26 10:43:45', '男', '江苏徐州');
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.1</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.17</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>8.0.21</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
<scope>test</scope>
</dependency>
<?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">
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url"
value="jdbc:mysql://192.168.134.100:3306/test?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&useSSL=false&serverTimezone=GMT%2B8&allowPublicKeyRetrieval=true"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.github.mapper"/>
</mappers>
</configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
<appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
<param name="Encoding" value="UTF-8" />
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
</layout>
</appender>
<logger name="java.sql">
<level value="debug" />
</logger>
<logger name="org.apache.ibatis">
<level value="info" />
</logger>
<root>
<level value="debug" />
<appender-ref ref="STDOUT" />
</root>
</log4j:configuration>
第三章:Mybatis 注解实现常用的 CRUD
package com.sunxiaping.domain;
import java.io.Serializable;
import java.util.Date;
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String gender;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", birthday=" + birthday +
", gender='" + gender + '\'' +
", address='" + address + '\'' +
'}';
}
}
package com.sunxiaping.mapper;
import com.sunxiaping.domain.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserMapper {
/**
* 查询所有用户信息
*
* @return
*/
@Select(" SELECT * FROM `user`")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "birthday", column = "birthday"),
@Result(property = "gender", column = "gender"),
@Result(property = "address", column = "address"),
})
List<User> findAll();
/**
* 添加用户信息
*
* @param user
*/
@Insert(" INSERT INTO `user` (username,birthday,gender,address) VALUES (#{username},#{birthday},#{gender},#{address})")
void saveUser(User user);
/**
* 修改用户信息
*
* @param user
*/
@Update(" UPDATE `user` set username = #{username},gender= #{gender} ,address = #{address} WHERE id = #{id} ")
void updateUser(User user);
/**
* 删除用户信息
*
* @param id
*/
@Delete(" DELETE FROM `user` WHERE id = #{id} ")
void deleteById(Integer id);
}
package com.sunxiaping;
import com.sunxiaping.domain.User;
import com.sunxiaping.mapper.UserMapper;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
public class UserTest {
SqlSessionFactory sqlSessionFactory = null;
SqlSession sqlSession = null;
@Before
public void before() throws IOException {
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
}
@After
public void after() {
if (sqlSession != null) {
sqlSession.close();
}
}
@Test
public void testFindAll() throws IOException {
sqlSession = sqlSessionFactory.openSession(true);
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.findAll();
System.out.println("userList = " + userList);
}
@Test
public void testSaveUser() {
sqlSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setUsername("zhangsan");
user.setBirthday(new Date());
user.setGender("男");
user.setAddress("江苏苏州");
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.saveUser(user);
}
@Test
public void testUpdateUser() {
sqlSession = sqlSessionFactory.openSession(true);
User user = new User();
user.setId(1);
user.setUsername("张三");
user.setGender("女");
user.setAddress("江苏苏州");
user.setBirthday(new Date());
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.updateUser(user);
}
@Test
public void testDeleteById() {
sqlSession = sqlSessionFactory.openSession(true);
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.deleteById(1);
}
}
第四章:Mybatis 注解实现一对一关联查询

SELECT * FROM `account`
SELECT * FROM `user` WHERE id = #{id}
package com.github.entity;
import java.io.Serializable;
import java.util.Date;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 10:42
*/
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String gender;
private String address;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", gender='"
+ gender + '\'' + ", address='" + address + '\'' + '}';
}
}
package com.github.entity;
import java.io.Serializable;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 10:44
*/
public class Account implements Serializable {
private Integer id;
private Double money;
/**
* 一个账户属于一个用户
*/
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Account{" + "id=" + id + ", money=" + money + ", user=" + user + '}';
}
}
package com.github.mapper;
import com.github.entity.User;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 10:45
*/
@Mapper
public interface UserMapper {
@Select("SELECT * FROM `user` WHERE id = #{id}")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "birthday", column = "birthday"),
@Result(property = "gender", column = "gender"),
@Result(property = "address", column = "address"),
})
User findById(Integer id);
}
package com.github.mapper;
import com.github.entity.Account;
import com.github.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 10:45
*/
@Mapper
public interface AccountMapper {
@Select("SELECT * FROM `account`")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "money", column = "money"),
@Result(
property = "user",
javaType = User.class,
column = "user_id",
one = @One(select = "com.github.mapper.UserMapper.findById")
)
})
List<Account> findAll();
}
package com.github.mybatis;
import com.github.entity.Account;
import com.github.mapper.AccountMapper;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-10-29 14:19
*/
public class MybatisTest {
SqlSession sqlSession;
@Before
public void before() throws IOException {
// 使用Mybatis的Resources读取mybatis-config.xml配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void test() throws IOException {
AccountMapper accountMapper = sqlSession.getMapper(AccountMapper.class);
List<Account> accountList = accountMapper.findAll();
accountList.forEach(System.out::println);
}
@After
public void after() {
if (null != sqlSession) {
sqlSession.close();
}
}
}
第五章:Mybatis 注解实现一对多关联查询

SELECT * FROM `user`
SELECT * FROM `account` where user_id = #{user_id}
package com.github.entity;
import java.io.Serializable;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 10:44
*/
public class Account implements Serializable {
private Integer id;
private Double money;
public Account(Integer id, Double money) {
this.id = id;
this.money = money;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Double getMoney() {
return money;
}
public void setMoney(Double money) {
this.money = money;
}
@Override
public String toString() {
return "Account{" + "id=" + id + ", money=" + money + '}';
}
}
package com.github.entity;
import java.io.Serializable;
import java.util.Date;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 10:42
*/
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String gender;
private String address;
// 一个用户有多个账号
private List<Account> accountList;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Account> getAccountList() {
return accountList;
}
public void setAccountList(List<Account> accountList) {
this.accountList = accountList;
}
@Override
public String toString() {
return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", gender='"
+ gender + '\'' + ", address='" + address + '\'' + ", accountList=" + accountList + '}';
}
}
package com.github.mapper;
import com.github.entity.Account;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 10:45
*/
@Mapper
public interface AccountMapper {
@Select("SELECT * FROM `account` where user_id = #{userId}")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "money", column = "money")}
)
List<Account> findByUserId(Integer userId);
}
package com.github.mapper;
import com.github.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 10:45
*/
@Mapper
public interface UserMapper {
@Select(" SELECT * FROM `user`")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "birthday", column = "birthday"),
@Result(property = "gender", column = "gender"),
@Result(property = "address", column = "address"),
@Result(
property = "accountList", // 被包含对象的变量名
column = "id", // 根据查询出来的user表中的id去根据user_id查询
many = @Many(select = "com.github.mapper.AccountMapper.findByUserId")),
})
List<User> findAll();
}
package com.github.mybatis;
import com.github.entity.User;
import com.github.mapper.UserMapper;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-10-29 14:19
*/
public class MybatisTest {
SqlSession sqlSession;
@Before
public void before() throws IOException {
// 使用Mybatis的Resources读取mybatis-config.xml配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void test() throws IOException {
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<User> userList = userMapper.findAll();
userList.forEach(System.out::println);
}
@After
public void after() {
if (null != sqlSession) {
sqlSession.close();
}
}
}
第六章:Mybatis 注解实现多对多关联查询

SELECT * FROM `student`
SELECT c.* FROM `student_course` sc INNER JOIN `course` c ON sc.cid = c.id WHERE sc.sid = #{id}
package com.github.entity;
import java.io.Serializable;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 11:06
*/
public class Student implements Serializable {
private Integer id;
private String name;
private Integer age;
private List<Course> courseList;
public Student() {}
public Student(Integer id, String name, Integer age, List<Course> courseList) {
this.id = id;
this.name = name;
this.age = age;
this.courseList = courseList;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
@Override
public String toString() {
return "Student{" + "id=" + id + ", name='" + name + '\'' + ", age=" + age + ", courseList=" + courseList + '}';
}
}
package com.github.entity;
import java.io.Serializable;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 11:07
*/
public class Course implements Serializable {
private Integer id;
private String name;
public Course() {}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Course{" + "id=" + id + ", name='" + name + '\'' + '}';
}
}
package com.github.mapper;
import com.github.entity.Course;
import org.apache.ibatis.annotations.Mapper;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 11:09
*/
@Mapper
public interface CourseMapper {
@Select("SELECT c.* FROM `student_course` sc INNER JOIN `course` c ON sc.cid = c.id WHERE sc.sid = #{id}")
List<Course> findBySid(Integer id);
}
package com.github.mapper;
import com.github.entity.Student;
import org.apache.ibatis.annotations.*;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-11-02 11:09
*/
@Mapper
public interface StudentMapper {
@Select("SELECT * FROM `student`")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "name", column = "name"),
@Result(property = "age", column = "age"),
@Result(
property = "courseList", //被包含对象的变量名
column = "id", //根据查询出来的student表中的id去中间表和course表中查询
many = @Many(select = "com.github.mapper.CourseMapper.findBySid")
)
})
List<Student> findAll();
}
package com.github.mybatis;
import com.github.entity.Student;
import com.github.mapper.StudentMapper;
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 org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* @author 许大仙
* @version 1.0
* @since 2021-10-29 14:19
*/
public class MybatisTest {
SqlSession sqlSession;
@Before
public void before() throws IOException {
// 使用Mybatis的Resources读取mybatis-config.xml配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
sqlSession = sqlSessionFactory.openSession();
}
@Test
public void test() throws IOException {
StudentMapper studentMapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = studentMapper.findAll();
studentList.forEach(System.out::println);
}
@After
public void after() {
if (null != sqlSession) {
sqlSession.close();
}
}
}