MyBatis Day03(20210927)

一.封装工具类

package com.neudeu.util;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class MybatisUtils {
	
	private static SqlSessionFactory sqlSessionFactory;

	static {
		try {
			// 定义mybaties的配置文件路径
			String resource = "SqlMapConfig.xml";
			// 得到配置文件流
			InputStream inputStream = Resources.getResourceAsStream(resource);
			// 创建会话工厂,传入mybaties的配置文件流
			sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
		
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	public static SqlSession getSession() {
		return sqlSessionFactory.openSession();
	}

}

二.数据库操作

1.插入记录,并获取主键

sql增删改都会返回int值,表示影响的行数,但insert标签中不能写resultType属性,所以想要获得插入记录的主键值需要经过一定处理;
常见于 插入于A表的该行记录主键 要作为 B表要插入记录的外键 时应用;

1.1使用selectKey标签
  • keyProperty属性:就是主键名,对应java属性名;
  • resultType属性:指的是主键的数据类型;
  • order属性:执行的顺序 对应after和before两个值
    before:先获取主键,在insert之前;
    after:先insert,再获取主键;

DeptMapper.xml

<mapper namespace="com.neuedu.mapper.DeptMapper">

	<!-- 插入部门信息 -->
	<insert id="insertDept" parameterType="Dept" >
		<!-- 获取主键 方式一:使用selectKey标签-->
		 <selectKey keyProperty="deptno" resultType="int" order="AFTER">
			select LAST_INSERT_ID()
		</selectKey> 	
		insert into dept(dname,loc) values(#{dname},#{loc})
	</insert>
	
</mapper>
1.2 使用useGeneratedKeys属性
  • useGeneratedKeys设置为true ,自动获取数据库中的主键;
  • keyProperty属性值设置为主键名;
  • 只适用与有自增长的数据库(mysql,SqlServer);

DeptMapper.xml

<mapper namespace="com.neuedu.mapper.DeptMapper">

	<!-- 插入部门信息 -->
	<insert id="insertDept" parameterType="Dept" useGeneratedKeys="true" keyProperty="deptno" > 	
		insert into dept(dname,loc) values(#{dname},#{loc})
	</insert>
	
</mapper>
mybatis会使用JDBC的getGeneratedkeys方法获取由数据库内部自动生成的主键,
并将该值赋值给由keyProperty指定的属性

接口:DeptMapper.java

public interface DeptMapper {

	//插入部门信息,返回值类型设置为主键数据类型
	int insertDept(Dept dept);
	
}

测试类Test02.java

public class Test02 {
	/**
	 * 向dept表中插入一条部门信息,并获取到这条信息的主键值
	 * insert into dept(dname,loc) values(#{dname},#{loc})
	 */
	@Test
	public void insertDeptRecord() {
		// 创建sqlsession
		SqlSession sqlSession = MybatisUtils.getSession();
		// 获取mapper代理对象,加载字节码文件
		DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
		// 通过代理对象调用方法
		Dept dept = new Dept();
		dept.setDname("安保部");
		dept.setLoc("大连");
		//返回的是影响行数
		//int row = mapper.insertDept(dept);
		mapper.insertDept(dept);
		//提交事务
		sqlSession.commit();
		//释放资源
		sqlSession.close();
		
		System.out.println(dept.getDeptno());
	}
2.多条件查询
  • 将参数类型parameterType设置为对象类型,通过对象属性传入多个条件;

例子:根据部门名称部门编号查找部门信息;要求名字中包含‘勤’字,且编号大于10。

DeptMapper.xml

<mapper namespace="com.neudeu.mapper.DeptMapper">
	<select id="findDeptByNameAndDeptno" parameterType="dept" resultType="dept">
		<!-- 转义字符 &gt; 大于号-->
		select * from dept where dname like '%${dname}%' and deptno &gt; #{deptno}
	</select>

在这里插入图片描述
接口:DeptMapper.java

public interface DeptMapper {

	// 根据部门名称和编号查询部门信息
	List<Dept> findDeptByNameAndDeptno(Dept dept);
	
}

测试类Test01_Dept.java

	@Test
	public void findDeptTest() {
		// 创建sqlSession
		SqlSession sqlSession = MybatisUtils.getSession();
		// 获取代理对象
		DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
		// 创建对象
		Dept dept = new Dept();
		dept.setDeptno(10);
		dept.setDname("勤");
		// 通过mapper对象调用方法
		List<Dept> list = mapper.findDeptByNameAndDeptno(dept);
		for (Dept d : list) {
			System.out.println(d.getDeptno());
			System.out.println(d.getDname());
		}
		//关闭资源
		sqlSession.close();
	}

三.动态sql

主要用于解决查询条件不确定的情况。

1.if+where标签
  • 通过where标签添加where
  • 不需要考虑where后是否加and,mybatis会自动处理
  • 不需要考虑是否加空格,mybatis会自动处理
  • 没有 else 标签,也没有 else if 标签。
  • 注意: job!=’’ 此处只可以判断是否为空,不能判断是否为某个值。也就是说:job!=‘经理’ 是不好使的

DeptMapper.xml

<mapper namespace="com.neudeu.mapper.DeptMapper">
	<select id="findDeptByIfWhere" parameterType="dept"	resultType="dept">
		select * from dept
		<where>
			<if test="dname != null and dname != ''">
				and dname like '%${dname}%'
			</if>
			<if test="deptno != null and deptno !=''">
				and deptno &gt; #{deptno}
			</if>
		</where>
	</select>
</mapper>

接口:DeptMapper.java

public interface DeptMapper {

	// 根据部门名称和编号查询部门信息(动态sql-ifwhere)
	List<Dept> findDeptByIfWhere(Dept dept);
	
}

测试类Test01_Dept.java

	@Test
	public void findDeptByIfWhere() {
		// 创建sqlSession
		SqlSession sqlSession = MybatisUtils.getSession();
		// 获取代理对象
		DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
		// 创建对象
		Dept dept = new Dept();
		dept.setDeptno(100);
//		dept.setDname("勤");
		
		// 通过mapper对象调用方法
		List<Dept> list = mapper.findDeptByIfWhere(dept);
		for (Dept d : list) {
			System.out.println(d.getDeptno());
			System.out.println(d.getDname());
		}
		
		sqlSession.close();
	}
2.choose标签
  • 自上而下执行when标签;
  • 当某一个条件满足时,执行该标签内容,下面when标签中的内容则不再执行;
  • 当所有when标签中的条件都不满足时,执行otherwise标签中内容;
    (otherwise标签也可以不写)

DeptMapper.xml

<mapper namespace="com.neudeu.mapper.DeptMapper">
	<select id="findDeptByChoose" parameterType="dept"  resultType="dept">
		select * from dept
		<where>
			<choose>
				<!-- 多个when标签只能执行一个。上面的条件如果满足,以下则不再执行 -->
				<when test="dname != null and dname != ''">
					and dname like '%${dname}%'
				</when>
				<when test="deptno != null and deptno !=''">
					and deptno &gt; #{deptno}
				</when>
				<otherwise>
					<!-- 当上面条件全部不满足时会执行 -->
				</otherwise>
			</choose>
		</where>
	</select>
</mapper>

接口:DeptMapper.java

public interface DeptMapper {

	// 根据部门名称和编号查询部门信息(动态sql-choose)
	List<Dept> findDeptByChoose(Dept dept);
	
}

测试类Test01_Dept.java

	@Test
	public void findDeptByChoose() {
		// 创建sqlSession
		SqlSession sqlSession = MybatisUtils.getSession();
		// 获取代理对象
		DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
		// 创建对象
		Dept dept = new Dept();
		dept.setDeptno(100);
		dept.setDname("勤");
		
		// 通过mapper对象调用方法
		List<Dept> list = mapper.findDeptByChoose(dept);
		for (Dept d : list) {
			System.out.println(d.getDeptno());
			System.out.println(d.getDname());
		}
		
		sqlSession.close();
	}
3.foreach标签
  • 用于遍历参数中的数组或集合;
  • collection属性:需要遍历的类型值有:list array
    (当传入多个参数时,collection属性值为形参名。 —2022/01/06)
  • item属性:表示遍历出来的元素
  • open属性:表示起始位置所拼接的内容
  • close属性:表示结束位置所拼接的内容
  • separato属性:每次迭代之间的符号
  • index属性:每次迭代的位置索引,就是循环变量
3.1遍历数组

DeptMapper.xml

<mapper namespace="com.neudeu.mapper.DeptMapper">
	<select id="findDeptByIds" parameterType="int" resultType="dept">
		select * from dept where deptno in
		<foreach collection="array" item="deptno" open="(" close=")" separator=",">
			#{deptno}
		</foreach>
	</select>
</mapper>

接口:DeptMapper.java

public interface DeptMapper {

	//查询部门编号是10,20,30的部门信息(foreach标签)
	List<Dept> findDeptByIds(int[] arr);
	
}

测试类Test01_Dept.java

	@Test
	public void findDeptByIds() {
		// 创建sqlSession
		SqlSession sqlSession = MybatisUtils.getSession();
		// 获取代理对象
		DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
		//定义数组
		int[] arr = {10,20,30};
		// 使用mapper对象调用方法
		List<Dept> list = mapper.findDeptByIds(arr);
		for(Dept dept:list) {
			System.out.println(dept);
		}
		
		sqlSession.close();
	}
3.2遍历集合

DeptMapper.xml

<mapper namespace="com.neudeu.mapper.DeptMapper">
	<select id="findDeptByIdsList" parameterType="java.lang.Integer" resultType="dept">
		select * from dept where deptno in
		<foreach collection="list" item="deptno" open="(" close=")" separator=",">
			#{deptno}
		</foreach>
	</select>
</mapper>

接口:DeptMapper.java

public interface DeptMapper {

	//查询部门编号是10,20,30的部门信息(foreach标签)
	List<Dept> findDeptByIdsList(List<Integer> list);
	
}

测试类Test01_Dept.java

	@Test
	public void findDeptByIdsList() {
		// 创建sqlSession
		SqlSession sqlSession = MybatisUtils.getSession();
		// 获取代理对象
		DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
		//定义集合
		ArrayList<Integer> arrayList = new ArrayList<>();
		arrayList.add(10);
		arrayList.add(20);
		arrayList.add(30);
		// 使用mapper对象调用方法
		List<Dept> list = mapper.findDeptByIdsList(arrayList);
		
		for(Dept dept:list) {
			System.out.println(dept);
		}
		
		sqlSession.close();
	}

四.resultMap

当sql语句中的字段名与实体对象中的属性名不一致时使用。

  • type属性:表示映射的实体对象
  • id属性:resultMap的唯一标识
  • 子标签id:用于配置主键的映射
    • property属性:实体类中属性名
    • column属性:属性对应的字段名
  • 子标签result:用于配置普通字段的映射
    • property属性:实体类中属性名
    • column属性:属性对应的字段名
  • 子标签association :配置单个对象的关联映射(对象中的对象
    • property属性:该对象中的属性名
    • javaType属性:该对象类型

javabean Emp.java

package com.neudeu.pojo;

import java.util.Date;
/*
 * emp-->dept 多对一关系
 * 在多的一方 设置 一的对象
 */
public class Emp {//	

	private int empno;
	...
	private Dept dept;	//Dept对象属性
	
	public int getEmpno() {
		return empno;
	}
	public void setEmpno(int empno) {
		this.empno = empno;
	}
	...
	public Dept getDept() {
		return dept;
	}
	public void setDept(Dept dept) {
		this.dept = dept;
	}

	@Override
	public String toString() {
		return "Emp [empno=" + empno + ", ename=" + ename + ", job=" + job + ", mgr=" + mgr + ", hiredate=" + hiredate
				+ ", sal=" + sal + ", comm=" + comm + ", deptno=" + deptno + ", dept=" + dept + "]";
	}

}

EmpMapper.xml

<mapper namespace="com.neudeu.mapper.EmpMapper">
	<!-- 定义方法 根据员工编号查询员工信息以及员工所在部门信息 -->
	
	<!-- 定义resultMap -->
	<resultMap type="emp" id="empResultMap">
	
		<!-- 主键映射 -->
		<id property="empno" column="empno"/>
		<!-- 普通映射 -->
		<result property="ename" column="ename"/>
		<result property="job" column="job"/>
		...
		
		<!-- 配置单个对象的关联映射 -->
		<!-- property是属性名 javaType是对象类型-->
		<association property="dept" javaType="dept">
			<!-- 主键映射 -->
			<id property="deptno" column="dno"/><!-- dno 与dept.deptno别名 dno 相同-->
			<!-- 普通字段 -->
			<result property="dname" column="dn"/><!-- dn 与dept.dname别名 dn相同-->
			<result property="loc" column="dl"/><!-- dl 与dept.loc别名 dl相同-->
		</association>
		
	</resultMap>
	
	<!-- 将定义好的resultMap的唯一标识id 赋值为resultMap属性-->
	<select id="selectEmpAndDeptById" parameterType="int" resultMap="empResultMap">
		SELECT
			emp.*,
			dept.deptno AS 'dno',
			dept.dname AS 'dn',
			dept.loc AS 'dl'
		FROM
			emp
		LEFT JOIN dept ON emp.deptno = dept.deptno
		WHERE emp.empno = #{empno}
	</select>
</mapper>

接口:EmpMapper.java

public interface EmpMapper {
	//定义方法--根据员工编号查询员工信息以及员工所在部门信息
	Emp selectEmpAndDeptById(int empno);
}

测试类Test02_Emp.java

	@Test
	public void findEmpAndDeptTest() {
		// 创建sqlSession
		SqlSession sqlSession = MybatisUtils.getSession();
		// 获取代理对象
		EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);
		//访问方法
		Emp emp = mapper.selectEmpAndDeptById(7788);
		
		System.out.println(emp);
		int d = emp.getDept().getDeptno();
		System.out.println(d);
		
		sqlSession.close();
	}

五.输入/输出类型总结

1.输入映射类型(parameterType)
  • 当sql语句需要一个参数时
    1.接口方法参数为一个基本数据类型:parameterType配置一个基本数据类型;
  • 当sql语句需要多个参数时
    1.接口方法参数为一个实体对象类型:parameterType配置一个实体对象类型;
    2.接口方法参数为一个集合类型(List,Map):parameterType配置集合中元素的类型;
2.输出映射类型(resultType)
  • 当sql语句中的字段名与实体对象中的属性名一致时,使用resultType:
    1.返回一条记录时,resultType可以配置成对象类型
    2.返回多条记录时,resultType也要配置成对象类型(表示集合中存储的对象)
    3.返回一条记录,且只有一列时,resultType可以配置成简单数据类型。
  • 当sql语句中的字段名与实体对象中的属性名不一致时,使用resultMap
    1.在resultMap中,显式的书写sql字段名与实体对象属性名的映射
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值