2.Mybatis的接口与xml映射

本文详细解析了MyBatis映射文件的顶级元素,包括SQL映射、缓存配置、可重用的SQL块及各类语句的映射。深入介绍了resultMap的使用,包括数据库结果集与对象的映射,以及复杂类型的一对一和一对多关联。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

编写MybatisUtil工具类

package com.kgc.util;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

import java.io.InputStream;

public class MyBatisUtil {
	//声明静态工厂变量
    private static SqlSessionFactory factory ;
	//实例化对象时自动执行静态代码块
    static {
        try{
        	//输入流读取配置文件xml
            InputStream is = Resources.getResourceAsStream("mybatis-config.xml");
            //工厂建造者建造
            factory = new SqlSessionFactoryBuilder().build(is);
        }catch (Exception e){
            e.printStackTrace();
        }
    }
	//提供获取SqlSession方法,防止对象创建过多导致内存溢出
    public static SqlSession createSqlSession() {
    	//开启事务,这里是一直让他不自动开启事务
        return factory.openSession(false);
    }
	//关闭sql对话资源
    public static void closeSqlSession(SqlSession s){
        if (s!=null){
            s.close();
        }
    }
}

mapper - namespace

<!-- 将mapper文件加入到配置文件中 -->
<mapper namespace="com.kgc.dao.user.UserMapper">
	

cache - 配置给定命名空间的缓存

<!--MyBatis的全局cache配置-->
<settings>
	<setting name = "cacheEnabled" value = "true"/>
</settings>

<!--在Mapper XML文件中设置缓存,默认情况下:未开启-->
<cache eviction = "FIFO" flushInterval="60000" 
	size="512" readOnly="true"/>
	
<!--在Mapper XML文件配置支持cache后,若需要对个别查询进行调整,可以单独设置cache-->
<select id = "selectAll" resultType="int" useCache="true"/>

cache-ref - 从其他命名空间引用缓存配置

参照缓存
这个特殊命名空间的唯一缓存会被使用或者刷新相同命名空间内 的语句。也许将来的某个时候,你会想在命名空间中共享相同的缓存配置和实例。在这样的 情况下你可以使用 cache-ref 元素来引用另外一个缓存。

<cache-ref namespace="com.someone.application.data.SomeMapper"/>

sql - 可以重用的SQL块,也可以被其他语句引用

这个元素可以被用来定义可重用的 SQL 代码段,可以包含在其他语句中。它可以被静态地(在加载参数) 参数化. 不同的属性值通过包含的实例变化. 比如:

<!--sql语句-->
<sql id="userColumns">
	${alias}.id,${alias}.username,${alias}.password 
</sql>
<!--sql引用-->
<select id="selectUsers" resultType="map">
  select
    <include refid="userColumns"><property name="alias" value="t1"/></include>,
    <include refid="userColumns"><property name="alias" value="t2"/></include>
  	from some_table t1
    cross join some_table t2
    
</select>

insert - 映射插入语句

