首页 > 其他分享 >MyBatis2(MyBatis基础配置 动态代理 映射器 select 元素 insert 元素 update 元素和delete 元素 resultMap 元素 多表联查)

MyBatis2(MyBatis基础配置 动态代理 映射器 select 元素 insert 元素 update 元素和delete 元素 resultMap 元素 多表联查)

时间:2024-07-02 22:55:31浏览次数:3  
标签:insert StudentMapper 多表 元素 List System sqlSession println public

目录

一、MyBatis基础配置

1. MyBatis配置文件

2. < configuration>元素

3. < enviroments>元素

4. < properties>元素

5. < typeAliases>元素

6. < mappers>元素

二、动态代理

三、映射器

1. 映射器与接口

2. 映射器的引入 

3. 映射器的组成 

四、select 元素

参数传递

多个参数传递 

方法1:JavaBean 方式​编辑

方法2:Map 方式

​编辑

方法3:arg0 方式 

方法4:param1方式 

五、insert 元素 

主键回填 

示例所有代码

六、update 元素和delete 元素

update 元素

delete 元素 

七、resultMap 元素 

八、多表联查

 一对一

一对多 

多对多 

级联的缺陷 


一、MyBatis基础配置

1. MyBatis配置文件

  • 功能:构建SqlSessionFactory的依据。
  • 意义:MyBatis最为核心的内容,对MyBatis的使用影响很大。
  • 注意:配置文件的层次顺序不能颠倒,一旦颠倒会出现异常。

主配置文件:

<?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>
	<!-- 和spring整合后 environments配置将废除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.cj.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/myhomework03?serverTimezone=GMT" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/zkt/mapper/student.xml" />
	</mappers>
</configuration>

  • 驱动类 JDBC 驱动类的名称
  • URL 所连接数据库的 URL
  • 用户名 所连接数据库的用户名
  • 密码 所连接数据库的密码

配置文件的层级结构

2. < configuration>元素

功能:标识配置文件的起始,所有配置信息都存放在这里。

3. < enviroments>元素

功能:配置数据库环境信息,注册数据源, 配置数据库事务。

  • <enviroment>:单个环境信息的标识
  • <transactionManager>:配置数据库事务;

数据库事务

●JDBC 使用 JDBC 的事务管理机制,就 是利用 java.sql.Connection 对 象完成对事务的提交;

●MANAGED 使用MANAGED 的事务管理机 制,这种机制MyBatis 自身不 会去实现事务管理,而是让程序 的容器(JBOSS,WebLogic)来 实现对事务的管理;

●自定义 由使用者自定义数据库事务的管 理方式,适用于特殊应用。

  • <dataSource>:配置环境信息中数据源连接的信息。

数据源       

        UNPOOLED 非连接池的数据源

        POOLED 连接池的数据源

        JNDI JNDI的数据源

        自定义数据源 其他类型数据源

  • <property>:配置环境信息的属性;

4. < properties>元素

功能:配置属性的元素,可以在配置文件的上下文中使用 该属性。

properties 配置文件

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/myhomework03?serverTimezone=GMT
jdbc.username=root
jdbc.password=123456

​

程序参数传递

property 子元素

                <property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />

使用:

将jdbc.properties 放到src目录下

使用建议

  • 不要使用混合方式,以避免管理混乱
  • 首选的方式是 Properties 文件方式
  • 如存在加密或者安全访问的问题,使用 第二种方式,为日后统一管理提供方便

5. < typeAliases>元素

别名 sqlMapper.xml 中用

Mybatis内部支持的别名:

别名映射的类型别名映射的类型
_bytebytebyteByte
_longlonglongLong
_shortshortshortShort
_intintintegerInteger
_integerintdoubleDouble
_doubledoublefloatFloat
_floatfloatbooleanBoolean
_booleanbooleandateDate
stringStringdecimalBigDecimal
bigdecimalBigDecimalmapMap
别名和大小写无关

功能:我们使用Mybatis 需要将查询的虚拟表映射为java中的实体类的对象,就需 要让Mybatis知道这些我们自定义的“类型”。 

在主配置文件中进行配置

<typeAliases>
		<package name="com.zkt.bean"/>
	</typeAliases>

在StudentMapper.xml 中可以使用类名

别名和大小写无关

