栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MyBatis(三)映射文件

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MyBatis(三)映射文件

映射文件

映射文件指导着MyBatis如何进行数据库增删改查,有着非常重要的意义。

例如:
•cache –命名空间的二级缓存配置
•cache-ref – 其他命名空间缓存配置的引用。
•resultMap – 自定义结果集映射
•parameterMap – 已废弃!老式风格的参数映射
•sql –抽取可重用语句块。
•insert – 映射插入语句
•update – 映射更新语句
•delete – 映射删除语句
•select – 映射查询语句

数据库数据和实体对象准备,后面案例需要使用

CREATE DATAbase  IF NOT EXISTS `test` DEFAULT CHARACTER SET utf8 ;

USE `test`;

DROP TABLE IF EXISTS `tbl_dept`;

CREATE TABLE `tbl_dept` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `dept_name` varchar(255) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1006 DEFAULT CHARSET=utf8;


insert  into `tbl_dept`(`id`,`dept_name`) values 
(1001,'研发部'),
(1002,'生产部'),
(1003,'销售部'),
(1004,'客服部'),
(1005,'安保部');


DROP TABLE IF EXISTS `tbl_employee`;

CREATE TABLE `tbl_employee` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `last_name` varchar(255) DEFAULT NULL,
  `gender` char(1) DEFAULT NULL,
  `email` varchar(255) DEFAULT NULL,
  `d_id` int(11) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `fk_emp_dept` (`d_id`),
  CONSTRAINT `fk_emp_dept` FOREIGN KEY (`d_id`) REFERENCES `tbl_dept` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

insert  into `tbl_employee`(`id`,`last_name`,`gender`,`email`,`d_id`) values 
(1,'张三','1','zhangsan@qq.com',1001),
(2,'tom','0','tom@qq.com',1002),
(3,'jerry','0','jerry@qq.com',1003),
(4,'jeck','1','jeck@qq.com',1004),
(5,'tom','1','tom@qq.com',1005),
(6,'lucy','0','lucy@qq.com',1001);

Employee

public class Employee {
    private Integer id;
    private String lastname;
    private String email;
    private String gender;
    private Dept dept;

    public Employee() {
    }

    public Employee(Integer id, String lastname, String email, String gender) {
        this.id = id;
        this.lastname = lastname;
        this.email = email;
        this.gender = gender;
    }

    public Employee(Integer id, String lastname, String email, String gender, Dept dept) {
        this.id = id;
        this.lastname = lastname;
        this.email = email;
        this.gender = gender;
        this.dept = dept;
    }


    public Dept getDept() {
        return dept;
    }

    public void setDept(Dept dept) {
        this.dept = dept;
    }

