mybatis insert返回主键_MyBatis的XML映射文件(一)

aec0e23ff5bf5a8ba2ff590315bbe3ee.png

[!note]

以下内容介绍Mybatis的XML映射文件的配置

顶级元素

SQL 映射文件只有很少的几个顶级元素(按照应被定义的顺序列出):

  •          cache          – 该命名空间的缓存配置。       

  •          cache-ref          – 引用其它命名空间的缓存配置。       

  •          resultMap          – 描述如何从数据库结果集中加载对象,是最复杂也是最强大的元素。       

  •         parameterMap            – 老式风格的参数映射。此元素已被废弃,并可能在将来被移除!请使用行内参数映射。文档中不会介绍此元素。                 

  •          sql          – 可被其它语句引用的可重用语句块。       

  •          insert          – 映射插入语句。       

  •          update          – 映射更新语句。       

  •          delete          – 映射删除语句。       

  •          select          – 映射查询语句。       

select

<select id="selectByUserId" parameterType="int" resultType="User">      select * from user where id = #{id}   select>
  • id:用来标识根dao接口中匹配的方法,必须与方法的名字一一对应。

  • parameterType:表示执行该sql需要传入的参数#{id}的类型为int或者Integer

  • resultType:表示该sql语句执行后的返回值为User类型。该属性只能返回单一的对象,关联查询时需要自定义结果集。当返回的结果是一个集合时,并不需要使用属性resultMap,只需要使用resultType指定集合中的元素类型即可。例如:

    <select id="selectAll" resultType="Emp">      select * from emp   select>[Emp{empno=1111, ename='zhangsan', job='null', mgr=null, hiredate=null, sal=6666.67, comm=null, deptno=null}, Emp{empno=2222, ename='hhh', job='null', mgr=null, hiredate=null, sal=1500.0, comm=null, deptno=null}, Emp{empno=3333, ename='wangwu', job='null', mgr=null, hiredate=null, sal=4000.0, comm=null, deptno=null}]

select元素的所有属性

select除了以上常用的几个属性外,还有其他属性:

属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
parameterMap用于引用外部 parameterMap 的属性,目前已被废弃。请使用行内参数映射和 parameterType 属性。
resultType期望从这条语句中返回结果的类全限定名或别名。注意,如果返回的是集合,那应该设置为集合包含的类型,而不是集合本身的类型。resultType 和 resultMap 之间只能同时使用一个。
resultMap对外部 resultMap 的命名引用。结果映射是 MyBatis最强大的特性,如果你对其理解透彻,许多复杂的映射问题都能迎刃而解。resultType 和 resultMap 之间只能同时使用一个。
flushCache用来标识当前sql语句的结果是否进入二级缓存。将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:false。
useCache将其设置为 true 后,将会导致本条语句的结果被二级缓存缓存起来,默认值:对 select 元素为 true。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
fetchSize这是一个给驱动的建议值,尝试让驱动程序每次批量返回的结果行数等于这个设置值。默认值为未设置(unset)(依赖驱动)。
statementType可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
resultSetTypeFORWARD_ONLY,SCROLL_SENSITIVE, SCROLL_INSENSITIVE 或 DEFAULT(等价于 unset) 中的一个,默认值为 unset (依赖数据库驱动)。
databaseId如果配置了数据库厂商标识(databaseIdProvider),MyBatis会加载所有不带 databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。
resultOrdered这个设置仅针对嵌套结果 select 语句:如果为true,将会假设包含了嵌套结果集或是分组,当返回一个主结果行时,就不会产生对前面结果集的引用。这就使得在获取嵌套结果集的时候不至于内存不够用。默认值:false
resultSets这个设置仅适用于多结果集的情况。它将列出语句执行后返回的结果集并赋予每个结果集一个名称,多个名称之间以逗号分隔。

例如:

