点一下关注吧!!!非常感谢!!持续更新!!!
大数据篇正在更新!
- MyBatis(正在更新)
一对多
查询模型
用户表和订单表的关系为,一个用户有多个订单,一个订单只属于一个用户,一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单。
一对多优点
数据清晰,关系明确。
数据完整性可以通过外键约束强制维护。
查询灵活,通过关联表可以获取丰富的数据。
一对多缺点
对于复杂查询,可能涉及多次连接(JOIN),性能稍差。
数据模型耦合较紧,当表结构发生变更时,影响范围较大。
编写代码
UserMapper
修改 UserMapper,加入新的方法findAllUserAndOderWithAnnotation,通过注解的方式实现:
@Select("select * from wzk_user")
@Results({
@Result(id = true, property = "id", column = "id"),
@Result(property = "username", column = "username"),
@Result(property = "password", column = "password"),
@Result(property = "birthday", column = "birthday"),
@Result(property = "roleList", column = "id", javaType = List.class,
many = @Many(select = "icu.wzk.mapper.OrderMapper.findByUserIdWithAnnotation"))
})
List<WzkUser> findAllUserAndOderWithAnnotation();
对应的截图如下所示:
OrderMapper
修改 OrderMapper,加入了 findByUserIdWithAnnotation,因为在 UserMapper 中,刚才的方法需要调用。
@Select("select * from wzk_orders where id = #{id}")
List<WzkOrder> findByUserIdWithAnnotation(int id);
对应的截图如下所示:
调用代码
public class WzkIcu12 {
public static void main(String[] args) throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<WzkUser> dataList = userMapper.findAllUserAndOderWithAnnotation();
dataList.forEach(System.out::println);
sqlSession.close();
}
}
对应的截图如下所示:
测试结果
控制台输出的结果如下所示:
WzkUser(id=1, username=wzk, password=icu, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=[WzkOrder(id=1, ordertime=Mon Nov 11 00:00:00 CST 2024, total=100.0, user=null)])
WzkUser(id=2, username=wzk2, password=icu2, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=[WzkOrder(id=2, ordertime=Mon Nov 11 00:00:00 CST 2024, total=200.0, user=null)])
24/11/13 09:34:12 DEBUG jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@75329a49]
对应的截图如下所示:
多对多
查询模型
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用,多对多的查询的需求:查询用户同时查询出该用户的所有角色
在数据库设计中,“多对多”关系是指两张表中的记录可以互相关联,多条记录可以关联多条记录。例如,“学生”表和“课程”表之间的关系可能是多对多,因为一个学生可以选修多门课程,而一门课程也可能被多名学生选修。
要实现多对多的关系,通常需要使用一个 中间表(关联表)。这个中间表起到桥梁的作用,将两个表的记录通过其主键关联起来。
多对多关系的特点
- 双向性:A可以关联多个B,同时B也可以关联多个A。
- 需要中间表:为了表示这种关系,通常使用一个中间表来维护关联。
- 灵活性高:多对多关系非常适合用来表示复杂的业务逻辑,尤其是在需要动态添加或修改关系时。
多对多关系的扩展
添加额外字段
中间表可以扩展为更多功能。例如,可以为选课添加时间戳、成绩字段、是否通过等。
索引优化
为中间表中的外键添加索引,提高查询性能。
ORM 框架支持
现代框架(如 Hibernate、Django ORM)支持多对多关系的自动管理。在代码中只需要声明模型的关系,底层会自动生成并管理中间表。
编写代码
UserMapper
修改 UserMapper,加入新的方法findAllUserAndRoleWithAnnotation,使用注解来实现:
@Select("select * from wzk_user")
@Results({
@Result(id = true,property = "id",column = "id"),
@Result(property = "username",column = "username"),
@Result(property = "password",column = "password"),
@Result(property = "birthday",column = "birthday"),
@Result(property = "roleList",column = "id",
javaType = List.class,
many = @Many(select = "icu.wzk.mapper.RoleMapper.findByUserIdWithAnnotation"))
})
List<WzkUser> findAllUserAndRoleWithAnnotation();
对应的截图如下所示:
RoleMapper
新建了 RoleMapper:
public interface RoleMapper {
@Select("select * from wzk_role r, wzk_user_role ur where r.id=ur.role_id and ur.user_id=#{uid}")
List<WzkRole> findByUserIdWithAnnotation(int uid);
}
对应的截图如下所示:
调用代码
public class WzkIcu13 {
public static void main(String[] args) throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
List<WzkUser> dataList = userMapper.findAllUserAndRoleWithAnnotation();
dataList.forEach(System.out::println);
sqlSession.close();
}
}
对应的截图如下所示:
测试结果
对上述的代码进行执行,控制台输出的结果如下所示:
24/11/13 10:01:13 DEBUG UserMapper.findAllUserAndRoleWithAnnotation: <== Total: 2
WzkUser(id=1, username=wzk, password=icu, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=[WzkRole(id=1, rolename=ADMIN)])
WzkUser(id=2, username=wzk2, password=icu2, birthday=Mon Nov 11 00:00:00 CST 2024, orderList=null, roleList=[WzkRole(id=2, rolename=USER)])
24/11/13 10:01:13 DEBUG jdbc.JdbcTransaction: Resetting autocommit to true on JDBC Connection [com.mysql.cj.jdbc.ConnectionImpl@1e802ef9]
对应的截图如下所示:
注解模式的优缺点
优点
- 开发简单:无需复杂的 XML 配置文件。
- 代码集中:SQL 语句和逻辑写在一起,便于维护。
- 便捷性:适合简单的 CRUD 操作,代码量少。
缺点
- 可读性差:SQL 语句嵌入代码,可能不易阅读。
- 复杂 SQL 不易维护:对于复杂 SQL,注解模式不如 XML 清晰。
- 可扩展性有限:不易支持动态 SQL 和高级功能。