    public Integer getId() {
        return id;
    }
    public void setId(Integer id) {
        this.id = id;
    }
    public String getLastname() {
        return lastname;
    }
    public void setLastname(String lastname) {
        this.lastname = lastname;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
    public String getGender() {
        return gender;
    }
    public void setGender(String gender) {
        this.gender = gender;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", lastname='" + lastname + ''' +
                ", email='" + email + ''' +
                ", gender='" + gender + ''' +
                ", dept=" + dept +
                '}';
    }
}

Dept

public class Dept {
    private Integer id;
    private String deptName;
    private List emps;

    public List getEmps() {
        return emps;
    }

    public void setEmps(List emps) {
        this.emps = emps;
    }

    public Dept() {
    }

    public Dept(Integer id, String deptName) {
        this.id = id;
        this.deptName = deptName;
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getDeptName() {
        return deptName;
    }

    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    @Override
    public String toString() {
        return "Dept{" +
                "id=" + id +
                ", deptName='" + deptName + ''' +
                '}';
    }
}

创建EmployeeMapper、DeptMapper接口文件和xml映射文件

public interface EmployeeMapper {}
public interface DeptMapper {}

EmployeeMapper.xml






DeptMapper.xml





配置全局配置文件mybatis-config.xml




	
		
			
			
				
				
				
				
			
		
	
	
		
		
	

测试类

public class Test {
    public static void main(String[] args) throws IOException {
        SqlSessionFactory sqlSessionFactory = getSqlSessionFactory();
        SqlSession sqlSession = sqlSessionFactory.openSession();
        try {
            EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
			
			//需要修改操作的代码

            sqlSession.commit();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            sqlSession.close();
        }
    }
    public static SqlSessionFactory getSqlSessionFactory() throws IOException {
        String resource = "mybatis-config.xml";
        InputStream inputStream = Resources.getResourceAsStream(resource);
        return new SqlSessionFactoryBuilder().build(inputStream);
    }
}
insert、update、delete元素
属性含义
id命名空间中的唯-标识符
parameterType将要传入语句的参数的完全限定类名或别名。这个属性是可选的,因为MyBatis可以通过TypeHandler推断出具体传入语句的参数类型,默认值为unset。
flushCache将其设置为true ,任何时候只要语句被调用都会导致本地缓存和二级缓存都会被清空,默认值: true (对应插入、更新和删除语句)。
timeout这个设置是在抛出异常之前,驱动程序等待数据库返回请求结果的秒数。默认值为unset (依赖驱动)。
statementTypeSTATEMENT , PREPARED或CALLABLE的一个。 这会让MyBatis分别使用Statement , PreparedStatement或CallableStatement ,默认值: PREPARED。
useGeneratedKeys(仅对insert和update有用)这会令MyBatis使用JDBC的getGeneratedKeys方法来取出由数据库内部生成的主键(比如:像MySQL和SQL Server这样的关系数据库管理系统的自动递增字段) ,默认值: false
keyProperty(仅对insert和update有用)唯一标记一个属性, MyBatis会通过getGeneratedKeys的返回值或者通过insert语句的selectKey子元素设置它的键值,默认: unset。
keyColumn(仅对insert和update有用)通过生成的键值设置表中的列名,这个设置仅在某些数据库(像PostgreSQL )是必须的,当主键列不是表中的第一列的时候需要设置。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。
databaseld如果配置了databaseldProvider . MyBatis会加载所有的不带databaseld或匹配当前databaseld的语句;如果带或者不带的语句都有,则不带的会被忽略。

1、EmployeeMapper接口中定义insert、update、delete对应的方法

void addEmp(Employee employee);

void updateEmp(Employee employee);

void deleteEmpById(Integer id);

2、映射文件配置对应的sql映射


