Mybatis 一对一、一对多、多对一
灵感来源于:https://www.cnblogs.com/xdp-gacl/p/4264440.html
关于select标签一些属性功能如下:
1、id:命名空间内唯一标识符,用来被引用这条语句。
2、parameterType:用来指定传入参数的完全限定名或别名。
3、resultType:指定返回的期望的完全限定名或别名,如果是集合,应该为集合包含的类型 ,不能和resultMap共存。
4、resultMap:命名引用外部的resultMap。
5、flushCache:默认false,设置为true,则不论语句什么时候被调用,都会清空缓存。
6、useCache:默认值true,会缓存本次语句结果。
7、timeout:这个设置驱动程序等待数据库返回请求结果,并抛出异常时间的最大等待值。默认不设置(驱动自行处理)。
8、fetchSize:暗示程序每次返回的结果行数。
9、statementType:STATEMENT、PREPARED、CALLABLE中的一种,让MyBatis选择使用Statement、PreparedStatement、CallableStatement。默认是PREPARED。
10、resultSetType:FORWARD_ONLY|SCROOL_SENSITIVE|SCROLL_INSENSITIVE中的一种,默认是不设置(驱动自行处理)。
---------------------
级联有三种对应关系:
1.一对一(association):如学号与学生
2.一对多(collection):如角色与用户
3.多对多(discriminator)鉴别器:如一个角色可以对应多个用户,一个用户也可以兼任多个角色
---------------------
每个Hibernate session的基本操作包括persist()、merge()、saveOrUpdate()、delete()、lock()、refresh()、evict()、replicate(),这些操作都有对应的级联风格(cascade style)。这些级联风格(cascade style)风格分别命名为persist、merge、save-update、delete、lock、refresh、evict、replicate。
在hibernate的配置文件中,有cascade属性,供我们设置关联表的增删改,但是在mybatis中,并没有这样的机制,因此需要我们自己去写。
1.事务处理。2.在数据库中设置外键。3.触发器
-
在创建表的时候就对外键定义成级联删除或者更新
父级 主键被其它表作为外键 子级表示把其它表的主键作为自己的外键
RESTRICT、NO ACTION、SET NULL 和 CASCADE
RESTRICT、NO ACTION是指在子表有关联记录的情况下父表不能更新
SET NULL 表示父级在更新或者删除时将子记录列的值设为null
ON DELETE CASCADE 表示父记录删除时子记录对应的列数据也删除
ON UPDATE CASCADE 表示父记录更新时子记录对应的列数据也更新
---------------------
--------------------
转发自:https://www.cnblogs.com/hq233/p/6752335.html
首先 数据库量表之间字段关系(没有主外键)
studentmajor表的id字段对应student表里major字段
两个实体类
package com.model; import java.util.Date; public class Student { private Integer sno; private String sname; private String ssex; private Integer sclass; private StudentMajor studentmajor; public Student() { super(); } public Student(Integer sno, String sname, String ssex, Integer sclass, StudentMajor studentmajor) { super(); this.sno = sno; this.sname = sname; this.ssex = ssex; this.sclass = sclass; this.studentmajor = studentmajor; } public StudentMajor getStudentmajor() { return studentmajor; } public void setStudentmajor(StudentMajor studentmajor) { this.studentmajor = studentmajor; } public Integer getSno() { return sno; } public void setSno(Integer sno) { this.sno = sno; } public String getSname() { return sname; } public void setSname(String sname) { this.sname = sname; } public String getSsex() { return ssex; } public void setSsex(String ssex) { this.ssex = ssex; } @Override public String toString() { return "Student [sno=" + sno + ", sname=" + sname + ", ssex=" + ssex + ", sclass=" + sclass + ", studentmajor=" + studentmajor + "]"; } public Integer getSclass() { return sclass; } public void setSclass(Integer sclass) { this.sclass = sclass; } }
package com.model; import java.util.List; public class StudentMajor { private Integer id; private String mcode; private String mname; private List<Student> students; public StudentMajor() { super(); } public StudentMajor(Integer id, String mcode, String mname, List<Student> students) { super(); this.id = id; this.mcode = mcode; this.mname = mname; this.students = students; } @Override public String toString() { return "StudentMajor [id=" + id + ", mcode=" + mcode + ", mname=" + mname + ", students=" + students + "]"; } public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getMcode() { return mcode; } public void setMcode(String mcode) { this.mcode = mcode; } public String getMname() { return mname; } public void setMname(String mname) { this.mname = mname; } public List<Student> getStudents() { return students; } public void setStudents(List<Student> students) { this.students = students; } }
定义两个接口
package com.dao; import java.util.List; import java.util.Map; import com.model.Student; public interface StudentMapper { /** * 全表查询 */ public List<Student> selectall(); /** * 根据专业查人员,给一对多用 */ public List<Student> selectz(Integer major); }
package com.dao; import java.util.List; import com.model.StudentMajor; public interface StudentMajorMapper { /** * 全表查询 * @return */ public List<StudentMajor> selectAll(); /** * 根据主键查数据,给多对一用 * @param id * @return */ public StudentMajor select(Integer id); }
定义两个实体类的映射方法
灵感参考===start
灵感参考==end
<?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.dao.StudentMapper"> <!-- 多对一查询 --> <resultMap type="Student" id="slist"> <!-- 跟一对一一样用association标签,实体类定义的成员,要跟数据库字段名对应上 --> <association property="studentmajor" column="major" select="com.dao.StudentMajorMapper.select"/> <!-- 用接口里定义的方法,根据student表中的major字段查出对应数据 --> </resultMap> <!-- 查全部 --> <select id="selectall" resultMap="slist" > select * from student </select> <!-- 根据专业查人员 --> <select id="selectz" parameterType="Integer" resultType="student"> select * from student s where s.major=#{major} </select> </mapper>
<?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.dao.StudentMajorMapper"> <!-- 一对多查询关联 --> <resultMap type="StudentMajor" id="slist"> <!-- 实体类属性对应数据库的主键字段,不然主键会查不到 --> <id property="id" column="id"/> <!-- 用collection标签 ,也是实体类属性要对应数据库字段--> <collection property="students" column="id" select="com.dao.StudentMapper.selectz"> </collection> </resultMap> <!-- 全表查询 --> <select id="selectAll" resultMap="slist"> select * from studentmajor </select> <!-- 根据主键查 --> <select id="select" parameterType="Integer" resultType="StudentMajor"> select * from studentmajor where id=#{id} </select> </mapper>
JUnit测试
package com.util; import java.util.List; import org.apache.ibatis.session.SqlSession; import org.junit.After; import org.junit.Before; import org.junit.Test; import com.dao.StudentMajorMapper; import com.dao.StudentMapper; import com.model.Student; import com.model.StudentMajor; public class JJJtest { private SqlSession ss; private StudentMapper sm; private StudentMajorMapper smm; @Before public void setUp() throws Exception { ss=SqlSessionUtil.getSqlSession(); sm=ss.getMapper(StudentMapper.class); smm=ss.getMapper(StudentMajorMapper.class); } @After public void tearDown() throws Exception { ss.commit(); ss.close(); } //一对多查询 public void test() { List<StudentMajor> list=smm.selectAll(); for(StudentMajor a:list){ System.out.println(a); } } //根据专业查人员,给一对多用 public void selectz(){ List<Student> l=sm.selectz(3); for(Student a:l){ System.out.println(a); } }
//多对一查询 @Test public void selectall() { List<Student> st=sm.selectall(); for(Student tt:st){ System.out.println(tt); } } //根据主键查询,给多对一用 public void select(){ StudentMajor a=smm.select(1); System.out.println(a); } }
一对多查询结果
多对一查询结果
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现