Mybatis的高级使用

Mybatis的介绍与简单使用,已经介绍了Mybatis的基本使用(包括了简单的输入输出类型,pojo输入输出类型,以及一些简单的sql),而这篇博客主要是来讲一些复杂的输入输出类型,动态sql,以及数据库表之间一对一,一对多的关联

 

pojo包装类输入类型

新建一个pojo包装类QueryVo.java

package pojo;

import java.io.Serializable;
import java.util.List;
/*
 * 
 */

public class QueryVo implements Serializable{
	private user user;
	private List<Integer> IdsList;

	public List<Integer> getIdsList() {
		return IdsList;
	}

	public void setIdsList(List<Integer> idsList) {
		IdsList = idsList;
	}

	public user getUser() {
		return user;
	}

	public void setUser(user user) {
		this.user = user;
	}
	
	
}

在user.xml书写SQL语句

<?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="map.UserMapper">
<select id="findUserByQueryVo"  parameterType="pojo.QueryVo" resultType="pojo.user">
		select * from users where Uname like "%"#{user.Uname}"%"
</select>
</mapper>

新建一个测试类MybatisMapperTest.java

public class MybatisMapperTest {

      public void testMapperQueryVo() throws Exception{
	    //加载核心配置文件
	    String resource = "sqlMapConfig.xml";
	    InputStream in = Resources.getResourceAsStream(resource);
	    //创建SqlSessionFactory
	    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
	    //创建Sqlsession
	    SqlSession sqlSession = sqlSessionFactory.openSession();
	    //执行sql
	    //sqlSession帮我生成一个实现类(给接口)
	    UserMapper mapper = sqlSession.getMapper(UserMapper.class);
	    QueryVo vo = new QueryVo();
	    user user = new user();
	    user.setUname("z");
	    vo.setUser(user);
	    List<pojo.user> findUserByQueryVo = mapper.findUserByQueryVo(vo);
	    for(user u :findUserByQueryVo){
	    	System.out.println(u);
	    }
	    
	}

}

 

ResultMap输出类型

在javabean中的属性名跟数据库的列名一样时,Mybatis是可以实现自动映射的,但是但javabean的属性名跟数据库列明不一样时,就需要我们手动映射

新建一张数据库表

再新建一个javabean,不难发现数据库列明Cardid跟javabean属性名Cardid_id不一样

package pojo;

import java.util.List;

public class affair {
	private String Lid;
	private String Cardid_id;
	private String Ltype;
	private double Lmoney;
	private String Ltid;
	private user user;
	
	
	public user getUser() {
		return user;
	}
	public void setUser(user user) {
		this.user = user;
	}
	
	public String getLid() {
		return Lid;
	}
	public void setLid(String lid) {
		Lid = lid;
	}
	
	public String getCardid_id() {
		return Cardid_id;
	}
	public void setCardid_id(String cardid_id) {
		Cardid_id = cardid_id;
	}
	public String getLtype() {
		return Ltype;
	}
	public void setLtype(String ltype) {
		Ltype = ltype;
	}
	public double getLmoney() {
		return Lmoney;
	}
	public void setLmoney(double lmoney) {
		Lmoney = lmoney;
	}
	public String getLtid() {
		return Ltid;
	}
	public void setLtid(String ltid) {
		Ltid = ltid;
	}
	@Override
	public String toString() {
		return "affair [Lid=" + Lid + ", Cardid_id=" + Cardid_id + ", Ltype=" + Ltype + ", Lmoney=" + Lmoney + ", Ltid="
				+ Ltid + ", user=" + user + "]";
	}
	
	
}

为该javaBean创建一个mapper.xml,命名为affair.xml(注意:手动映射时,select标签的结果映射一定要写resultMap,不能写resultType,否则会报找不到类的错误)

<?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="map.AffairMapper">
    
    <!--
          resultMap标签进行手动映射,只需要对javaBean中属性名跟数据库列名进行手动映射即可
          其他相同的他会自动映射
     -->
	<resultMap type="pojo.affair"  id="zp">
		<result column="Cardid" property="Cardid_id"/>
	</resultMap>	
	
	<select id="selectAffairList"  resultMap="zp" >
		select Lid,Cardid,Ltype,Ltid,Lmoney from affairs
	</select>