    insert into tbl_employee(last_name, email, gender,d_id) values (#{lastname},#{email},#{gender},#{dept.id})


    update tbl_employee set last_name=#{lastname},email=#{email},gender=#{gender},d_id=#{dept.id} where id = #{id}


    delete from tbl_employee where id =  #{id}

parameterType:参数类型,可以省略

3、测试

try {
    EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
    //增
    Employee employee = new Employee(null, "李四", "lisi@qq.com", "1",new Dept(1002,"生产部"));
    mapper.addEmp(employee);
    sqlSession.commit();
} catch (Exception e) {
    e.printStackTrace();
}finally {
    sqlSession.close();
}

结果:

DEBUG 10-15 16:27:32,328 ==>  Preparing: insert into tbl_employee(last_name, email, gender,d_id) values (?,?,?,?)   (baseJdbcLogger.java:145) 
DEBUG 10-15 16:27:32,378 ==> Parameters: 李四(String), lisi@qq.com(String), 1(String), 1002(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-15 16:27:32,382 <==    Updates: 1  (baseJdbcLogger.java:145) 

Process finished with exit code 0

try {
    EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

    //改
    Employee tom = new Employee(2, "tom", "tom002@qq.com", "1",new Dept(1002,null));
    mapper.updateEmp(tom);
    
    sqlSession.commit();
} catch (Exception e) {
    e.printStackTrace();
}finally {
    sqlSession.close();
}

结果:

DEBUG 10-15 16:40:03,706 ==>  Preparing: update tbl_employee set last_name=?,email=?,gender=?,d_id=? where id = ?   (baseJdbcLogger.java:145) 
DEBUG 10-15 16:40:03,761 ==> Parameters: tom(String), tom002@qq.com(String), 1(String), 1002(Integer), 2(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-15 16:40:03,765 <==    Updates: 1  (baseJdbcLogger.java:145) 

Process finished with exit code 0

try {
	 EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);

	 //删
	 mapper.deleteEmpById(9);

	 sqlSession.commit();
} catch (Exception e) {
 	e.printStackTrace();
}finally {
 	sqlSession.close();
}

结果:

DEBUG 10-15 16:43:38,360 ==>  Preparing: delete from tbl_employee where id = ?   (baseJdbcLogger.java:145) 
DEBUG 10-15 16:43:38,424 ==> Parameters: 9(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-15 16:43:38,427 <==    Updates: 1  (baseJdbcLogger.java:145) 

Process finished with exit code 0

主键生成方式

若数据库支持自动生成主键的字段(比如 MySQL 和 SQL Server),则可以设置useGeneratedKeys=”true”,然后再把keyProperty 设置到目标属性上。

不自动生成主键时运行结果:

DEBUG 10-15 17:57:44,062 ==>  Preparing: insert into tbl_employee(last_name, email, gender,d_id) values (?,?,?,?)   (baseJdbcLogger.java:145) 
DEBUG 10-15 17:57:44,111 ==> Parameters: 李四(String), lisi@qq.com(String), 1(String), 1002(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-15 17:57:44,114 <==    Updates: 1  (baseJdbcLogger.java:145) 
null

Process finished with exit code 0

添加自动生成主键


    insert into tbl_employee(last_name, email, gender,d_id) values (#{lastname},#{email},#{gender},#{dept.id})

mysql支持自增主键,自增主键值的获取,mybatis也是利用statement.getGenreatedKeys();
 useGeneratedKeys=“true”:使用自增主键获取主键值策略
 keyProperty:指定对应的主键属性,也就是mybatis获取到主键值以后,将这个值封装给javaBean的哪个属性

try {
   EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
   //增
   Employee employee = new Employee(null, "李四", "lisi@qq.com", "1",new Dept(1002,"生产部"));
   mapper.addEmp(employee);
   System.out.println(employee.getId());

   sqlSession.commit();
} catch (Exception e) {
   e.printStackTrace();
}finally {
   sqlSession.close();
}

结果:

DEBUG 10-15 17:58:44,062 ==>  Preparing: insert into tbl_employee(last_name, email, gender,d_id) values (?,?,?,?)   (baseJdbcLogger.java:145) 
DEBUG 10-15 17:58:44,111 ==> Parameters: 李四(String), lisi@qq.com(String), 1(String), 1002(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-15 17:58:44,114 <==    Updates: 1  (baseJdbcLogger.java:145) 
10

Process finished with exit code 0

而对于不支持自增型主键的数据库(例如Oracle),则可以使用 selectKey 子元素:
selectKey 元素将会首先运行,id 会被设置,然后插入语句会被调用。


    
        
        
        select EMPLOYEES_SEQ.nextval from dual
        
    

    
    
    insert into employees(EMPLOYEE_ID,LAST_NAME,EMAIL)
    values(#{id},#{lastname},#{email})
    

Oracle不支持自增;Oracle使用序列来模拟自增;每次插入的数据的主键是从序列中拿到的值
 keyProperty:查出的主键值封装给javaBean的哪个属性
 order=“BEFORE”:当前sql在插入sql之前运行
     AFTER:当前sql在插入sql之后运行
 resultType:查出的数据的返回值类型
BEFORE运行顺序:
  先运行selectKey查询id的sql;查出id值封装给javaBean的id属性
  在运行插入的sql;就可以取出id属性对应的值
AFTER运行顺序:
  先运行插入的sql(从序列中取出新值作为id)
  再运行selectKey查询id的sql

属性含义
keyPropertyselectKey语句结果应该被设置的目标属性。
keyColumn匹配属性的返回结果集中的列名称。
resultType返回结果的类型。MyBatis 通常可以推算出来,但是为了更加确定写上也不会有什么问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。
order可以被设置为BEFORE或AFTER。如果设置为BEFORE ,那么它会首先选择主键,设置keyProperty然后执行插入语句。如果设置为AFTER ,那么先执行插入语句,然后是selectKey元素
statementType与前面相同, MyBatis支持STATEMENT , PREPARED和CALLABLE语句的映射类型,分别代表PreparedStatement和CallableStatement类型
参数处理(Parameters) 1、单个参数

可以接受基本类型,对象类型,集合类型的值。这种情况MyBatis可直接使用这个参数,不需要经过任何处理。

#{参数名/任意名}:取出参数值。

例:
EmployeeMapper接口中增加根据id查询employee的方法

Employee getEmpById(Integer id);

    select id, last_name lastName, email, gender,d_id from tbl_employee where id = #{param1} and last_name = #{param2}

结果:

DEBUG 10-15 18:47:20,705 ==>  Preparing: select id, last_name lastName, email, gender,d_id from tbl_employee where id = ? and last_name = ?   (baseJdbcLogger.java:145) 
DEBUG 10-15 18:47:20,779 ==> Parameters: 7(Integer), lucy(String)  (baseJdbcLogger.java:145) 
DEBUG 10-15 18:47:20,823 <==      Total: 1  (baseJdbcLogger.java:145) 
Employee{id=7, lastname='lucy', email='lucy@qq.com', gender='0', dept=null}

Process finished with exit code 0
3、命名参数

当参数很多的时候,paramN也不太好区分,这时候可以选择命名参数。

【命名参数】:明确指定封装参数时map的key;@Param(“id”)
  多个参数会被封装成 一个map,
  key:使用@Param注解指定的值
  value:参数值
  #{指定的key}取出对应的参数值

EmployeeMapper接口中使用@param注解指定

Employee getEmpByIdAndLastname(@Param("id") Integer id, @Param("lastname") String lastname);

这时候映射文件中即可使用命名参数


    select id, last_name lastName, email, gender,d_id from tbl_employee where id = #{id} and last_name = #{lastname}

结果:

DEBUG 10-15 18:55:32,991 ==>  Preparing: select id, last_name lastName, email, gender,d_id from tbl_employee where id = ? and last_name = ?   (baseJdbcLogger.java:145) 
DEBUG 10-15 18:55:33,033 ==> Parameters: 7(Integer), lucy(String)  (baseJdbcLogger.java:145) 
DEBUG 10-15 18:55:33,063 <==      Total: 1  (baseJdbcLogger.java:145) 
Employee{id=7, lastname='lucy', email='lucy@qq.com', gender='0', dept=null}

Process finished with exit code 0
4、POJO实体对象参数

如果多个参数正好是我们业务逻辑的数据模型,我们就可以直接传入pojo。

#{pojo属性名}:取出传入的pojo的属性值

EmployeeMapper接口中增加getEmpByPojo方法

Employee getEmpByPojo(Employee employee);

    select id, last_name lastName, email, gender,d_id from tbl_employee where id = #{id} and last_name = #{ lastname }

try {
	EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
	
	Employee employee = new Employee(1, "张三", null, null);
    System.out.println(mapper.getEmpByPojo(employee));

	sqlSession.commit();
} catch (Exception e) {
	e.printStackTrace();
}finally {
	sqlSession.close();
}

结果:

DEBUG 10-15 19:18:16,301 ==>  Preparing: select id, last_name lastName, email, gender,d_id from tbl_employee where id = ? and last_name = ?   (baseJdbcLogger.java:145) 
DEBUG 10-15 19:18:16,418 ==> Parameters: 1(Integer), 张三(String)  (baseJdbcLogger.java:145) 
DEBUG 10-15 19:18:16,495 <==      Total: 1  (baseJdbcLogger.java:145) 
Employee{id=1, lastname='张三', email='zhangsan@qq.com', gender='1', dept=null}

Process finished with exit code 0
5、Map传参

如果多个参数不是业务模型中的数据,没有对应的pojo,不经常使用,为了方便,我们也可以传入map

#{map中的key}:取出map中对应的值

EmployeeMapper接口中增加getEmpByMap方法

Employee getEmpByMap(Map map);

    select id, last_name lastName, email, gender,d_id from tbl_employee where id = #{id} and last_name = #{ lastname }

try {
	EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
	
	Map map = new HashMap<>();
    map.put("id",1);
    map.put("lastname","张三");
    Employee empByMap = mapper.getEmpByMap(map);
    System.out.println(empByMap);

	sqlSession.commit();
} catch (Exception e) {
	e.printStackTrace();
}finally {
	sqlSession.close();
}

结果:

DEBUG 10-15 19:32:13,717 ==>  Preparing: select id, last_name lastName, email, gender,d_id from tbl_employee where id = ? and last_name = ?   (baseJdbcLogger.java:145) 
DEBUG 10-15 19:32:13,766 ==> Parameters: 1(Integer), 张三(String)  (baseJdbcLogger.java:145) 
DEBUG 10-15 19:32:13,810 <==      Total: 1  (baseJdbcLogger.java:145) 
Employee{id=1, lastname='张三', email='zhangsan@qq.com', gender='1', dept=null}

Process finished with exit code 0
6、TO传参

如果多个参数不是业务模型中的数据,但是经常要使用,推荐来编写一个TO(Transfer Object)数据传输对象(即将需要传参的参数写一个对象,把这些参数封装成这个对象的属性,然后同pojo用法一致)

7、扩展 a、接口中一个加了@param,一个没加

Employee getEmp(@Param(“id”)Integer id,String lastName);
取值:id==>#{id或param1} lastName==>#{param2}

b、接口中有实体类,实体类加了@param

Employee getEmp(Integer id,@Param(“e”)Employee emp);
取值:id==>#{param1} lastName===>#{param2.lastName或者e.lastName}

c、参数中有list

特别注意:如果是Collection(List、Set)类型或者是数组, 也会特殊处理。也是把传入的list或者数组封装在map中。
key:Collection(collection),如果是List还可以使用这个key(list)、数组(array)

Employee getEmpById(List ids);
取值:取出第一个id的值: #{ ids[0]}或者#{list[0]}

总结:参数多时会封装map,为了不混乱,我们可以使用@Param来指定封装时使用的key;
#{key}就可以取出map中的值;

参数值的获取

#{}:可以获取map中的值或者pojo对象属性的值;获取参数的值,预编译到SQL中。安全。
${}:可以获取map中的值或者pojo对象属性的值;获取参数的值,拼接到SQL中。有SQL注入问题。
大多情况下,我们去参数的值都应该去使用#{};

原生jdbc不支持占位符的地方我们就可以使用${}进行取值, 比如分表、排序。。。;
例:按照年份分表拆分

select * from ${year}_salary where xxx;
select * from tbl_employee order by ${f_name} 

#{}:更丰富的用法:
 规定参数的一些规则:
  javaType、 jdbcType、 mode(存储过程)、 numericScale、
  resultMap、 typeHandler、 jdbcTypeName、 expression(未来准备支持的功能)

jdbcType通常需要在某种特定的条件下被设置:
实际上通常被设置的是:
 在我们数据为null的时候,有些数据库可能不能识别mybatis对null的默认处理。比如Oracle(报错);
 JdbcType OTHER:无效的类型;因为mybatis对所有的null都映射的是原生Jdbc的OTHER类型,oracle不能正确处理;

由于全局配置中:jdbcTypeForNull=OTHER;oracle不支持;两种办法
1、取值时指定,只影响当前的:#{email,jdbcType=OTHER};
2、修改全局配置。影响全局:

mode 属性允许指定 IN,OUT 或 INOUT 参数。如果参数为 OUT 或 INOUT,参数对象属性的真实值将会被改变,就像在获取输出参数时所期望的那样。

select元素

Select元素来定义查询操作。

常用的三个属性:
Id:唯一标识符。用来引用这条语句,需要和接口的方法名一致
parameterType:参数类型。可以不传,MyBatis会根据TypeHandler自动推断
resultType:返回值类型。 别名或者全类名,如果返回的是集合,定义集合中元素的类型。不能和resultMap同时使用

属性含义
parameterType将会传入这条语句的参数类的完全限定名或别名。这个属性是可选的.因为MyBatis可以通过TypeHandler推断出具体传入语句的参数,默认值为unset.
resultType从这条语句中返回的期望类型的类的完全限定名或别名。注意如果是集合那应该是集合可以包含的类型,而不能是集合本身该属性。和resultMap 不能同时使用。
resultMap外部resultMap的命名引用。和resultType属性不能同时使用。
flushCache将其设置为true ,任何时候只要语句被调用,都会导致本地缓存和二级缓存都会被清空,默认值: false
useCache将其设置为true ,将会导致本条语句的结果被二级缓存。默认值:对select元素为true
timeout这个设置是在抛出异常之前.驱动程序等待数据库返回请求结果的秒数。默认值为unset (依赖驱动)。
fetchSize影响驱动程序每次批量返回的结果行数。默认值为unset (依赖驱动)。
statementTypeSTATEMENT , PREPARED或CALLABLE的一个。 这会让MyBatis分别使用Statement , PreparedStatement或CallableStatement ,默认值: PREPARED。
resultSetTypeFORWARD_ onLY . SCROLL _SENSITIVE或SCROLL _INSENSITIVE中的一个,默认值为unset (依赖驱动)
databaseld如果配置了databaseldProvider , MyBatis会加载所有的不带databaseld或匹配当前databaseld的语句;如果带或者不带的语句都有,则不带的会被忽略。
resultOrdered这个设置仅针对嵌套结果select语句适用:如果为true ,就假设包含了嵌套结果集或是分组,这样当返回-个主结果行,就不会发生有对前面结果集引用的情况。这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值: false
resultSets这个设置仅对多结果集的情况适用,它将列出语句执行后返回的结果集并每个结果集给一 个名称,名称是逗号分隔的
1、查询返回List

EmployeeMapper接口中增加名字模糊查询employee的方法

List getEmpByNameLike(String lastname);

    select * from tbl_employee where id=#{id}

association定义关联对象的封装规则:
 select:表明当前属性是调用select指定的方法查出的结果
 column:指定将哪一列的值传给这个方法
 流程:使用select指定的方法(传入column指定的这列参数的值)查出对象,并封装给property指定的属性

try {
	EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
	
	System.out.println(mapper.getEmpAndDeptStep(2));
	
	sqlSession.commit();
} catch (Exception e) {
	e.printStackTrace();
}finally {
	sqlSession.close();
}

结果:

DEBUG 10-16 15:53:08,624 ==>  Preparing: select * from tbl_employee where id=?   (baseJdbcLogger.java:145) 
DEBUG 10-16 15:53:08,671 ==> Parameters: 2(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 15:53:08,749 <==      Total: 1  (baseJdbcLogger.java:145) 
DEBUG 10-16 15:53:08,749 ==>  Preparing: select id,dept_name deptName from tbl_dept where id = ?   (baseJdbcLogger.java:145) 
DEBUG 10-16 15:53:08,749 ==> Parameters: 1002(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 15:53:08,749 <==      Total: 1  (baseJdbcLogger.java:145) 
Employee{id=2, lastname='tom', email='tom002@qq.com', gender='1', dept=Dept{id=1002, deptName='生产部'}}

Process finished with exit code 0
示例四:分段查询之延迟加载

在不开启延迟加载的情况下,每次我们采用分段查询,它都是将多条sql查询语句同时执行,如果开启延迟加载(懒加载、按需加载),当我们需要使用其他表的信息时,它才会再去加载查询其他表的信息。开启方法:分段查询的基础之上加上两个配置。

配置全局配置文件mybatis-config.xml


	
	
	

测试一:不使用部门信息

try {
	EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
	
	Employee employee = mapper.getEmpAndDeptStep(2);
    System.out.println(employee.getLastname());

	sqlSession.commit();
} catch (Exception e) {
	e.printStackTrace();
}finally {
	sqlSession.close();
}

结果:只有一条查询语句

DEBUG 10-16 16:10:12,753 ==>  Preparing: select * from tbl_employee where id=?   (baseJdbcLogger.java:145) 
DEBUG 10-16 16:10:12,799 ==> Parameters: 2(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 16:10:12,909 <==      Total: 1  (baseJdbcLogger.java:145) 
tom

Process finished with exit code 0

测试二:使用部门信息

try {
	EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
	
	Employee employee = mapper.getEmpAndDeptStep(2);
    System.out.println(employee.getDept());

	sqlSession.commit();
} catch (Exception e) {
	e.printStackTrace();
}finally {
	sqlSession.close();
}

结果:两条查询语句

DEBUG 10-16 16:11:32,939 ==>  Preparing: select * from tbl_employee where id=?   (baseJdbcLogger.java:145) 
DEBUG 10-16 16:11:32,985 ==> Parameters: 2(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 16:11:33,064 <==      Total: 1  (baseJdbcLogger.java:145) 
DEBUG 10-16 16:11:33,064 ==>  Preparing: select id,dept_name deptName from tbl_dept where id = ?   (baseJdbcLogger.java:145) 
DEBUG 10-16 16:11:33,064 ==> Parameters: 1002(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 16:11:33,064 <==      Total: 1  (baseJdbcLogger.java:145) 
Dept{id=1002, deptName='生产部'}

Process finished with exit code 0
Collection集合类型

案例:查询部门的时候将部门对应的所有员工信息也查询出来

示例一:Collection嵌套结果集

DeptMapper接口中增加方法

Dept getDeptByIdPlus(Integer id);

DeptMapper映射文件


   
   
   
       
       
       
       
   


   SELECT d.id did,d.dept_name dept_name,
          e.id eid,e.last_name last_name,e.email email,e.gender gender
   FROM tbl_dept d
       LEFT JOIN tbl_employee e
       ON d.id=e.d_id
   WHERe d.id=#{id}

使用collection标签定义关联的集合类型的属性封装规则:
 collection定义关联集合类型的属性的封装规则
 ofType:指定集合里面元素的类型

测试代码:

try {
	DeptMapper mapper = sqlSession.getMapper(DeptMapper.class);
    Dept dept = mapper.getDeptByIdPlus(1001);
    System.out.println(dept);
    dept.getEmps().forEach(System.out::println);
	sqlSession.commit();
} catch (Exception e) {
	e.printStackTrace();
}finally {
	sqlSession.close();
}

结果:

DEBUG 10-16 16:36:45,729 ==>  Preparing: SELECT d.id did,d.dept_name dept_name, e.id eid,e.last_name last_name,e.email email,e.gender gender FROM tbl_dept d LEFT JOIN tbl_employee e ON d.id=e.d_id WHERe d.id=?   (baseJdbcLogger.java:145) 
DEBUG 10-16 16:36:45,776 ==> Parameters: 1001(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 16:36:45,823 <==      Total: 2  (baseJdbcLogger.java:145) 
Dept{id=1001, deptName='研发部'}
Employee{id=1, lastname='张三', email='zhangsan@qq.com', gender='1', dept=null}
Employee{id=7, lastname='lucy', email='lucy@qq.com', gender='0', dept=null}

Process finished with exit code 0
示例二:Collection分步查询

EmployeeMapper接口中增加方法

List getEmpsByDeptId(Integer DeptId);

EmployeeMapper映射文件


   select id, last_name lastName, email, gender  from tbl_employee where d_id=#{deptId}

DeptMapper接口中增加方法

Dept getDeptByIdStep(Integer id);

DeptMapper映射文件


    
    
    
    


    select * from tbl_employee where id=#{id}

  • discriminator:
     column:指定判定的列名
      javaType:列值对应的java类型
  • case : 基于某些值的结果映射
    嵌入结果映射 这种情形结果也映射它本身,因此可以包含很多相同的元素,或者它可以参照一个外部的结果映射。
      value:case匹配value值选择结果映射
      resultType:指定封装的结果类型,不能缺少

测试1:男生

try {
	EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
	
	System.out.println(mapper.getEmpAndDeptStep(1));
	
	sqlSession.commit();
} catch (Exception e) {
	e.printStackTrace();
}finally {
	sqlSession.close();
}

结果:

DEBUG 10-16 17:31:42,589 ==>  Preparing: select * from tbl_employee where id=?   (baseJdbcLogger.java:145) 
DEBUG 10-16 17:31:42,667 ==> Parameters: 1(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 17:31:42,698 <==      Total: 1  (baseJdbcLogger.java:145) 
Employee{id=1, lastname='张三', email='张三', gender='1', dept=null}

Process finished with exit code 0

测试2:女生

try {
	EmployeeMapper mapper = sqlSession.getMapper(EmployeeMapper.class);
	
	System.out.println(mapper.getEmpAndDeptStep(3));
	
	sqlSession.commit();
} catch (Exception e) {
	e.printStackTrace();
}finally {
	sqlSession.close();
}

结果:

DEBUG 10-16 17:32:27,611 ==>  Preparing: select * from tbl_employee where id=?   (baseJdbcLogger.java:145) 
DEBUG 10-16 17:32:27,674 ==> Parameters: 3(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 17:32:27,752 <==      Total: 1  (baseJdbcLogger.java:145) 
DEBUG 10-16 17:32:27,752 ==>  Preparing: select id,dept_name deptName from tbl_dept where id = ?   (baseJdbcLogger.java:145) 
DEBUG 10-16 17:32:27,752 ==> Parameters: 1003(Integer)  (baseJdbcLogger.java:145) 
DEBUG 10-16 17:32:27,752 <==      Total: 1  (baseJdbcLogger.java:145) 
Employee{id=3, lastname='jerry', email='jerry@qq.com', gender='0', dept=Dept{id=1003, deptName='销售部'}}

Process finished with exit code 0
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/327754.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号