6. < mappers>元素

功能:用来在MyBatis初始化的时候引入映射器。

<mappers>层次结构

用第三种方法

最终的主配置文件:

<?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>

	<properties resource="jdbc.properties">	</properties>
	
	<typeAliases>
		<package name="com.zkt.bean"/>
	</typeAliases>
	
	<!-- 和spring整合后 environments配置将废除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url" value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<!-- <mapper resource="com/zkt/mapper/StudentMapper.xml" /> -->
		<package name="com.zkt.mapper"/>
	</mappers>
</configuration>

 把接口和sqlmapper.xml放到一个包下

同包同名同路径

注册指定包下的所有mapper接口 

 这样就可以将mapper包下的sqlMapper.xml文件读取到

面试题

为什么不能用方法的重载

使用了动态代理

要求了方法名要和id一致

又因为mybatis 要求id不允许重复

所以不能实现方法的重载

二、动态代理

        在接口中有方法的返回值定义,参数的定义,方法名,在sqlMapper.xml 中也对应这接口给予了赋值, 这时候dao的实现类就显得多余,这是Mybatis可以帮助我们自动产生实现类,并可以调取方法得到结 果,这就是Mybatis的mapper动态代理

动态代理的规范

        Mapper接口开发方法只需要程序员编写Mapper接口(相当于Dao接口),由Mybatis框架根据接口定义创建接 口的动态代理对象,代理对象的方法体同上边Dao接口实现类方法。

Mapper接口开发需要遵循以下规范:

  • 1. Mapper.xml文件中的namespace与mapper接口的类路径相同。
  • 2. Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
  • 3. Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql 的parameterType的类型相同
  • 4. Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同

动态代理:

  •         1. 接口中的方法名要和SqlSession中的id一致
  •         2. 接口中的入参 要和 parameterType 类型一致
  •         3. 接口中的方法的出参  要和  resultType 类型一致
  •         4. 接口和sqlMapper 同包
  •         5. 接口和sqlMapper 同名
  •         6. 接口类路径 和 sqlMapper 的namesapce 一致

使用动态代理

使用SqlSession的方法getMapper() 让Mybatis自动生成对应接口的实现对象。

	SqlSession sqlSession = DaoUtil.getSqlSession();
		
		//动态代理
//		1. 接口中的方法名要和SqlSession中的id一致
//		2. 接口中的入参 要和 parameterType 类型一致
//		3. 接口中的方法的出参  要和  resultType 类型一致
//		4. 接口和sqlMapper 同包
//		5. 接口和sqlMapper 同名
//		6. 接口类路径 和 sqlMapper 的namesapce 一致
		
		StudentMapper isd =sqlSession.getMapper(StudentMapper.class);
		
		
		List<Student> sList = isd.findAllStudent();
		sList.forEach(System.out::println);
		DaoUtil.closeResource(sqlSession);
  • selectOne和selectList :动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用 selectList方法,如果返回单个对象则调用selectOne方法。
  • namespace: mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入 参数可以使用pojo包装对象或map对象,保证dao的通用性。

三、映射器

  • 半自动化的体现 配置SQL 语句,体现了半自动化 和灵活性。
  • ORM的体现 对象关系映射的实现,数据库表 和POJO 类的映射关系。

1. 映射器与接口

映射器配置文件和接口绑定:配置文件名对应接口名,id 属性值对应方法名。

2. 映射器的引入 

3. 映射器的组成 

<sql>:提取sql代码 引用sql标签实现sql语句

<parameterMap>:参数的映射(已经弃用)

四、select 元素

语法:

语法规则:
< select 属性=“值”>查询类SQL语句</ select >
属性说明
id唯一标识,接口中的方法名;
parameterType参数的类型;
resultType结果的类型;
resultMap复杂的结果集映射关系;
输出简单类型:                                定义接口方法:
//学生表中一共有多少学生
	public int countStudent();

在StudentMapper.xml中写对应标签和sql语句

<select id="countStudent" resultType="int">
 	select count(*) from student 
</select>

测试:

StudentMapper isd =sqlSession.getMapper(StudentMapper.class);
		int c = isd.countStudent();
		System.out.println("一共有"+c+"个学生");	
	    DaoUtil.closeResource(sqlSession);