<select id="selectPerson" parameterType="int" parameterMap="deprecated" resultType="hashmap" resultMap="personResultMap" flushCache="false" useCache="true" timeout="10" fetchSize="256" statementType="PREPARED" resultSetType="FORWARD_ONLY">

insert、update和delete

insert、update以及delete三个元素的基础用法:

<insert id="save" >      insert into emp(empno,ename) values(#{empno},#{ename})   insert>   <update id="update">      update emp set sal=#{sal} where empno = #{empno}   update>   <delete id="delete">      delete from emp where empno = #{empno}   delete>

insert、update以及delete三个元素的属性如下:

属性描述
id在命名空间中唯一的标识符,可以被用来引用这条语句。
parameterType将会传入这条语句的参数的类全限定名或别名。这个属性是可选的,因为MyBatis 可以通过类型处理器(TypeHandler)推断出具体传入语句的参数,默认值为未设置(unset)。
parameterMap用于引用外部 parameterMap 的属性,目前已被废弃。请使用行内参数映射和 parameterType 属性。
flushCache用来标识当前sql语句的结果是否进入二级缓存。将其设置为 true 后,只要语句被调用,都会导致本地缓存和二级缓存被清空,默认值:(对 insert、update 和 delete 语句)true。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为未设置(unset)(依赖数据库驱动)。
statementType用来选择执行sql语句的方式。statement:基本的jdbc操作,用来表示一个sql语句,不能防止sql注入 PREPARED:采用预编译的方式,能够防止sql注入,设置参数的时候需要该对象来进行设置 CALLABLE:调用存储过程。可选 STATEMENT,PREPARED 或 CALLABLE。这会让 MyBatis 分别使用Statement,PreparedStatement 或 CallableStatement,默认值:PREPARED。
useGeneratedKeys(仅适用于 insert 和 update)完成插入或更新操作时,可以将自增生成的主键值返回到具体的对象属性中。需要配合属性keyProperty使用:指定返回的主键要赋值到哪个对象属性中。这会令 MyBatis 使用 JDBC 的getGeneratedKeys 方法来取出由数据库内部生成的主键(比如:像 MySQL 和 SQL Server 这样的关系型数据库管理系统的自动递增字段),默认值:false。
keyProperty(仅适用于 insert 和 update)指定能够唯一识别对象的属性,MyBatis 会使用getGeneratedKeys 的返回值或 insert 语句的 selectKey 子元素设置它的值,默认值:未设置(unset)。如果生成列不止一个,可以用逗号分隔多个属性名称。
keyColumn(仅适用于 insert 和 update)设置生成键值在表中的列名,在某些数据库(像 PostgreSQL)中,当主键列不是表中的第一列的时候,是必须设置的。如果生成列不止一个,可以用逗号分隔多个属性名称。
databaseId如果配置了数据库厂商标识(databaseIdProvider),MyBatis 会加载所有不带databaseId 或匹配当前 databaseId 的语句;如果带和不带的语句都有,则不带的会被忽略。

例如:

<insert id="insertAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" keyProperty="" keyColumn="" useGeneratedKeys="" timeout="20"><update id="updateAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" timeout="20"><delete id="deleteAuthor" parameterType="domain.blog.Author" flushCache="true" statementType="PREPARED" timeout="20">

以上useGeneratedKeys属性的用法:插入数据后将生成的主键赋值给user对象的id字段,即 keyProperty="id"

<insert id="saveUser" useGeneratedKeys="true" keyProperty="id">  insert into user(user_name) values(#{userName})insert>

sql获取参数值

创建表:

CREATE TABLE `emp` (`empno` int(5) NOT NULL,`ename` varchar(20) DEFAULT NULL,`job` varchar(20) DEFAULT NULL,`mgr` int(20) DEFAULT NULL,`hiredate` datetime(6) DEFAULT NULL,`sal` double(20,2) DEFAULT NULL,`comm` double(20,0) DEFAULT NULL,`deptno` int(10) DEFAULT NULL,PRIMARY KEY (`empno`)) ENGINE=InnoDB DEFAULT CHARSET=latin1;

mybatis-config.xml配置文件:

<?xml  version="1.0" encoding="UTF-8" ?>/span>       PUBLIC "-//mybatis.org//DTD Config 3.0//EN"       "http://mybatis.org/dtd/mybatis-3-config.dtd"><configuration>      <properties resource="db.properties">properties>      <settings>              <setting name="mapUnderscoreToCamelCase" value="true"/>   settings>      <typeAliases>              <package name="com.fan.bean"/>   typeAliases>      <environments default="development">              <environment id="development">                      <transactionManager type="JDBC"/>                      <dataSource type="POOLED">                              <property name="driver" value="${driver}"/>               <property name="url" value="${url}"/>               <property name="username" value="${username}"/>               <property name="password" value="${password}"/>           dataSource>       environment>   environments>   <mappers>       <package name="com.fan.dao"/>   mappers>configuration>

[!tip]

sql获取参数值的方式:#{}或者${}

使用#{}获取参数值时执行的sql:select * from emp where empno = ?

EmpDao.xml映射文件:

<?xml  version="1.0" encoding="UTF-8" ?>/span>       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"       "http://mybatis.org/dtd/mybatis-3-mapper.dtd"><mapper namespace="com.fan.dao.EmpDao"><select id="selectEmpByEmpno" resultType="Emp">      select * from emp where empno = #{empno}   select>mapper>

实体类:

package com.fan.bean;import java.util.Date;/*** @Description* @Author 1966659927@qq.com* @Date 2020-11-02 15:05* @Version 1.0* @Project mybatis_helloworld**/public class Emp {   private Integer empno;   private String ename;   private String job;   private Integer mgr;   private Date hiredate;   private Double sal;   private Double comm;   private Integer deptno;   public Integer getEmpno() {       return empno;  }   public void setEmpno(Integer empno) {       this.empno = empno;  }   public String getEname() {       return ename;  }   public void setEname(String ename) {       this.ename = ename;  }   public String getJob() {       return job;  }   public void setJob(String job) {       this.job = job;  }   public Integer getMgr() {       return mgr;  }   public void setMgr(Integer mgr) {       this.mgr = mgr;  }   public Date getHiredate() {       return hiredate;  }   public void setHiredate(Date hiredate) {       this.hiredate = hiredate;  }   public Double getSal() {       return sal;  }   public void setSal(Double sal) {       this.sal = sal;  }   public Double getComm() {       return comm;  }   public void setComm(Double comm) {       this.comm = comm;  }   public Integer getDeptno() {       return deptno;  }   public void setDeptno(Integer deptno) {       this.deptno = deptno;  }   @Override   public String toString() {       return "Emp{" +               "empno=" + empno +               ", ename='" + ename + '\'' +               ", job='" + job + '\'' +               ", mgr=" + mgr +               ", hiredate=" + hiredate +               ", sal=" + sal +               ", comm=" + comm +               ", deptno=" + deptno +               '}';  }}

DAO层接口:

package com.fan.dao;import com.fan.bean.Emp;/*** @Description* @Author 1966659927@qq.com* @Date 2020-11-02 15:12* @Version 1.0* @Project mybatis_helloworld**/public interface EmpDao {   public Emp selectEmpByEmpno(Integer empno);   }

测试类:

?> 为了不必要的内容冗余,后面不再给出整体类,只给出相关测试方法

import com.fan.bean.Emp;import com.fan.dao.EmpDao;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 org.junit.Before;import org.junit.FixMethodOrder;import org.junit.Test;import org.junit.runner.OrderWith;import org.junit.runners.MethodSorters;/*** @Description* @Author 1966659927@qq.com* @Date 2020-11-02 15:25* @Version 1.0* @Project mybatis_helloworld**/public class MyTest {   SqlSessionFactory sqlSessionFactory = null;   /*   * 在测试方法之前执行   * */   @Before   public void init() throws IOException {       //通过xml创建一个SqlSessionFactory。SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,因此 SqlSessionFactory 的最佳作用域是应用作用域。       String resource = "mybatis-config.xml";       InputStream inputStream = Resources.getResourceAsStream(resource);       sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  }   @Test   public void testSelect() throws IOException {       SqlSession sqlSession = sqlSessionFactory.openSession();       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       //执行具体的sql       Emp emp = mapper.selectEmpByEmpno(1111);       System.out.println(emp);       //关闭数据库会话,保证每次请求都是创建了一个本次请求的新会话,避免造成数据混乱       sqlSession.close();  }}

测试结果:

DEBUG [main] - ==>  Preparing: select * from emp where empno = ?DEBUG [main] - ==> Parameters: 1111(Integer)

使用?{}获取参数值时执行的sql:select * from emp where empno = 1111

<select id="selectEmpByEmpno" resultType="Emp">      select * from emp where empno = ${empno}   select>

测试类:同上

DAO层接口:同上

测试结果:

DEBUG [main] - ==>  Preparing: select * from emp where empno = 1111DEBUG [main] - ==> Parameters:

通过以上两个结果执行的sql语句可以看出:#{}的处理方式是使用了参数预编译的方式,不会引起sql注入的问题。

${}的处理方式是直接拼接sql语句,会有sql注入的风险。

当sql需要动态的获取表名、列名时就需要使用${}来拼接sql。

   <select id="selectEmpByEmpno" resultType="Emp">      select * from ${arg0} where empno = #{arg1}   select>

DAO层接口:

public Emp selectEmpByEmpno(String table, Integer empno);

测试方法中调用时传入相应的表名称即可:

Emp emp = mapper.selectEmpByEmpno("emp", 1111);

sql获取多参数值

?> 当查询语句包含多个参数时,如何获取需要的参数?

1、如果是单个参数:    基本数据类型:可以使用#{}随便获取,即#{}中的参数名可以不是对象属性名,可以随意指定

<select id="selectEmpByEmpno" resultType="Emp">  select * from emp where empno = #{aaa}select>

测试同上

引用数据类型:使用#{}获取值时必须使用对象的属性名

<select id="selectEmpByEmpnoAndSal" resultType="Emp">      select * from emp where empno = #{empno} and sal > #{sal}   select>

DAO层接口:

public List<Emp> selectEmpByEmpnoAndSal(Emp emp);

测试方法:注意传给接口的是一个引用类型Emp对象,此时sql在获取该对象中属性值时就必须使用对象的属性名

@Test   public void test_selectEmpByEmpnoAndSal(){       SqlSession sqlSession = sqlSessionFactory.openSession();       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       Emp emp = new Emp();       emp.setEmpno(2222);       emp.setSal(500.0);       List<Emp> emps = mapper.selectEmpByEmpnoAndSal(emp);       System.out.println(emps);       sqlSession.close();  }

2、如果是多个参数:此时需要使用、{arg1}、、{param1}...来获取参数    原因在于,mybatis在传入多个参数时,会将这些参数的结果封装到map中,在map中key值就是(arg0,arg1,...),    (param1,param2,...),这种方式无法根据属性名来获取具体的参数值。

<select id="selectEmpByEmpnoAndSal2" resultType="Emp">      select * from emp where empno = ${arg0} and sal > ${arg1}   select>

   如果想要使用参数的方式获取值,可以在dao接口方法的参数加上注解@Param("参数名")。

<select id="selectEmpByEmpnoAndSal2" resultType="Emp">      select * from emp where empno = #{empno} and sal > #{sal}   select>

DAO层接口:

public List<Emp> selectEmpByEmpnoAndSal2(@Param("empno") Integer empno, @Param("sal") Double sal);

测试方法:

@Test   public void test_selectEmpByEmpnoAndSal2(){       SqlSession sqlSession = sqlSessionFactory.openSession();       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       List<Emp> emps = mapper.selectEmpByEmpnoAndSal2(2222,500.0);       System.out.println(emps);       sqlSession.close();  }

3、将参数包装成map传入sql,sql将自动解析map获取参数

<select id="selectEmpByEmpnoAndSal3" resultType="Emp">  select * from emp where empno = #{empno} and sal > #{sal}select>

DAO层接口:

public List<Emp> selectEmpByEmpnoAndSal3(Map<String, Object> map);
@Test   public void test_selectEmpByEmpnoAndSal3(){       SqlSession sqlSession = sqlSessionFactory.openSession();       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       Map<String,Object> map = new HashMap<String, Object>();       map.put("empno", 2222);       map.put("sal", 500.0);       List<Emp> emps = mapper.selectEmpByEmpnoAndSal3(map);       System.out.println(emps);       sqlSession.close();  }

resultType与resultMap

resultType

resultType:表示返回的结果类型,一般使用的并不多,该属性只能返回单一的对象,关联查询时需要自定义结果集。            当返回的结果是一个集合时,并不需要使用属性resultMap,只需要使用resultType指定集合中的元素类型即可

<select id="selectAll" resultType="Emp">      select * from emp   select>      <select id="selectAll2" resultType="Emp">      select * from emp   select>      <select id="selectEmpByEmpno_1" resultType="map">      select * from emp where empno = #{empno}   select>

DAO层接口:

public Map<Object, Object> selectEmpByEmpno_1(Integer empno);   public List<Emp> selectAll();   @MapKey("ename")//代表该字段将作为结果的key,Emp将作为value   public Map<String, Emp> selectAll2();

测试方法:

@Test   public void testSelectAll(){       SqlSession sqlSession = sqlSessionFactory.openSession(true);       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       List<Emp> emps = mapper.selectAll();       System.out.println(emps);       sqlSession.close();  }      @Test   public void test_selectEmpByEmpno_1(){       SqlSession sqlSession = sqlSessionFactory.openSession();       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       Map<Object, Object> map = mapper.selectEmpByEmpno_1(2222);       System.out.println(map);       sqlSession.close();  }   @Test   public void test_selectAll2(){       SqlSession sqlSession = sqlSessionFactory.openSession();       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       Map<String, Emp> map = mapper.selectAll2();       System.out.println(map);       sqlSession.close();  }

测试结果分别为:

testSelectAll

DEBUG [main] - ==>  Preparing: select * from empDEBUG [main] - ==> Parameters:DEBUG [main] - <==      Total: 5[Emp{empno=1111, ename='zhangsan', job='null', mgr=null, hiredate=null, sal=6666.67, comm=null, deptno=null}, Emp{empno=2222, ename='hhh', job='null', mgr=null, hiredate=null, sal=1500.0, comm=null, deptno=null}, Emp{empno=3333, ename='wangwu', job='null', mgr=null, hiredate=null, sal=4000.0, comm=null, deptno=null}, Emp{empno=4444, ename='maliu', job='null', mgr=null, hiredate=null, sal=8000.0, comm=null, deptno=null}, Emp{empno=5555, ename='lisi', job='null', mgr=null, hiredate=null, sal=null, comm=null, deptno=null}]

test_selectEmpByEmpno_1

DEBUG [main] - ==>  Preparing: select * from emp where empno = ?DEBUG [main] - ==> Parameters: 2222(Integer)DEBUG [main] - <==      Total: 1{ename=hhh, empno=2222, sal=1500.0}

test_selectAll2

DEBUG [main] - ==>  Preparing: select * from empDEBUG [main] - ==> Parameters:DEBUG [main] - <==      Total: 5{lisi=Emp{empno=5555, ename='lisi', job='null', mgr=null, hiredate=null, sal=null, comm=null, deptno=null}, zhangsan=Emp{empno=1111, ename='zhangsan', job='null', mgr=null, hiredate=null, sal=6666.67, comm=null, deptno=null}, hhh=Emp{empno=2222, ename='hhh', job='null', mgr=null, hiredate=null, sal=1500.0, comm=null, deptno=null}, maliu=Emp{empno=4444, ename='maliu', job='null', mgr=null, hiredate=null, sal=8000.0, comm=null, deptno=null}, wangwu=Emp{empno=3333, ename='wangwu', job='null', mgr=null, hiredate=null, sal=4000.0, comm=null, deptno=null}}

resultMap

resultMap:当进行关联查询时,在返回结果的对象中还包含另一个对象的引用时,此时需要自定义结果集合使用resultMap

一般情况下,mybatis会自动帮我们封装结果集(数据库字段名和类属性必须一一对应),但是当数据库中字段的值和类中的属性不匹配时,这时就需要我们自定义结果集。当然可以在sql中添加字段别名来保证查询结果赋值成功,但不可复用、比较繁琐。

<select id="selectDogById" resultType="Dog">      select id id, dname name, dage age, dgender gender from dog where id=#{id}   select>

自定义结果集resultMap:

   <resultMap id="myDog" type="Dog">              <id property="id" column="id">id>              <result property="name" column="dname">result>       <result property="age" column="dage">result>       <result property="gender" column="dgender">result>   resultMap>   <select id="selectDogById_1" resultMap="myDog">      select * from dog where id=#{id}   select>

创建表:

CREATE TABLE `dog` (`id` int(5) NOT NULL,`dname` varchar(5) DEFAULT NULL,`dage` int(2) DEFAULT '1',`dgender` char(1) DEFAULT NULL,PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;

实体类:

package com.fan.bean;/*** @Description* @Author 1966659927@qq.com* @Date 2020-11-12 10:16* @Version 1.0* @Project mybatis_helloworld**/public class Dog {   private Integer id;   private String name;   private Integer age;   private String gender;   public Integer getId() {       return id;  }   public void setId(Integer id) {       this.id = id;  }   public String getName() {       return name;  }   public void setName(String name) {       this.name = name;  }   public Integer getAge() {       return age;  }   public void setAge(Integer age) {       this.age = age;  }   public String getGender() {       return gender;  }   public void setGender(String gender) {       this.gender = gender;  }   @Override   public String toString() {       return "Dog{" +               "id=" + id +               ", name='" + name + '\'' +               ", age=" + age +               ", gender='" + gender + '\'' +               '}';  }}

DAO层接口:

package com.fan.dao;import com.fan.bean.Dog;/*** @Description* @Author 1966659927@qq.com* @Date 2020-11-12 10:21* @Version 1.0* @Project mybatis_helloworld**/public interface DogDao {   public Dog selectDogById(Integer id);   public Dog selectDogById_1(Integer id);}

测试类:

import com.fan.bean.Dog;import com.fan.dao.DogDao;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 org.junit.Before;import org.junit.Test;import java.io.IOException;import java.io.InputStream;/*** @Description* @Author 1966659927@qq.com* @Date 2020-11-02 15:25* @Version 1.0* @Project mybatis_helloworld**/public class MyTest2 {   SqlSessionFactory sqlSessionFactory = null;   /*   * 在测试方法之前执行   * */   @Before   public void init() throws IOException {       //通过xml创建一个SqlSessionFactory。SqlSessionFactory一旦被创建就应该在应用的运行期间一直存在,因此 SqlSessionFactory 的最佳作用域是应用作用域。       String resource = "mybatis-config.xml";       InputStream inputStream = Resources.getResourceAsStream(resource);       sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);  }   @Test   public void test_selectDogById(){       SqlSession sqlSession = sqlSessionFactory.openSession();       DogDao mapper = sqlSession.getMapper(DogDao.class);       Dog dog = mapper.selectDogById(1);       System.out.println(dog);       sqlSession.close();  }   @Test   public void test_selectDogById_1(){       SqlSession sqlSession = sqlSessionFactory.openSession();       DogDao mapper = sqlSession.getMapper(DogDao.class);       Dog dog = mapper.selectDogById_1(1);       System.out.println(dog);       sqlSession.close();  }}
association属性

association属性是resultMap的子属性。当包含其他对象时,可以通过 对象.属性 来取到其他对象的值 或者使用association属性。

创建表:

create table `dept`(`deptno` int(4) not null,`dname` varchar(10) default null,`loc` varchar(10) default null)engine=innodb default charset=utf8

1、 对象.属性 的方式获取其他对象的值

<resultMap id="myEmp" type="Emp">       <id column="empno" property="empno">id>       <result column="ename" property="ename">result>       <result column="job" property="job">result>       <result column="mgr" property="mgr">result>       <result column="hiredate" property="hiredate">result>       <result column="sal" property="sal">result>       <result column="comm" property="comm">result>       <result column="deptno" property="dept.deptno">result>       <result column="dname" property="dept.dname">result>       <result column="loc" property="dept.loc">result>   resultMap>   <select id="selectEmpByEmpno" resultMap="myEmp">      select * from emp left join dept on emp.deptno = dept.deptno where empno = #{empno}   select>

实体类:

package com.fan.bean;import java.util.List;/*** @Description* @Author 1966659927@qq.com* @Date 2020-11-12 16:50* @Version 1.0* @Project mybatis_sqlMapping**/public class Dept {   private Integer deptno;   private String dname;   private String loc;   public Integer getDeptno() {       return deptno;  }   public void setDeptno(Integer deptno) {       this.deptno = deptno;  }   public String getDname() {       return dname;  }   public void setDname(String dname) {       this.dname = dname;  }   public String getLoc() {       return loc;  }   public void setLoc(String loc) {       this.loc = loc;  }   @Override   public String toString() {       return "Dept{" +               "deptno=" + deptno +               ", dname='" + dname + '\'' +               ", loc='" + loc + '\''+               '}';  }}

DAO层接口:

public Emp selectEmpByEmpno(Integer empno);

测试方法:

@Test   public void test_selectEmpByEmpno(){       SqlSession sqlSession = sqlSessionFactory.openSession();       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       Emp emp = mapper.selectEmpByEmpno(1111);       System.out.println(emp);       sqlSession.close();  }

测试结果:

DEBUG [main] - ==>  Preparing: select * from emp left join dept on emp.deptno = dept.deptno where empno = ?DEBUG [main] - ==> Parameters: 1111(Integer)DEBUG [main] - <==      Total: 1Emp{empno=1111, ename='zhangsan', job='null', mgr=null, hiredate=null, sal=6666.67, comm=null, dept=Dept{deptno=1, dname='软件', loc='null', emps=null}}

2、association属性 的方式获取其他对象的值

<resultMap id="myEmp_1" type="Emp">       <id column="empno" property="empno">id>       <result column="ename" property="ename">result>       <result column="job" property="job">result>       <result column="mgr" property="mgr">result>       <result column="hiredate" property="hiredate">result>       <result column="sal" property="sal">result>       <result column="comm" property="comm">result>       <association property="dept" javaType="Dept">           <id column="deptno" property="deptno">id>           <result column="dname" property="dname">result>           <result column="loc" property="loc">result>       association>   resultMap>   <select id="selectEmpByEmpno_1" resultMap="myEmp_1">      select * from emp left join dept on emp.deptno = dept.deptno where empno = #{empno}   select>

实体类:同上

DAO层接口:

public Emp selectEmpByEmpno_1(Integer empno);

测试方法:

@Test   public void test_selectEmpByEmpno_1(){       SqlSession sqlSession = sqlSessionFactory.openSession();       EmpDao mapper = sqlSession.getMapper(EmpDao.class);       Emp emp = mapper.selectEmpByEmpno_1(1111);       System.out.println(emp);       sqlSession.close();  }

测试结果:

DEBUG [main] - ==>  Preparing: select * from emp left join dept on emp.deptno = dept.deptno where empno = ?DEBUG [main] - ==> Parameters: 1111(Integer)DEBUG [main] - <==      Total: 1Emp{empno=1111, ename='zhangsan', job='null', mgr=null, hiredate=null, sal=6666.67, comm=null, dept=Dept{deptno=1, dname='软件', loc='null', emps=null}}
collection属性

collection属性是resultMap的子属性,用于数据库中一对多的情形。

例如:一个部门对应多个员工,即一个部门dept中有多个员工emp。

<resultMap id="myDept" type="com.fan.bean.Dept">       <id column="deptno" property="deptno">id>       <result column="dname" property="dname">result>       <result column="loc" property="loc">result>       <collection property="emps" ofType="com.fan.bean.Emp">           <id column="empno" property="empno">id>           <result column="ename" property="ename">result>           <result column="job" property="job">result>           <result column="mgr" property="mgr">result>           <result column="hiredate" property="hiredate">result>           <result column="sal" property="sal">result>           <result column="comm" property="comm">result>       collection>  resultMap> <select id="selectDeptByDeptno" resultMap="myDept">    select * from dept left join emp on dept.deptno = emp.deptno where dept.deptno = #{deptno} select>

实体类:添加一个emp的集合

package com.fan.bean;import java.util.List;/*** @Description* @Author 1966659927@qq.com* @Date 2020-11-12 16:50* @Version 1.0* @Project mybatis_sqlMapping**/public class Dept {   private Integer deptno;   private String dname;   private String loc;   private List<Emp> emps;   public Integer getDeptno() {       return deptno;  }   public void setDeptno(Integer deptno) {       this.deptno = deptno;  }   public String getDname() {       return dname;  }   public void setDname(String dname) {       this.dname = dname;  }   public String getLoc() {       return loc;  }   public void setLoc(String loc) {       this.loc = loc;  }   public List<Emp> getEmps() {       return emps;  }   public void setEmps(List<Emp> emps) {       this.emps = emps;  }   @Override   public String toString() {       return "Dept{" +               "deptno=" + deptno +               ", dname='" + dname + '\'' +               ", loc='" + loc + '\'' +               ", emps=" + emps +               '}';  }}

DAO层接口:

public Dept selectDeptByDeptno(Integer deptno);

测试类:

@Testpublic void test_selectDeptByDeptno(){   SqlSession sqlSession = sqlSessionFactory.openSession();   DeptDao mapper = sqlSession.getMapper(DeptDao.class);   Dept dept = mapper.selectDeptByDeptno(1);   System.out.println(dept);   sqlSession.close();}

测试结果:可以看到一个dept对应了多个emp

DEBUG [main] - ==>  Preparing: select * from dept left join emp on dept.deptno = emp.deptno where dept.deptno = ?DEBUG [main] - ==> Parameters: 1(Integer)DEBUG [main] - <==      Total: 3Dept{deptno=1, dname='软件', loc='null', emps=[Emp{empno=1111, ename='zhangsan', job='null', mgr=null, hiredate=null, sal=6666.67, comm=null, dept=null}, Emp{empno=3333, ename='wangwu', job='null', mgr=null, hiredate=null, sal=4000.0, comm=null, dept=null}, Emp{empno=4444, ename='maliu', job='null', mgr=null, hiredate=null, sal=8000.0, comm=null, dept=null}]}

以上文章已同步到个人博客:https://bfanfanfan.gitee.io/fanfanfan

Ⓜ️ 我是一只小白猿,下期再见!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值