<insert id="add" parameterType="User">
	<!--sql语句,入参是实体类的变量-->
	insert into smbms_user (userCode,userName,userPassword)
        values(#{userCode},#{userName},#{userPassword});

</insert>

update - 映射更新语句

接口

/**
* 修改数据
* @param user
* @return int
*/
public int update(User user);
<update id="update" parameterType="User">
	update smbms_user
<!--
prefix:在trim标签内sql语句加上前缀。
suffix:在trim标签内sql语句加上后缀。
suffixOverrides:指定去除多余的后缀内容,如:suffixOverrides=",",去除trim标签内sql语句多余的后缀。
prefixOverrides:指定去除多余的前缀内容
-->
	<trim prefix="set" suffixOverrides="," suffix="where id = #{id}">
		<if test="userCode!=null">userCode = #{userCode},</if>
		<if test="userName!=null">userName = #{userName},</if>
		<if test="userPassword!=null">userPassword = #{userPassword},</if>
		<if test="gender!=null">gender = #{gender},</if>
		<if test="birthday!=null">birthday = #{birthday},</if>
		<if test="phone!=null">phone = #{phone},</if>
		<if test="address!=null">address = #{address},</if>
		<if test="userRole!=null">userRole = #{userRole},</if>
	</trim>

</update>

delete - 映射删除语句

接口

/**
* 修改数据
* @param user
* @return int
*/
public int delete(@Param("id")int id);
<delete id="delete">
		<!--SQL语句-->
        delete from smbms_user where id = #{id};
        
</delete>

select - 映射查询语句

<select id="getUserListByPage" resultType="User">
		<!--SQL语句-->
        select * from smbms_user
            where 1 = 1
        <!--if判断标签-->
        <if test="userName!=null and userName!=''">
            and userName like concat('%',#{userName},'%')
        </if>
        limit #{start},#{end};
        
</select>

resultMap - 用来描述数据库结果集和对象的对应的关系

<!--reusltMap ID有唯一性-->
<resultMap id="userList" type="User">
		<!--result结果标签,property实体类变量,column数据库字段-->
        <result property="id" column="id"></result>
        <result property="userCode" column="userCode"></result>
        <result property="userName" column="userName"></result>
        <result property="phone" column="phone"></result>
        <result property="userRole" column="userRole"></result>
        <result property="userRoleName" column="roleName"></result>
        <result property="birthday" column="birthday"></result>
</resultMap>
<!--查询标签根据属性resultMap来找reusltMap关联ID-->
<select id="getUserListByMap" resultMap="userList" parameterType="map">
	select u.*,r.roleName from smbms_user u,smbms_role r
	<!--动态SQL where-if标签-->
	<where>
		u.userRole = r.id
		<if test="userRole !=null">
			and userRole = #{uRole}
		</if>
		
		<if test="userName !=null and userName !=''">
			and userName like concat('%',#{uName},'%');
		</if>
	</where>
</select>
//测试类
public void getUserListByMap(){

	SqlSession sqlSession = null;
	List<User> list = null;
	Map<String,Object> map = new HashMap<String, Object>();
	//map名字要对应xml里的参数名
	map.put("uName","马");
	map.put("uRole",2);
	
	try{
	   //使用工具类创建sqlSession对象
	   sqlSession = MyBatisUtil.createSqlSession();
	   //调用接口的方式实现查询
	   list = sqlSession.getMapper(UserMapper.class).getUserListByMap(map);
	   
	}catch (Exception e){
	   //打印错误堆栈信息
	   e.printStackTrace();
	   
	}finally{
		//关闭SqlSession对话
		sqlSession.closeSqlSession();
	}
	for (User a:list){
	   System.out.println(a.getUserCode()+":"+a.getUserName()+"\t"+"用户角
						  色:"+a.getUserRoleName()+"---"+a.getBirthday());
	}
}

resultMap - 复杂类型关联

association
映射一个嵌套JavaBean属性,一对一
实体类
/**
	User实体类
*/
public class User {
	private int id;//主键ID
	private String userCode;//用户编码
	private String userName;//用户名称
	private String userPassword;//用户密码
	private int gender;//性别(1:女、 2:男)
	private String birthday;//出生日期
	private int age; //年龄
	private String phone;//手机
	private String address;//地址
	private int userRole;//用户角色(取自角色表-角色id)
	private int createdBy;//创建者(userId)
	private Date creationDate;//创建时间
	private int modifyBy;//更新者(userId)
	private Date modifyDate;//更新时间
	private String idPicPath;
	private Role role;
	private String userRoleName;
	private List<Address> addresses;
}
/**
*	Role实体类
*/
public class Role {
	private int id;// 主键ID
	private String roleCode;// 角色编码
	private String roleName; // 角色名称
	private int createdBy; // 创建者
	private Date creationDate;// 创建时间
	private int modifyBy; // 修改者
	private Date modifyDate;// 修改时间
}
<resultMap id="getUserList_Map" type="User">
	<id property="id" column="id"></id>
	<result property="userName" column="userName"></result>
	<result property="userCode" column="userCode"></result>
	<!--映射一个嵌套JavaBean属性,一对一 这里对应的是实体类里的 role类型的变量-->
	<association property="role" javaType="Role">
		<id property="id" column="r.id"></id>
		<result property="roleName" column="roleName"></result>
	</association>
</resultMap>

<select id="getUserList_choose" resultMap="getUserList_Map">
  select u.*,r.* from smbms_user u,smbms_role r where u.userRole= r.id
  	  <!-- choose相当于Java的switch-case -->
      <choose>
          <when test="userName !=null and userName !=''">
              and u.userName like concat('%',#{userName},'%')
          </when>
          <when test="userCode !=null and userCode !=''">
              and u.userCode like concat('%',#{userCode},'%')
          </when>
          <otherwise>
              and YEAR(creationDate) = YEAR(#{creationDate})
          </otherwise>
      </choose>
</select>
collection
映射一个嵌套集合属性,一对多
实体类
/**
*	User实体类
*/
public class User{
	...省略其他字段变量
	private List<Address> addresses;

}
/**
*	Address实体类
*/
public class Address {
	 private int id;//主键ID;
	 private String contact;//联系人姓名;
	 private String addressDesc;//收货地址明细;
	 private String postCode;//邮编;
	 private String tel;//联系人电话;
	 private  int createdBy;//创建者;
	 private Date creationDate ;//创建时间;
	 private int modifyBy ;//修改者;
	 private Date modifyDate ;//修改时间;
	 private int userId ;//用户ID;
}

<resultMap id="userAddressResult" type="User">
	 <id property="id" column="u.id"></id>
     <result property="userCode" column="userCode"></result>
     <result property="userName" column="userName"></result>
   	 <!--映射一个嵌套集合属性,一对多,类似于联表查询-->
     <collection property="addresses" ofType="Address">
         <id property="id" column="a.id"></id>
         <result property="addressDesc" column="addressDesc"></result>
         <result property="postCode" column="postCode"></result>
         <result property="tel" column="tel"></result>
     </collection>
     
</resultMap>

<select parameterType="int" id="getAddressListByUserId" resultMap="userAddressResult">
    select u.*,a.* from smbms_user u,smbms_address a
        where u.id = a.userId and u.id = #{id};
        
</select>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值