参数传递

  • XML 文件中:配置文件中利用parameterType 属性设置参数类型,利用 #{}设置参数的使用及位置。
  • 接口中:接口中,按照方法的入参方式指定参数类型和参数名称。

如果条件有> < >= <= 可以使用转义字符进行代替:

符号小于小于等于大于大于等于单引号双引号
原符号<<=>>=&'"
替换符号&lt;&lt;=&gt;&gt;=&amp;&apos;&quot;
StudentMapper.xml
<select id="findStudentxiaoyuNum" resultType="Student" parameterType="int">
 	select * from student where sid &lt; #{v}
</select>

StudentMapper.java

	//学生标号小于num
	public List<Student> findStudentxiaoyuNum(int num);

测试:

		StudentMapper isd =sqlSession.getMapper(StudentMapper.class);
        List<Student> sList = isd.findStudentxiaoyuNum(5);
		sList.forEach(System.out::println);
        DaoUtil.closeResource(sqlSession);

多个参数传递 

方法1:JavaBean 方式

StudentMapper.xml

<select id="findStudentBySsexAndClassid" resultType="Student" parameterType="Student">
 	select * from student where ssex= #{ssex} and classid= #{classid}
</select>

StudentMapper.java

//多参 --->增删改查
	//1. 对象
	public List<Student> findStudentBySsexAndClassid(Student s);

测试:

		StudentMapper isd =sqlSession.getMapper(StudentMapper.class);
   		Student s = new Student();
		s.setSsex("男");
		s.setClassid(1);
		System.out.println(isd.findStudentBySsexAndClassid(s));
        DaoUtil.closeResource(sqlSession);

方法2:Map 方式

 耦合度太高

StudentMapper.xml

<select id="findStudentPageByMap" resultType="Student" parameterType="map">
 	select * from student limit #{wz},#{bc}
</select>

StudentMapper.java

//分页查看学生信息 limit 位置 ,步长 Map
	//2.Map
	public List<Student> findStudentPageByMap(Map<String, Integer> map);

测试:

		StudentMapper isd =sqlSession.getMapper(StudentMapper.class);
   		Map<String, Integer> map= new HashMap<String, Integer>();
		map.put("wz", (1-1)*3);
		map.put("bc", 3);
		List<Student> sList = isd.findStudentPageByMap(map);
		sList.forEach(System.out::println);
        DaoUtil.closeResource(sqlSession);

方法3:arg0 方式 

StudentMapper.xml

<select id="findStudentBySsexAndClassidArgs" resultType="Student" >
 	select * from student where ssex= #{arg0} and classid= #{arg1}
</select>

StudentMapper.java

//3.arg0... 尽量不使用 会失效
	public List<Student> findStudentBySsexAndClassidArgs(String sex,int classid);

测试:

	StudentMapper isd =sqlSession.getMapper(StudentMapper.class);
   	List<Student> sList = isd.findStudentBySsexAndClassidArgs("女", 2);
	sList.forEach(System.out::println);
    DaoUtil.closeResource(sqlSession);

方法4:param1方式 

StudentMapper.xml

<select id="findStudentBySsexAndClassidParams" resultType="Student" >
 	select * from student where ssex= #{param1} and classid= #{param2}
</select>

StudentMapper.java

//4.param1...
	public List<Student> findStudentBySsexAndClassidParams(String sex,int classid);

测试:

	StudentMapper isd =sqlSession.getMapper(StudentMapper.class);
    List<Student> sList = isd.findStudentBySsexAndClassidParams("女", 2);
	sList.forEach(System.out::println);
    DaoUtil.closeResource(sqlSession);

五、insert 元素 

语法:

语法规则:
< insert 属性=“值”>新增类SQL语句</ insert >

属性说明
id唯一标识,接口中的方法名;
parameterType参数的类型;
keyProperty(属性名)表示以哪个列作为属性的主键,不能和keyColumn同时使用;
keyColumn(字段名)指明哪一列是主键,不能和keyProperty同时使用;
useGeneratedKeys使用JDBC的getGeneratedKeys方式来取有数据库内部生成的主键;

主键回填 

功能:当主键在数据库中为自增字段时,新增成功后,回填主键。

StudentMapper.xml

	<!--
			主键回填
	 	useGeneratedKeys="true"  开启主键回填
	 	keyProperty="sid"  把主键数据回填给对象的属性
 	-->
