一、MyBatis 的常用注解
- @Insert:实现数据插入
- @Update:实现数据更新
- @Delete:实现删除数据
- @Select:查询数据
- @Result:实现结果集封装
- @Results:可以与 @Result 一起使用
- @One:实现一对一结果集封装
- @Many:实现一对多结果集封装
二、MyBatis 的增删改查
完成对 User 的增删改查操作
1.编写 SqlMapConfig.xml配置文件
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--指定JDBC配置信息-->
<properties resource="jdbc.properties"></properties>
<settings>
<!-- 打印sql日志 -->
<setting name="logImpl" value="STDOUT_LOGGING" />
</settings>
<!-- default 指定默认环境的名称 -->
<environments default="dev">
<!-- id指定当前环境名称 -->
<environment id="dev">
<!-- 事务管理类型,交由 JDBC 管理事务 -->
<transactionManager type="JDBC"></transactionManager>
<!-- 指定当前数据源类型是连接池 -->
<dataSource type="POOLED">
<!-- 数据源配置的基本参数 -->
<property name="driver" value="${mysql.driver}"/>
<property name="url" value="${mysql.url}"/>
<property name="username" value="${mysql.username}"/>
<property name="password" value="${mysql.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper class="com.mfc.dao.UserDao"></mapper>
</mappers>
</configuration>
2.编写 User 实体类
public class User {
private Integer id;
private String username;
// set、get、toString 方法省略。。。
}
3.编写 UserDao 接口
public interface UserDao {
@Select("select * from user")
public List<User> findAllUser();
@Select("select * from user where id=#{id}")
public User findUserById(Integer id);
@Insert("insert into user values(#{id},#{username})")
public void addUser(User user);
@Delete("delete from user where id=#{id}")
public void deleteUser(Integer id);
@Update("update user set t.username=#{username} where id=#{id}")
public void updateUser(User user);
}
4.编写测试类
这里只测试查询方法:
@org.junit.Test
public void test() throws Exception{
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
SqlSessionFactory factory = builder.build(inputStream);
SqlSession sqlSession = factory.openSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
List<User> users = userDao.findAllUser();
for (User user : users) {
System.out.println(user);
}
sqlSession.close();
}
三、MyBatis 的注解复杂映射
1.复杂映射简介
- 在此之前我们已经实现了使用 XML 配置复杂关系映射,可参考2.持久层框架设计实现及MyBatis 源码解析 - 基于 XML 的 Mybatis 应用
- 复杂关系映射使用的注解:
2.一对一查询
-
一对一查询模型
- 用户表和订单表的关系为:一个用户有多个订单,一个订单只从属于一个用户
- 一对一查询的需求:查询一个订单,与此同时查询出该订单的所属用户
-
一对一查询语句
-
查看 orders 表数据
-
查看 user 表数据
-
编写一对一查询语句并执行:
select * from orders o; select * from user u where u.id = 查询出的订单中的 uid;
-
-
MyBatis 实现一对一
-
编写 Orders 实体类
public class Orders { private Integer id; private String ordertime; private Double total; private User user; // set、get、toString 方法省略。。。 }
-
编写 User 实体类
public class User { private Integer id; private String username; // set、get、toString 方法省略。。。 }
-
创建 OrdersDao 接口
public interface OrdersDao { @Results({ // 指定 Orders实体类 和 orders 表的映射 @Result(property = "id",column = "id"), // 指定 Orders实体类 和 orders 表的映射 @Result(property = "ordertime",column = "ordertime"), // 指定 Orders实体类 和 orders 表的映射 @Result(property = "total",column = "total"), // 配置 订单和用户 一对一的关系。property配置的是Orders中的属性名,column配置的是orders表中的字段名 // javaType配置的是orders中uid字段关联的对象class // one配置的是查询orders中uid字段关联的对象的方法 @Result(property = "user",column = "uid",javaType = User.class, one = @One(select = "com.mfc.dao.UserDao.findUserById")) }) @Select("select * from orders") public List<Orders> findOrders(); }
-
创建 UserDao 接口
public interface UserDao { @Select("select * from user where id=#{id}") public List<User> findUserById(Integer id); }
-
编写测试类
@org.junit.Test public void test() throws Exception{ InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(inputStream); SqlSession sqlSession = factory.openSession(); OrdersDao ordersDao = sqlSession.getMapper(OrdersDao.class); List<Orders> orders = ordersDao.findOrders(); for (Orders order : orders) { System.out.println(order); } sqlSession.close(); }
-
测试结果
-
3.一对多查询
-
一对多查询模型
- 用户表和订单表的关系为:一个用户有多个订单,一个订单只从属一个用户
- 一对多查询需求:查询一个用户,以此同时查询出该用户具有的订单
-
一对多查询语句
-
查看 orders 表数据
-
查看 user 表数据
-
编写一对多查询语句并执行:
select * from user u; select * from orders o where o.uid = 查询出来的用户 id;
-
-
MyBatis 实现一对多
- 编写 Orders 实体类
public class Orders { private Integer id; private String ordertime; private Double total; private Integer uid; // set、get、toString 方法省略。。。 }
- 编写 User 实体类
public class User { private Integer id; private String username; private List<Orders> orders = new ArrayList<>(); // set、get、toString方法省略。。。 }
- 编写 UserDao 接口
public interface UserDao { @Results({ // 指定 User实体类 和 user 表的映射 @Result(property = "id",column = "id"), // 指定 User实体类 和 user 表的映射 @Result(property = "username",column = "username"), // 配置 用户和订单 一对多的关系。property配置的是User实体类中的属性名,column配置的是user表中的字段名 // javaType配置的是多的一方的集合对象 // many配置的是查询user中id字段关联的Orders对象的方法 @Result(property = "orders",column = "id",javaType = List.class, many = @Many(select = "com.mfc.dao.OrdersDao.findOrdersById")) }) @Select("select * from user") public List<User> findUsers(); }
- 编写 OrdersDao
public interface OrdersDao { @Select("select * from orders where uid=#{uid}") public List<Orders> findOrdersById(Integer uid); }
- 测试类
@org.junit.Test public void test() throws Exception{ InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(inputStream); SqlSession sqlSession = factory.openSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> users = userDao.findUsers(); for (User user : users) { System.out.println(user); } sqlSession.close(); }
- 测试结果
- 编写 Orders 实体类
4.多对多查询
-
多对多查询模型
- ⽤户表和⻆⾊表的关系为,⼀个⽤户有多个⻆⾊,⼀个⻆⾊被多个⽤户使⽤
- 多对多查询的需求:查询⽤户同时查询出该⽤户的所有⻆⾊
-
多对多查询语句
-
查看 user 表数据
-
查看中间表 user_role 数据
-
查看 role 表数据
-
编写多对多查询语句并执行
select * from user; select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=⽤户的id
-
-
MyBatis 实现多对多
- 编写 User 实体类
public class User { private Integer id; private String username; private List<Role> roles = new ArrayList<>(); // set、get、toString方法省略。。。 }
- 编写 Role 实体类
public class Role { private Integer id; private String rolename; // set、get、toString方法省略。。。 }
- 编写 UserDao 接口
public interface UserDao { @Results({ // 指定 User实体类 和 user 表的映射 @Result(property = "id",column = "id"), // 指定 User实体类 和 user 表的映射 @Result(property = "username",column = "username"), // 配置 用户和订单 一对多的关系。property配置的是User实体类中的属性名,column配置的是user表中的字段名 // javaType配置的是多的一方的集合对象 // many配置的是查询user中id字段关联的Orders对象的方法 @Result(property = "roles",column = "id",javaType = List.class, many = @Many(select = "com.mfc.dao.RoleDao.findRoleByUid")) }) @Select("select * from user") public List<User> findUsers(); }
- 编写 RoleDao 接口
public interface RoleDao { @Select("select * from role r,user_role ur where r.id=ur.rid and ur.uid=#{uid}") public List<Role> findRoleByUid(Integer uid); }
- 测试类
@org.junit.Test public void test() throws Exception{ InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(inputStream); SqlSession sqlSession = factory.openSession(); UserDao userDao = sqlSession.getMapper(UserDao.class); List<User> users = userDao.findUsers(); for (User user : users) { System.out.println(user.getUsername()); List<Role> roles = user.getRoles(); for (Role role : roles) { System.out.println(role); } System.out.println("===================="); } sqlSession.close(); }
- 测试结果
- 编写 User 实体类