</mapper>

创建一个AffairMapper接口,实现Mapper动态代理

package map;

import java.util.List;

import org.apache.logging.log4j.core.config.Order;

import pojo.affair;

public interface AffairMapper {
	//查询所有数据
	public List<affair> selectAffairList();

	
}

最后到测试类中进行测试

public class MybatisMapperTest {

     @Test
	public void testAffairList() throws Exception{
	    //加载核心配置文件
	    String resource = "sqlMapConfig.xml";
	    InputStream in = Resources.getResourceAsStream(resource);
	    //创建SqlSessionFactory
	    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
	    //创建Sqlsession
	    SqlSession sqlSession = sqlSessionFactory.openSession();
	    //执行sql
	    //sqlSession帮我生成一个实现类(给接口)
	    AffairMapper mapper = sqlSession.getMapper(AffairMapper.class);
	    List<affair> selectAffairList = mapper.selectAffairList();
	    for(affair affair : selectAffairList){
	    	System.out.println(affair.toString());
	    }
	    
	}
}

 

起别名映射:

javabean的属性名跟数据库列明不一样时,除了可以用resultMap进行手动映射外,我们还可以用另外一种更简单的映射方法,那就是在sql语句中起别名,直接在列名后面加上对应的属性名作为别名

<?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="map.AffairMapper">
	<select id="selectAffairList"  resultMap="zp" >
		select Lid,Cardid Cardid_id ,Ltype,Ltid,Lmoney from affairs
	</select>
</mapper>

 

一对一的关联

在上面的affair类中,有一个类型user类型的属性user,这也就意味着一个affair对应一个user,也就是一对一的关联

affair.xml配置如下

使用一对一关联时,不管javaBean属性名跟类名是否相同,都必须手动映射,否则取出来是null

<?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="map.AffairMapper">
    

   <resultMap type="pojo.affair" id="affair">
	<result column="Cardid" property="Cardid_id" />
	<result column="Lid" property="Lid" />
	<result column="Ltype" property="Ltype" />
	<result column="Lmoney" property="Lmoney" />
	<result column="Ltid" property="Ltid" />
		<!-- 一对一 -->
	        <association property="user" javaType="pojo.user">
			<result column="Uname" property="Uname"/>
		</association> 
	</resultMap>
	<select id="selectAffairs" resultMap="affair">
		select
		a.Lid,
		a.Cardid, 
		a.Ltype,
		a.Lmoney,
		a.Ltid,
		u.Uname
		from affairs a left join users u on a.Cardid = u.cardid
	</select>
</mapper>

在AffairMapper接口中添加方法

package map;

import java.util.List;

import org.apache.logging.log4j.core.config.Order;

import pojo.affair;

public interface AffairMapper {
	//一对一关联查询   以日志为中心关联用户
	public List<affair> selectAffairs();

	
}

最后新建一个测试类进行测试

public class MybatisMapperTest2 {

	@Test
	public void testOrderList() throws Exception{
		//加载核心配置文件
		String resource = "sqlMapConfig.xml";
		InputStream in = Resources.getResourceAsStream(resource);
		//创建SqlSessionFactory
	    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(in);
	    //创建Sqlsession
	    SqlSession sqlSession = sqlSessionFactory.openSession();
	    //执行sql
	    //sqlSession帮我生成一个实现类(给接口)
	    AffairMapper mapper = sqlSession.getMapper(AffairMapper.class);
	    List<affair> selectAffairs = mapper.selectAffairs();
	    
	    for(affair affair :selectAffairs ){
	    	System.out.println(affair.toString());
	    }
	}

}

 

一对多的关联

有时候一个affair类中可能不是private user user 而是private List<user> user

也就是对应的不是一个user,而是一个user的集合,对应关系也就从一对一变成了一对多

affair.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="map.AffairMapper">
    

   <resultMap type="pojo.affair" id="affair">
	<result column="Cardid" property="Cardid_id" />
	<result column="Lid" property="Lid" />
	<result column="Ltype" property="Ltype" />
	<result column="Lmoney" property="Lmoney" />
	<result column="Ltid" property="Ltid" />
        
        <!--
                ofType是指泛型类型
                也就是传入集合(List<user>)里面元素的类型
                而非集合本身的类型
        -->
		<collection property="user" ofType="pojo.user">
			<result column="Uname"  property="Uname" />
		</collection>
	</resultMap>
	<select id="selectAffairs" resultMap="affair">
		select
		a.Lid,
		a.Cardid, 
		a.Ltype,
		a.Lmoney,
		a.Ltid,
		u.Uname
		from affairs a left join users u on a.Cardid = u.cardid
	</select>
