Mybatis接口結合xml、字段屬性匹配以及聯表查詢


1.接口結合xml文件(相對於注解方式來說聯表方便)
2.字段與實體類屬性不匹配的處理
3.聯表查詢
 
一、接口結合xml文件
1.右鍵工程建議名為resources的Source Folder文件夾,用於存放config.xml、映射mappper包、properties文件
   (經過編譯后文件內容都會在bin文件夾下)
2. dao包下建接口
1.映射文件下<mapper>標簽屬性namespace要和接口所在的包匹配
2.各操作標簽id要與接口中對應方法名一致==>作為接口的實現類
    public interface RoleDao {
        public void addRole(Role role);
        public List<Role> selectById(@Param("min")int min,@Param("max")int max);   
    }    //@param注解參數命名,默認為[0, 1, param1, param2],見補充五

<?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.zhiyou100.yj.dao.OrderDao">    
    <insert id="addRole" parameterType="com.zhiyou100.yj.bean.Role">
        insert into role(uname,description) values(#{uname},#{description})
    </insert>
    <select id="selectById" resultType="com.zhiyou100.yj.bean.Role">
        select * from role where id>#{min} and id&lt;=#{max};
    </select>
</mapper>    

3.測試

class RoleMapperTest {
    static SqlSession session=null;
    static RoleDao roleDao=null;

    @BeforeAll
    static void setUpBeforeClass() throws Exception {
        Reader reader = Resources.getResourceAsReader("config.xml");
        SqlSessionFactory SessionFactory = new SqlSessionFactoryBuilder().build(reader);
        session = SessionFactory.openSession();
        roleDao = session.getMapper(RoleDao.class);
    }

    @Test
    void testAddRole() {
        Role role=new Role("李大炳","助理");
        roleDao.addRole(role);
    }
    @Test
    void testSelectById() {
        List<Role> roles = roleDao.selectById(3, 4);
        System.out.println(roles);
    }

    @AfterAll
    static void tearDownAfterClass() throws Exception {
        session.commit();
    }
}

補充一:接口結合xml如何實現參數傳入

直接傳參會報告以下異常:
Error querying database. 
Cause:org.apache.ibatis.binding.BindingException: Parameter 'uname' not found. Available parameters are [0, 1, param1, param2]
這是由於mabatis把參數默認封裝到map中,它的鍵有兩種形式[0, 1, param1, param2]
解決這個問題有3種方法:
1、把參數改為Mybatis默認的參數[arg0, argX, param1, paramX](X對應參數個數);
2、把參數封裝為一個JavaBean,然后把接口參數改為這個JavaBean;
3、方法傳入map參數;
4、接口參數上使用@Param注解;(推薦)

 

二、字段名與實體類屬性不匹配

public class Role{
    private int id;
    private String uname;
    private String description;
}
<update id="updateRole">
    update role set role_uname=#{uname},role_description=#{description} where role_id=#{id}
</update>
報錯:(查詢時不匹配屬性結果心顯示為null)
org.apache.ibatis.binding.BindingException:
Type interface com.zhiyou100.yj.dao.RoleDao is not known to the MapperRegistry.

方法一:為字段起別名以匹配實體類屬性
<select id="selectById" parameterType="int" resultType="com.zhiyou100.yj.bean.Role">
    select role_uname name,role_description description,role_id id from role where role_id=#{id}   
</select>
方法二:resultMap屬性替換resultType屬性,並在resultMap中寫字段屬性對照關系
<select id="selectById" parameterType="int" resultMap="roleMap">
    select * from role where role_id=#{id}   
</select>
<resultMap type="com.zhiyou100.yj.bean.Role" id="roleMap">    <!-- type:表示那個實體類與表的對應關系,類比返回類型-->
    <id column="role_id" property="id"/>
    <result column="role_description" property="description"/>
    <result column="role_uname" property="name"/>
</resultMap>

 

三、聯表查詢

1、多對一查詢;一對一查詢(一的一方作為另一方的屬性,查詢結果封裝到對象)    //如每個班級對應一個班主任
2、一對多查詢(多的一方構成集合作為一的屬性,查詢結果封裝到集合)    //如每個班級包含多個學生

1、多對一查詢;一對一查詢
public class Clazz {
      private int cId;
      private String cName;
      private int teacheId;
      private Teacher teacher;    //關聯的是老師對象
      private List<Student> students;    //關聯的是學生對象集合
}
public class Teacher {
      private int id;
      private String tName;
}
public class Student {
      private int  sId;
      private String sName;
      private int classId;
}

<!-- 一對一聯表 -->
<select id="selectClazzById" resultMap="ClazzMap">
    select * from class c,teacher t where c.teacher_id=t.t_id  and c_id=#{id}
</select>
      
<resultMap type="com.zhiyou100.yj.bean.Clazz" id="ClazzMap">
    <id column="c_id" property="cId"/>
    <result column="c_name" property="cName"/>
    <result column="teacher_id" property="teacheId"/>
<!--
    property:Teacher對象屬性
    javaType:Teacher對象類型
-->
<association property="teacher" javaType="com.zhiyou100.yj.bean.Teacher">
    <id column="t_id" property="id"/>
    <result column="t_name" property="tName"/>
</association>
</resultMap>

<!-- 一對一嵌套 -->
<select id="selectClazzById2" resultMap="ClazzMap2">
    select * from class where c_id=#{cid}    <!--查詢班級id,根據查詢結果中獲得的班主任id進一步查詢-->
</select>

<resultMap type="com.zhiyou100.yj.bean.Clazz" id="ClazzMap2">
    <id column="c_id" property="cId"/>
    <result column="c_name" property="cName"/>
    <result column="teacher_id" property="teacheId"/>
<!--
    property:Teacher對象屬性
    javaType:Teacher對象類型
    select:對應進一步查詢語句的id(另一張表查詢)
    column:進一步查詢對應的條件字段(外鍵字段)
-->
    <association property="teacher" javaType="com.zhiyou100.yj.bean.Teacher" select="selectTeacher"  column="teacher_id">
    </association>
</resultMap>

<!--寫法一:屬性字段不匹配,起別名-->
<select id="selectTeacher"  resultType="com.zhiyou100.yj.bean.Teacher">
    select t_id id,t_name tName from teacher where  t_id=#{teacher_id}
</select>
<!--寫法二:屬性字段不匹配,resultMap-->
<select id="selectTeacher" resultMap="TeacherMap">
    select * from teacher where t_id=#{teacher_id}
</select>
<resultMap type="com.zhiyou100.yj.bean.Teacher" id="TeacherMap" >
    <id column="t_id" property="id"/>
    <result column="t_name" property="tName"/>
</resultMap>

<!-- 一對多聯表 -->
<select id="selectClazzById3" resultMap="ClazzMap3">
    select * from class c,student s,teacher t where  c.c_id=s.class_id  and  t.t_id=c.teacher_id  and  c.c_id=#{id};
</select>
      
<resultMap type="com.zhiyou100.yj.bean.Clazz" id="ClazzMap3">
    <id column="c_id" property="cId"/>
    <result column="c_name" property="cName"/>
    <result column="teacher_id" property="teacheId"/>
    <association property="teacher"  javaType="com.zhiyou100.yj.bean.Teacher">    <!--對象類型:teacher-->
        <id column="t_id" property="id"/>
        <result column="t_name" property="tName"/>
    </association>
    <collection property="students"  ofType="com.zhiyou100.yj.bean.Student">   <!-- 集合類型:students;ofType:集合泛型的數據類型-->
        <id column="s_id" property="sId"/>
        <result column="s_name" property="sName"/>
        <result column="class_id" property="classId"/>
    </collection>
</resultMap>

<!-- 一對多嵌套 -->
<select id="selectClazz4" resultMap="ClazzMap4">
    select * from class where c_id=#{cid}
</select>

<resultMap type="com.zhiyou100.yj.bean.Clazz" id="ClazzMap4">
    <id column="c_id" property="cId" />
    <result column="c_name" property="cName" />
    <result column="teacher_id" property="teacheId" />
    <association property="teacher" javaType="com.zhiyou100.yj.bean.Teacher" select="selectTeacher" column="teacher_id">
    </association>
    <collection property="students" ofType="com.zhiyou100.yj.bean.Student" select="selectStudent" column="c_id">
    </collection>
</resultMap>

<select id="selectTeacher" resultType="com.zhiyou100.yj.bean.Teacher">
    select t_id id,t_name tName from teacher where  t_id=#{teacher_id}
</select>

<select id="selectStudent" resultType="com.zhiyou100.yj.bean.Student">
    select s_id sId,s_name sName,class_id classId from student  where class_id=#{c_id}
</select>

補充二:MyBatis中$與#的區別

$:解析時不會為內容添加"",是sql語句的拼接,存在sql注入危害
  傳入的是列名或表名時,可以使用$
  eg:如果value的值是anything' OR 'x'='x,那么sql語句就會是select * from user where name='anything' or 'x'='x'
#:解析時會為內容添加"",采用占位符,傳遞過來的#{xxx}的內容會被轉義,然后替換掉"?"的內容
  eg:select * from student where name='anything\' or \'x\'=\'x'

補充三:添加對象時如何把生產的id返回

<insert id="addRole" useGeneratedKeys="true" keyProperty="id">
    insert into role(uname,description) values(#{uname},#{description})
</insert>

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM