目录
一、MyBatis 注解开发概述
二、使用注解完成 CRUD 操作
1. 配置 MyBatis 核心文件 SqlMapConfig.xml
2. UserDao 接口及注解
3. UserTest 测试方法
三、多对一查询(One-to-Many)
1. 多对一立即加载查询
2.StudentDao 接口方法
四、多对一延迟加载查询(Lazy Loading)
1. StudentDao 接口方法
2. TeacherDao 接口方法
五、一对多查询(Many-to-One)
1. TeacherDao 接口方法(延迟加载)
2. StudentDao 接口方法
一、MyBatis 注解开发概述
MyBatis 提供了基于 XML 配置和基于注解的两种开发方式。注解方式相对简单,但实际开发中更推荐使用 XML 配置方式,以减少对源代码的修改,提高可维护性。
1. MyBatis 常用注解
- @Insert:添加数据
- @Update:修改数据
- @Delete:删除数据
- @Select:查询数据
- @Result:实现结果集封装
- @Results:配合 @Result 使用,封装多个结果集
- @One:一对一、多对一映射
- @Many:一对多映射
二、使用注解完成 CRUD 操作
1. 配置 MyBatis 核心文件 SqlMapConfig.xml
<mappers>
<!-- 第一种方式:使用 class 引入具体的 Dao 接口 -->
<mapper class="com.qcby.dao.UserAnnoDao"/>
<!-- 第二种方式:针对整个包下的所有接口 -->
<package name="com.qcby.dao"/>
</mappers>
2. UserDao
接口及注解
import com.qcby.entity.User;
import org.apache.ibatis.annotations.*;
import java.util.List;
public interface UserDao {
// 查询所有用户
@Select("SELECT * FROM user")
@Results(id="userMap", value = {
@Result(property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "birthday", column = "birthday"),
@Result(property = "sex", column = "sex"),
@Result(property = "address", column = "address")
})
List<User> findAll();
// 根据 ID 查询用户
@Select("SELECT * FROM user WHERE id = #{id}")
@ResultMap("userMap")
User findById(int id);
// 插入用户数据
@Insert("INSERT INTO user(username, birthday, sex, address) VALUES(#{username}, #{birthday}, #{sex}, #{address})")
@SelectKey(statement = "SELECT LAST_INSERT_ID()", keyColumn = "id", keyProperty = "id", before = false, resultType = Integer.class)
int insert(User user);
// 更新用户信息
@Update("UPDATE user SET username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address} WHERE id = #{id}")
int update(User user);
// 删除用户
@Delete("DELETE FROM user WHERE id = #{id}")
int delete(int id);
// 查询用户总数
@Select("SELECT COUNT(*) FROM user")
int findCount();
// 模糊查询用户
@Select("SELECT * FROM user WHERE username LIKE #{username}")
List<User> findByName(String username);
}
3. UserTest
测试方法
public class UserTest {
private InputStream in;
private SqlSession session;
private UserDao mapper;
@Before
public void init() throws IOException {
in = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
session = factory.openSession();
mapper = session.getMapper(UserDao.class);
}
@After
public void destroy() throws IOException {
session.close();
in.close();
}
@Test
public void findAll() {
List<User> users = mapper.findAll();
users.forEach(System.out::println);
}
@Test
public void findById() {
System.out.println(mapper.findById(4));
}
@Test
public void insert() {
User user = new User("小美", new Date(), "女", "保定");
int insert = mapper.insert(user);
session.commit();
System.out.println(insert);
}
@Test
public void update() {
User user = new User(22, "小美", new Date(), "女", "上海");
int update = mapper.update(user);
session.commit();
System.out.println(update);
}
@Test
public void delete() {
int delete = mapper.delete(22);
session.commit();
System.out.println(delete);
}
@Test
public void findCount() {
System.out.println(mapper.findCount());
}
@Test
public void findByName() {
mapper.findByName("%a%").forEach(System.out::println);
}
}
三、多对一查询(One-to-Many)
1. 多对一立即加载查询
StudentDao
接口方法
@Select("SELECT student.*, teacher.Tname FROM student LEFT JOIN teacher ON student.t_id = teacher.id")
@Results(value = {
@Result(property = "id", column = "id"),
@Result(property = "Sname", column = "Sname"),
@Result(property = "sex", column = "sex"),
@Result(property = "age", column = "age"),
@Result(property = "t_id", column = "t_id"),
@Result(property = "teacher.Tname", column = "Tname")
})
List<Student> getStudent();
测试代码
@Test
public void getStudent() {
List<Student> students = mapper.getStudent();
students.forEach(System.out::println);
}
四、多对一延迟加载查询(Lazy Loading)
1. StudentDao
接口方法
@Select("SELECT * FROM student")
@Results(value = {
@Result(property = "id", column = "id"),
@Result(property = "Sname", column = "Sname"),
@Result(property = "sex", column = "sex"),
@Result(property = "age", column = "age"),
@Result(property = "teacher", column = "t_id",
one = @One(select = "com.qcby.dao.TeacherDao.getTeacher", fetchType = FetchType.LAZY))
})
List<Student> getStudent();
2. TeacherDao
接口方法
@Select("SELECT * FROM teacher WHERE id = #{t_id}")
Teacher getTeacher(Integer id);
3. 测试代码
@Test
public void getStudent() {
List<Student> students = mapper.getStudent();
students.forEach(System.out::println);
}
五、一对多查询(Many-to-One)
1. TeacherDao
接口方法(延迟加载)
@Select("SELECT * FROM Teacher")
@Results(value = {
@Result(property = "id", column = "id"),
@Result(property = "Tname", column = "Tname"),
@Result(property = "students", column = "id",
many = @Many(select = "com.qcby.dao.StudentDao.findByUid", fetchType = FetchType.LAZY))
})
List<Teacher> findAllLazy();
2. StudentDao
接口方法
@Select("SELECT * FROM student WHERE t_id = #{t_id}")
Student findByUid(int uid);
3. 测试代码
@Test
public void findAllLazy() {
List<Teacher> list = mapper.findAllLazy();
list.forEach(System.out::println);
}
总结
- 注解方式可以快速开发,但 XML 配置更具灵活性和可维护性。
@One
和@Many
结合fetchType.LAZY
可以实现延迟加载,优化查询性能。- CRUD 操作通过
@Insert
、@Select
、@Update
、@Delete
进行实现。 - 一对多、多对一映射可以用
@One
和@Many
进行关联查询。
注解开发适用于小型项目或快速原型搭建,而企业级应用更推荐使用 XML 配置方式以降低代码耦合度。