</mapper>

接下在AffairMapper添加方法,在测试来进行测试,由于跟上面一对一操作一样就不多说了

 

动态sql

很多时候普通的增删改查等基本sql语句是不够用的,我们可能需要根据数据的变化动态改变sql

这就需要我们书写动态sql,mybatis给我们提供一些常用的标签

以下的操作均是针对user表

所写的sql均是在user.xml文件中

  • sql片段

      当我们书写大量sql语句时候,有些sql片段是重复的,为了让重复sql只写一遍,Mybatis就给我们提供sql片段

<!--抽取公共片段-->
<sql id="select">
	select * from users 
</sql> 

<!--引用公共片段-->
<select id="findUsers" resultType="pojo.user">
		<include refid="select"></include>
</select>
  •   ifwhere

     if标签可以进行判断有则添加,没有则不添加,而where标签可以去掉第一个条件前面的and

<!-- 根据姓名和名字查询用户 -->
	<select id="selectUserBySexAndUsername" parameterType="Integer" resultType="pojo.user">
		<include refid="select"></include>
		<!-- 根据性别和名字查询用户 where 可以去掉第一个前and  -->
		<where>
		<if test=" Usex != null and Usex != '' ">
			Usex = #{Usex}
		</if>
		<if test="Uname != null and Uname != '' ">
			 and Uname = #{Uname}
		</if>
		</where>
	</select>
  • foreach

     foreach变迁主要运用在遍历,经常搭配关键字in使用

     in (1,2,3,4) 括号内需要一些数字,此时遍历数组或者集合得到这些数字是最好不过了

     遍历数组

<!-- 

    对于数组collection要让它等于"array",否则会报错 

-->
	<select id="selectUserByIds1"  resultType="pojo.user">
			<include refid="select"></include>
			<where>
				<foreach collection="array" item="id" separator="," open="Idcard in("  close=")">
					#{id}
				</foreach>
			</where>
	</select>

     遍历集合

<!-- 
        遍历集合时,collection要设置为list,否则会报错
 -->
	<select id="selectUserByIds2" resultType="pojo.user">
			<include refid="select"></include>
			<where>
				<foreach collection="list" item="id" separator="," open="Idcard in("  close=")">
					#{id}
				</foreach>
			</where>
	</select>

     集合/数据存在pojo包装类中(参看最上面的pojo类)

	<!-- 
            遍历pojo包装类时 collection设置该pojo类中数据类型为数组或者集合的属性名
          -->
	<select id="selectUserByIds"  resultType="pojo.user">
			<include refid="select"></include>
			<where>
				<foreach collection="IdsList" item="id" separator="," open="Idcard in("  close=")">
					#{id}
				</foreach>
			</where>
	</select>

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
MyBatis中,高级查询可以使用延迟加载机制来实现。延迟加载是将数据加载时机推迟,例如推迟嵌套查询的执行时机。通过延迟加载,可以先查询主表,按需实时做关联查询,返回关联表结果集,提高效率。 在MyBatis中,实现关联查询有两种不同的方式:嵌套Select查询和嵌套结果映射。嵌套Select查询是通过执行另外一个SQL映射语句来加载期望的复杂类型,而嵌套结果映射则使用嵌套的结果映射来处理连接结果的重复子集。 对于关联结果映射和其他类型的映射,工作方式类似。需要指定目标属性名以及属性的javaType,大多数情况下MyBatis可以推断出来,如果需要的话,还可以设置JDBC类型。如果想要覆盖获取结果值的过程,可以设置类型处理器。 综上所述,通过延迟加载机制和适当的关联查询方式,MyBatis可以实现高级查询功能。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [Mybatis高级查询](https://blog.csdn.net/weixin_37650458/article/details/96587906)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [MyBatis高级查询](https://blog.csdn.net/qq_66991094/article/details/127147576)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值