<insert id="addStudent" parameterType="Student"  useGeneratedKeys="true" keyProperty="sid">
	insert into student(sname,birthday,ssex,classid)
	values(#{sname},#{birthday},#{ssex},#{classid})
</insert>

StudentMapper.java

//新增
	public int addStudent(Student s);

测试:

	StudentMapper isd =sqlSession.getMapper(StudentMapper.class);
   //添加学生 --> 添加该学生的入学成绩
		Student s = new Student();
		s.setSsex("男");
		s.setClassid(1);
		s.setSname("zkt77");
		s.setBirthday(new Date());
		
		System.out.println("添加前"+s);
		int ret =isd.addStudent(s);
		System.out.println("添加后"+s);

		if (ret>0) {
			System.out.println("添加成功");
			sqlSession.commit();
		}else {
			System.out.println("添加失败");
			sqlSession.rollback();
		}
    DaoUtil.closeResource(sqlSession);

示例所有代码

Student.java

public class Student {

	//属性 对应 数据库中的字段 ---名字一致 类型一致
	//长像相似就行
	private int sid;
	private String sname;
	private Date birthday;
	private String ssex;
	private int classid;
	
	//1:1外部属性
	private Banji bj;

     get/set 方法 
     构造方法省略。。。
}

StudentMapper.xml

<?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.zkt.mapper.StudentMapper">

	<select id="findAllStudent" resultType="student">
		select * from student
	</select>

	<select id="countStudent" resultType="int">
		select count(*) from student
	</select>

	<select id="findStudentSname" resultType="String">
		select sname from student
	</select>

	<select id="findStudentxiaoyuNum" resultType="Student"
		parameterType="int">
		select * from student where sid &lt; #{v}
	</select>

	<select id="findStudentBySsexAndClassid" resultType="Student"
		parameterType="Student">
		select * from student where ssex= #{ssex} and classid= #{classid}
	</select>

	<select id="findStudentPageByMap" resultType="Student"
		parameterType="map">
		select * from student limit #{wz},#{bc}
	</select>

	<select id="findStudentBySsexAndClassidArgs"
		resultType="Student">
		select * from student where ssex= #{arg0} and classid= #{arg1}
	</select>

	<select id="findStudentBySsexAndClassidParams"
		resultType="Student">
		select * from student where ssex= #{param1} and classid= #{param2}
	</select>

	<select id="findStudentBySid" resultType="Student"
		parameterType="int">
		select * from student where sid = #{v}
	</select>

	<!-- 主键回填 useGeneratedKeys="true" 开启主键回填 keyProperty="sid" 把主键数据回填给对象的属性 -->
	<insert id="addStudent" parameterType="Student"
		useGeneratedKeys="true" keyProperty="sid">
		insert into student(sname,birthday,ssex,classid)
		values(#{sname},#{birthday},#{ssex},#{classid})
	</insert>


	<!-- 多表 所有字段都要写映射关系 -->
	<resultMap type="Student" id="stu_class_Map">
		<result column="sid" property="sid" />
		<result column="sname" property="sname" />
		<result column="birthday" property="birthday" />
		<result column="ssex" property="ssex" />
		<result column="classid" property="classid" />

		<!--1:1 关系 -->
		<association property="bj">
			<result column="classid" property="classid" />
			<result column="classname" property="classname" />
		</association>
	</resultMap>

	<select id="findStudentAndClass" resultMap="stu_class_Map">
		select * from student
		left join class on student.classid=class.classid
	</select>


	<delete id="deleteStudent" parameterType="int">
		delete from student where sid = #{v}
	</delete>


	<update id="updateStudent" parameterType="Student">
		update student
		set sname = #{sname},
		birthday = #{birthday},
		ssex = #{ssex},
		classid = #{classid}
		where sid = #{sid}
	</update>

</mapper>

StudentMapper.java

package com.zkt.mapper;

import java.util.List;
import java.util.Map;

import com.zkt.bean.Student;

public interface StudentMapper {

	// 新增
	public int addStudent(Student s);

	// 修改
	public int updateStudent(Student s);

	// 删除
	public int deleteStudent(int sid);

	// 查询
	// 单查
	public Student findStudentBySid(int sid);

	// 全查
	public List<Student> findAllStudent();

	// 学生表中一共有多少学生
	public int countStudent();

	// 获取学生表中所有学生的姓名
	public List<String> findStudentSname();

	// 学生标号小于num
	public List<Student> findStudentxiaoyuNum(int num);

	// 多参 --->增删改查
	// 1. 对象
	public List<Student> findStudentBySsexAndClassid(Student s);

	// 分页查看学生信息 limit 位置 ,步长 Map
	// 2.Map
	public List<Student> findStudentPageByMap(Map<String, Integer> map);

	// 3.arg0... 尽量不使用 会失效
	public List<Student> findStudentBySsexAndClassidArgs(String sex, int classid);

	// 4.param1...
	public List<Student> findStudentBySsexAndClassidParams(String sex, int classid);

	// 查询学生和对应的信息

	public List<Student> findStudentAndClass();

}

测试:

package com.zkt.test;

import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.ibatis.session.SqlSession;

import com.zkt.bean.Student;
import com.zkt.dao.DaoUtil;
import com.zkt.mapper.StudentMapper;

public class Test {
	public static void main(String[] args) {
		SqlSession sqlSession = DaoUtil.getSqlSession();

		// 动态代理
//		1. 接口中的方法名要和SqlSession中的id一致
//		2. 接口中的入参 要和 parameterType 类型一致
//		3. 接口中的方法的出参  要和  resultType 类型一致
//		4. 接口和sqlMapper 同包
//		5. 接口和sqlMapper 同名
//		6. 接口类路径 和 sqlMapper 的namesapce 一致

		StudentMapper isd = sqlSession.getMapper(StudentMapper.class);

//		int c = isd.countStudent();
//		System.out.println("一共有"+c+"个学生");
//		List<String> nameList = isd.findStudentSname();
//		nameList.forEach(System.out::println);

//		List<Student> sList = isd.findStudentxiaoyuNum(5);
//		sList.forEach(System.out::println);

//		Student s = new Student();
//		s.setSsex("男");
//		s.setClassid(1);
//		System.out.println(isd.findStudentBySsexAndClassid(s));

//		Map<String, Integer> map= new HashMap<String, Integer>();
//		map.put("wz", (1-1)*3);
//		map.put("bc", 3);
//		List<Student> sList = isd.findStudentPageByMap(map);
//		sList.forEach(System.out::println);

//		List<Student> sList = isd.findStudentBySsexAndClassidArgs("女", 2);

//		List<Student> sList = isd.findStudentBySsexAndClassidParams("女", 2);
//		sList.forEach(System.out::println);

		// 添加学生 --> 添加该学生的入学成绩
		Student s = new Student();
		s.setSsex("男");
		s.setClassid(1);
		s.setSname("zkt77");
		s.setBirthday(new Date());

		System.out.println("添加前" + s);
		int ret = isd.addStudent(s);
		System.out.println("添加后" + s);

		if (ret > 0) {
			System.out.println("添加成功");
			sqlSession.commit();
		} else {
			System.out.println("添加失败");
			sqlSession.rollback();
		}
		DaoUtil.closeResource(sqlSession);

//		Student s = isd.findStudentBySid(5);
//		System.out.println(s);

//		Student s1 =new Student();
//		s1.setSname("刘备");
//		s1.setSsex("男");
//		s1.setBirthday(new Date());
//		s1.setClassid(2);
//		int ret =isd.addStudent(s1);
//		if (ret>0) {
//			System.out.println("添加成功");
//		}else {
//			System.out.println("添加失败");
//		}

//		int ret=isd.deleteStudent(13);
//		if (ret>0) {
//			System.out.println("删除成功");
//		}else {
//			System.out.println("删除失败");
//		}

//		Student s2 =new Student();
//		s2.setSid(9);
//		s2.setSname("张飞");
//		s2.setSsex("女");
//		s2.setBirthday(new Date());
//		s2.setClassid(1);
//		int ret =isd.updateStudent(s2);
//		if (ret>0) {
//			System.out.println("修改成功");
//		}else {
//			System.out.println("修改失败");
//		}

	}
}

六、update 元素和delete 元素

实现方式同上

update 元素

语法:

语法规则:
< update 属性=“值”>查询类SQL语句</ update >

属性说明
id唯一标识,接口中的方法名;
parameterType参数的类型;

delete 元素 

语法:

语法规则:
< delete 属性=“值”>查询类SQL语句</ delete >

属性说明
id唯一标识,接口中的方法名;
parameterType参数的类型;

七、resultMap 元素 

  • 定义映射规则 ORM 的特性,POJO 类和数据 库的映射关系;
  • 级联操作 多表存在主外键关系时,主表和 从表之间的关联操作;
  • 类型转换 数据库字段的类型和POJO 类 属性的类型转换。

resultMap 元素的结构

<resultMap>
     <constructor>
         <idArg />
         <arg />
     </constructor>
     <id />
     <result />
     <association />
     <collection />
     <discriminator>
         <case />
     </discriminator>
 </resultMap>

 <constructor>
用于配置构造方法的元素。
<id>
标识主键列,允许多个主键。
<result>
POJO到SQL列名的映射关系。

使用POJO 存储结果集

练习:

表的结构:
create table schoolmaster(
 smid int PRIMARY KEY auto_increment,
 sm_name varchar(10) ,
 smsex varchar(2)
 );
 insert into schoolmaster(sm_name,smsex) values('老刘','男');

表名和字段名不一致

如果没有做映射处理

我们发现获取表名不一样没有问题 但是字段名不一样会拿不到值

映射处理后

SMaster.java

public class SMaster {

	private int smid;
	private String smname;
	private String smsex;



        get/set 方法 
        构造方法省略。。。
}

SMasterMapper.java

public interface SMasterMapper {

	//新增
	public int addSm(SMaster sm);
	
	//查询
	public List<SMaster> findAllSm();
}

SMasterMapper.xml

<?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.zkt.mapper.SMasterMapper">

	<insert id="addSm"  parameterType="SMaster">
		insert into schoolmaster(sm_name,smsex)
		values(#{smname},#{smsex})
	</insert>

	<!--
		单表查询
		只写映射不上的
	  -->
	<resultMap type="SMaster" id="smMap">
		<result column="sm_name" property="smname" />
	</resultMap>
	
	<select id="findAllSm" resultMap="smMap">
		select * from schoolmaster
	</select>
</mapper>

测试:

public static void main(String[] args) {
		SqlSession sqlSession =DaoUtil.getSqlSession();
		SMasterMapper smMapper =sqlSession.getMapper(SMasterMapper.class);
		
		SMaster sm = new SMaster();
		sm.setSmname("zkt");
		sm.setSmsex("男");
		
		int ret=smMapper.addSm(sm);
		if (ret>0) {
			System.out.println("添加成功");
			sqlSession.commit();
		}else {
			System.out.println("添加失败");
			sqlSession.rollback();
		}
		
//		List<SMaster> sList = smMapper.findAllSm();
//		sList.forEach(System.out::println);

		DaoUtil.closeResource(sqlSession);
		
		
	}

注意: 单表查询 只写映射不上的

八、多表联查

级联(cascade),是指多个对象之间的映射关系,建立数据之间的级联关系提高管理效率

  • 一对一 :一个对象对应唯一的对象, 举例:中国公民和身份证;
  • 一对多 :一个对象对应多个对象, 举例:班级和学生;
  • 多对多 :多个对象对应多个对象, 举例:公司角色和公司员工

 一对一

一对一级联步骤

  1. 创建关联POJO:一对一级联时,以对象方式存 储关联关系;
  2. 创建映射器:创建对应的映射器;
  3. 级联映射:利用 <association>元素完成一对一级联;
  4. 验证:编写测试类验证级联关系;

首先在实体类中添加级联表的对象:

Student.java

public class Student {

	//属性 对应 数据库中的字段 ---名字一致 类型一致
	//长像相似就行
	private int sid;
	private String sname;
	private Date birthday;
	private String ssex;
	private int classid;
	
	//1:1外部属性
	private Banji bj;

     get/set 方法 
     构造方法省略。。。
}

StudentMapper.xml

<!-- 多表 所有字段都要写映射关系 -->
	<resultMap type="Student" id="stu_class_Map">
				<result column ="sid" property ="sid"/>
				<result column ="sname" property ="sname"/>
				<result column ="birthday" property ="birthday"/>
				<result column ="ssex" property ="ssex"/>
				<result column ="classid" property ="classid"/>
	
		<!--1:1 关系  -->
		<association property="bj">
			<result column ="classid" property ="classid"/>
			<result column ="classname" property ="classname"/>
		</association>
	</resultMap> 

	<select id="findStudentAndClass" resultMap="stu_class_Map">
		select * from student left join class on student.classid=class.classid
	</select>

StudentMapper.java

	//查询学生和对应的信息
	
	public List<Student> findStudentAndClass();	

测试:

public class Test04 {
	public static void main(String[] args) {
		SqlSession sqlSession =DaoUtil.getSqlSession();
		StudentMapper stuMapper =sqlSession.getMapper(StudentMapper.class);
		List<Student> sList = stuMapper.findStudentAndClass();
		sList.forEach(System.out::println);

		DaoUtil.closeResource(sqlSession);

	}
}

一对多 

一对多级联步骤

  • 创建”一“方POJO:以集合的形式级联“多”方对象
  • 创建“多”方对象:创建“多”方的POJO 对象
  • 创建映射器:创建对应的映射器
  • 实现一对多级联:利用collection 元素实现一对多的级联
  • 测试:编写测试文件测试一对多级联

首先在实体类中添加级联表的对象list集合:

Banji.java

public class Banji {
    private int classid;
    private String classname;

    //1:N 外部属性
    private List<Student> sList;

    get/set 方法 
    构造方法省略。。。
}

BanjiMapper.java 

public interface BanjiMapper {

	public List<Banji> findBanjiAndStudent();
}

BanjiMapper.xml

<?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.zkt.mapper.BanjiMapper">

	<resultMap type="Banji" id="class_stu_Map">
		<result column="classid" property="classid" />
		<result column="classname" property="classname" />

			<!--1:N  -->
		<collection property="sList" ofType="student">
			<result column="sid" property="sid" />
			<result column="sname" property="sname" />
			<result column="birthday" property="birthday" />
			<result column="ssex" property="ssex" />
			<result column="classid" property="classid" />
		</collection>
	</resultMap>

<select id="findBanjiAndStudent" resultMap="class_stu_Map">
	select * from class left join student on class.classid=student.classid
</select>

</mapper>

 测试:

public class Test05 {
	public static void main(String[] args) {
		SqlSession sqlSession = DaoUtil.getSqlSession();

		BanjiMapper bjMapper = sqlSession.getMapper(BanjiMapper.class);

		List<Banji> sList = bjMapper.findBanjiAndStudent();
		sList.forEach(System.out::println);

		DaoUtil.closeResource(sqlSession);

	}
}

多对多 

换种思路 以 成绩表为主表 对其他俩个表进行联查

bean下

Course.java

public class Course {
	private int cid;
	private String cname;
	private int tid;

   get/set 方法 
    构造方法省略。。。
}

Sc.java

public class Sc {

	private int sid;
	private int cid;
	private double score;
	
	// 外部属性
	private Student stu;
	private Course cou;
    
    get/set 方法 
    构造方法省略。。。
}

mapper下

ScMapper.java

public interface ScMapper {

	public List<Sc> findAllScAndStudentAndCourse();
}

ScMapper.xml

<?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.zkt.mapper.ScMapper">

	<resultMap type="Sc" id="sc_stu_cou_Map">
		<result column="sid" property="sid"/>
		<result column="cid" property="cid"/>
		<result column="score" property="score"/>
		
		<association property="stu">
			<result column="sid" property="sid"/>
			<result column="sname" property="sname"/>
			<result column="birthday" property="birthday"/>
			<result column="ssex" property="ssex"/>
			<result column="classid" property="classid"/>
		</association>
		
		<association property="cou">
			<result column="cid" property="cid"/>
			<result column="cname" property="cname"/>
			<result column="tid" property="tid"/>
		</association>
	
	</resultMap>

	<select id="findAllScAndStudentAndCourse" resultMap="sc_stu_cou_Map">
		select * from sc 
		inner join student on sc.sid = student.sid
		inner join course on course.cid = sc.cid
	</select>
	
	
</mapper>

测试:

public class Test06 {
	public static void main(String[] args) {
		SqlSession sqlSession = DaoUtil.getSqlSession();
		ScMapper scmapper = sqlSession.getMapper(ScMapper.class);

		List<Sc> sclist = scmapper.findAllScAndStudentAndCourse();

		for (Sc sc : sclist) {
			System.out.println(sc.getStu().getSname() + "-" + sc.getCou().getCname() + "-" + sc.getScore());
		}

		DaoUtil.closeResource(sqlSession);
	}
}

级联的缺陷 

  • 性能缺陷 级联操作会降低性能, 增加程序的执行时间;
  • 复杂度缺陷 关联较多造成复杂度的 增加,不利于他人的理 解和维护;

使用建议
1、根据实际情况增加级联关系
2、多层关联式,建议超过三层关联时尽量少用级联

 

标签:insert,StudentMapper,多表,元素,List,System,sqlSession,println,public
From: https://blog.csdn.net/qq_52897007/article/details/140118002

相关文章

  • 数组-移除元素
    移除元素移除元素(leetcode27)varremoveElement=function(nums,val){constn=nums.length;letleft=0;for(letright=0;right<n;right++){if(nums[right]!==val){nums[left]=nums[right];left++......
  • Python123:找出不是两个数组共有的元素、矩阵运算、方阵循环右移(C语言)
    文章目录1、找出不是两个数组共有的元素2、矩阵运算3、方阵循环右移1、找出不是两个数组共有的元素题目:给定两个整型数组,本题要求找出不是两者共有的元素。输入格式:输入分别在两行中给出两个整型数组,每行先给出正整数N(≤20),随后是N个整数,其间以空格分隔。‪‬‪......
  • JavaScript 中删除数组元素
    在JavaScript中,没有像Java的ArrayList中的remove方法那样直接删除指定元素的方法,删除指定下标的数组元素可以通过几种方式实现方法一:使用 splice() 方法splice()方法可以在数组中添加或删除元素,并返回被删除的元素。letarr=[1,2,3,4,5];letindexToRemove......
  • WPF 中 StackPanel 控件的可视化 Visibility.Collapsed 控件元素会自动前移
    XAML:<Grid><Grid.RowDefinitions><RowDefinition/><RowDefinitionHeight="Auto"/></Grid.RowDefinitions><StackPanelGrid.Row="0"><TextBoxx:Name="txb_001&quo......
  • SMS多表面同步透镜设计
    SMS多表面同步透镜设计一、设计原理1、Snell定律的矢量形式折射定律又称Snell定律,主要包括两个方面:一是入射光线、法线和折射光线共面,二是入射角和折射角满足以下关系:n1......
  • 解决Vue template模板中单一根元素
    引言错误的用法会导致页面加载空白<template><divid="1">内容1<div><divid="2">内容2<div></template>解决Vue模板中单一根元素要求的问题及原理解析在Vue.js开发中,单一根元素的要求是确保Vue能够有效地编译和渲染组件的重要规则之一。本文将深入探讨这一......
  • 9、爬虫-xpath-selenium爬取网页隐藏元素
    安装:pipinstalllxml1、导入:fromlxmlimportetree2、创建对象:  tree=etree.XML(xml文件)  tree=etree.HTML(html文件)  等3、找标签:  tree.xpath("//book/name/text()")4、语法:  text()表示取节点标记的文字  tree.xpath("//book/publisher[3]/text()......
  • 【算法探险】在排序数组中查找元素的第一个和最后一个位置
    【算法探险】在排序数组中查找元素的第一个和最后一个位置一、引言:算法界的寻宝图二、技术概述:双剑合璧,左右逢源定义与核心特性优势代码示例:初露锋芒三、技术细节:抽丝剥茧,揭秘算法奥秘原理解析难点剖析四、实战应用:数字海洋,定位精准应用场景案例展示五、优化与改进:精......
  • 让一个元素水平垂直居中的方式
    1.定位+margin<style>*{margin:0;padding:0;}.father{width:400px;height:400px;border:1pxsolid;position:relative;}.son{position:absolute;width:200px;height:200px;background-color:red;top:0;right:0;......
  • 元素的简单操作
    针对元素的简单操作:(1)点击:element.click() (2)输入内容、清除内容:element.send_keys("内容")element.clear() (3)返回元素尺寸、坐标:element.sizeelement.location (4)获取元素标签文本:element.text (5)获取元素属性值:element.get_attribute("属性名") (6)检查元素:是......