第一章:Mybatis 分页插件 — PageHelper

  • 导入相关 jar 包的 Maven 坐标:
  1. <!-- Mybatis -->
  2. <dependency>
  3. <groupId>org.mybatis</groupId>
  4. <artifactId>mybatis</artifactId>
  5. <version>3.4.1</version>
  6. </dependency>
  7. <!-- 日志 -->
  8. <dependency>
  9. <groupId>log4j</groupId>
  10. <artifactId>log4j</artifactId>
  11. <version>1.2.17</version>
  12. </dependency>
  13. <!-- MySQL驱动 -->
  14. <dependency>
  15. <groupId>mysql</groupId>
  16. <artifactId>mysql-connector-java</artifactId>
  17. <version>8.0.21</version>
  18. </dependency>
  19. <!-- Junit单元测试 -->
  20. <dependency>
  21. <groupId>junit</groupId>
  22. <artifactId>junit</artifactId>
  23. <version>4.13</version>
  24. <scope>test</scope>
  25. </dependency>
  26. <!-- 分页插件 -->
  27. <dependency>
  28. <groupId>com.github.pagehelper</groupId>
  29. <artifactId>pagehelper</artifactId>
  30. <version>5.1.11</version>
  31. </dependency>
  • sql 脚本:
  1. DROP TABLE IF EXISTS `employee`;
  2. CREATE TABLE `employee` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `last_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  5. `gender` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  6. `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  7. PRIMARY KEY (`id`) USING BTREE
  8. ) ENGINE = InnoDB AUTO_INCREMENT = 6 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  9. INSERT INTO `employee` VALUES (1, 'jerry', '男', 'jerry@qq.com');
  10. INSERT INTO `employee` VALUES (2, 'aa', '男', 'aa@11.com');
  11. INSERT INTO `employee` VALUES (3, 'bb', '男', 'bb@11.com');
  12. INSERT INTO `employee` VALUES (4, 'aa', '男', 'aa@11.com');
  13. INSERT INTO `employee` VALUES (5, 'bb', '男', 'bb@11.com');
  • log4j.xml
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
  3. <log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
  4. <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
  5. <param name="Encoding" value="UTF-8" />
  6. <layout class="org.apache.log4j.PatternLayout">
  7. <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m (%F:%L) \n" />
  8. </layout>
  9. </appender>
  10. <logger name="java.sql">
  11. <level value="debug" />
  12. </logger>
  13. <logger name="org.apache.ibatis">
  14. <level value="info" />
  15. </logger>
  16. <root>
  17. <level value="debug" />
  18. <appender-ref ref="STDOUT" />
  19. </root>
  20. </log4j:configuration>
  • Employee.java
  1. package com.sunxiaping.domain;
  2. import org.apache.ibatis.type.Alias;
  3. import java.io.Serializable;
  4. @Alias("emp")
  5. public class Employee implements Serializable {
  6. private Integer id;
  7. private String lastName;
  8. private String email;
  9. private String gender;
  10. public Integer getId() {
  11. return id;
  12. }
  13. public void setId(Integer id) {
  14. this.id = id;
  15. }
  16. public String getLastName() {
  17. return lastName;
  18. }
  19. public void setLastName(String lastName) {
  20. this.lastName = lastName;
  21. }
  22. public String getEmail() {
  23. return email;
  24. }
  25. public void setEmail(String email) {
  26. this.email = email;
  27. }
  28. public String getGender() {
  29. return gender;
  30. }
  31. public void setGender(String gender) {
  32. this.gender = gender;
  33. }
  34. @Override
  35. public String toString() {
  36. return "Employee{" +
  37. "id=" + id +
  38. ", lastName='" + lastName + '\'' +
  39. ", email='" + email + '\'' +
  40. ", gender='" + gender + '\'' +
  41. '}';
  42. }
  43. }
  • EmployeeMapper.java
  1. package com.sunxiaping.mapper;
  2. import com.sunxiaping.domain.Employee;
  3. import org.apache.ibatis.annotations.Mapper;
  4. import org.apache.ibatis.annotations.Result;
  5. import org.apache.ibatis.annotations.Results;
  6. import org.apache.ibatis.annotations.Select;
  7. import java.util.List;
  8. @Mapper
  9. public interface EmployeeMapper {
  10. @Select(" SELECT * FROM employee ")
  11. @Results({
  12. @Result(id = true, property = "id", column = "id"),
  13. @Result(property = "lastName", column = "last_name"),
  14. @Result(property = "email", column = "email"),
  15. @Result(property = "gender", column = "gender")}
  16. )
  17. List<Employee> findAllEmps();
  18. }
  • mybatis-config.xml
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 注册插件 -->
  7. <plugins>
  8. <!-- com.github.pagehelper为PageHelper类所在包名 -->
  9. <plugin interceptor="com.github.pagehelper.PageInterceptor">
  10. <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
  11. <property name="param1" value="value1"/>
  12. </plugin>
  13. </plugins>
  14. <environments default="development">
  15. <environment id="development">
  16. <transactionManager type="JDBC"/>
  17. <dataSource type="POOLED">
  18. <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
  19. <property name="url"
  20. value="jdbc:mysql://192.168.134.100:3306/test?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true"/>
  21. <property name="username" value="root"/>
  22. <property name="password" value="123456"/>
  23. </dataSource>
  24. </environment>
  25. </environments>
  26. <mappers>
  27. <package name="com.sunxiaping.mapper"/>
  28. </mappers>
  29. </configuration>
  • 测试:
  1. package com.sunxiaping;
  2. import com.github.pagehelper.Page;
  3. import com.github.pagehelper.PageHelper;
  4. import com.sunxiaping.domain.Employee;
  5. import com.sunxiaping.mapper.EmployeeMapper;
  6. import org.apache.ibatis.io.Resources;
  7. import org.apache.ibatis.session.SqlSession;
  8. import org.apache.ibatis.session.SqlSessionFactory;
  9. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  10. import java.io.IOException;
  11. import java.io.InputStream;
  12. import java.util.List;
  13. public class EmployeeTest {
  14. public static void main(String[] args) throws IOException {
  15. String resource = "mybatis-config.xml";
  16. InputStream inputStream = Resources.getResourceAsStream(resource);
  17. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  18. SqlSession sqlSession = sqlSessionFactory.openSession();
  19. EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
  20. Page<Object> page = PageHelper.startPage(3, 2);
  21. List<Employee> employeeList = employeeMapper.findAllEmps();
  22. System.out.println("employeeList = " + employeeList);
  23. System.out.println("当前页码:" + page.getPageNum());
  24. System.out.println("总记录数:" + page.getTotal());
  25. System.out.println("每页的记录数:" + page.getPageSize());
  26. System.out.println("总页码:" + page.getPages());
  27. sqlSession.close();
  28. }
  29. }

第二章:批量操作

  • BatchExecutor,只需要在 SqlSession 中设置如下的代码:
  1. SqlSession sqlSession = sqlSessionFactory.openSession(ExecutorType.BATCH);
  • 如果 Mybatis 和 Spring 整合,则需要额外的配置:
  1. <!--配置一个可以进行批量执行的sqlSession -->
  2. <bean id="sqlSession" class="org.mybatis.spring.SqlSessionTemplate">
  3. <constructor-arg name="sqlSessionFactory" ref="sqlSessionFactoryBean"></constructor-arg>
  4. <constructor-arg name="executorType" value="BATCH"></constructor-arg>
  5. </bean>

第三章:自定义类型处理器

3.1 概述

  • 我们可以通过自定义 TypeHandler 的形式来设置参数或者取出结果集的时候自定义参数封装策略。

3.2 开发步骤和应用示例

  • 步骤:

    • ① 实现 TypeHandler 接口或者继承 BaseTypeHandler 。
    • ② 使用 @MappedTypes 定义处理的 java 类型,使用 @MappedJdbcTypes 定义 jdbcType 类型。
    • ③ 在自定义结果集标签或者参数处理的时候声明使用自定义 TypeHandler 进行处理或者在全局配置 TypeHandler 要处理的 javaType 。
  • 示例:Mybatis 默认处理枚举的类型(EnumTypeHandler)

  • sql 脚本:
  1. DROP TABLE IF EXISTS `employee`;
  2. CREATE TABLE `employee` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `last_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  5. `gender` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  6. `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  7. `emp_status` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  8. PRIMARY KEY (`id`) USING BTREE
  9. ) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  10. -- ----------------------------
  11. -- Records of employee
  12. -- ----------------------------
  13. INSERT INTO `employee` VALUES (1, 'jerry', '男', 'jerry@qq.com', NULL);
  14. INSERT INTO `employee` VALUES (2, 'aa', '男', 'aa@11.com', NULL);
  15. INSERT INTO `employee` VALUES (3, 'bb', '男', 'bb@11.com', NULL);
  16. INSERT INTO `employee` VALUES (4, 'aa', '男', 'aa@11.com', NULL);
  17. INSERT INTO `employee` VALUES (5, 'bb', '男', 'bb@11.com', NULL);
  18. INSERT INTO `employee` VALUES (6, '哈哈', '男', 'haha@qq.com', 'LOGIN');
  19. INSERT INTO `employee` VALUES (7, '哈哈', '男', 'haha@qq.com', 'LOGIN');
  20. INSERT INTO `employee` VALUES (8, '哈哈', '男', 'haha@qq.com', 'LOGIN');
  21. INSERT INTO `employee` VALUES (9, '哈哈', '男', 'haha@qq.com', 'LOGIN');
  22. INSERT INTO `employee` VALUES (10, '哈哈', '男', 'haha@qq.com', 'LOGIN');
  • EmpStatus.java
  1. package com.sunxiaping.enums;
  2. /**
  3. * 用户状态
  4. */
  5. public enum EmpStatus {
  6. LOGIN, LOGOUT, REMOVE
  7. }
  • Employee.java
  1. package com.sunxiaping.domain;
  2. import com.sunxiaping.enums.EmpStatus;
  3. import java.io.Serializable;
  4. public class Employee implements Serializable {
  5. private Integer id;
  6. private String lastName;
  7. private String email;
  8. private String gender;
  9. private EmpStatus empStatus;
  10. public EmpStatus getEmpStatus() {
  11. return empStatus;
  12. }
  13. public void setEmpStatus(EmpStatus empStatus) {
  14. this.empStatus = empStatus;
  15. }
  16. public Integer getId() {
  17. return id;
  18. }
  19. public void setId(Integer id) {
  20. this.id = id;
  21. }
  22. public String getLastName() {
  23. return lastName;
  24. }
  25. public void setLastName(String lastName) {
  26. this.lastName = lastName;
  27. }
  28. public String getEmail() {
  29. return email;
  30. }
  31. public void setEmail(String email) {
  32. this.email = email;
  33. }
  34. public String getGender() {
  35. return gender;
  36. }
  37. public void setGender(String gender) {
  38. this.gender = gender;
  39. }
  40. @Override
  41. public String toString() {
  42. return "Employee{" +
  43. "id=" + id +
  44. ", lastName='" + lastName + '\'' +
  45. ", email='" + email + '\'' +
  46. ", gender='" + gender + '\'' +
  47. ", empStatus=" + empStatus +
  48. '}';
  49. }
  50. }
  • EmployeeMapper.java
  1. package com.sunxiaping.mapper;
  2. import com.sunxiaping.domain.Employee;
  3. import org.apache.ibatis.annotations.Insert;
  4. import org.apache.ibatis.annotations.Mapper;
  5. import org.apache.ibatis.annotations.Options;
  6. @Mapper
  7. public interface EmployeeMapper {
  8. @Insert(" INSERT INTO `employee` (last_name,email,gender,emp_status) VALUES (#{lastName},#{email},#{gender},#{empStatus}) ")
  9. @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
  10. void addEmp(Employee employee);
  11. }
  • 测试:
  1. package com.sunxiaping;
  2. import com.sunxiaping.domain.Employee;
  3. import com.sunxiaping.enums.EmpStatus;
  4. import com.sunxiaping.mapper.EmployeeMapper;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import java.io.IOException;
  10. import java.io.InputStream;
  11. public class EmployeeTest {
  12. /**
  13. * 默认情况下,Mybatis在处理枚举对象的时候保存的是枚举的名字:EnumTypeHandler
  14. *
  15. * @param args
  16. * @throws IOException
  17. */
  18. public static void main(String[] args) throws IOException {
  19. String resource = "mybatis-config.xml";
  20. InputStream inputStream = Resources.getResourceAsStream(resource);
  21. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  22. SqlSession sqlSession = sqlSessionFactory.openSession();
  23. EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
  24. Employee employee = new Employee();
  25. employee.setLastName("哈哈");
  26. employee.setGender("男");
  27. employee.setEmail("haha@qq.com");
  28. employee.setEmpStatus(EmpStatus.LOGIN);
  29. employeeMapper.addEmp(employee);
  30. System.out.println("employee = " + employee);
  31. EmpStatus empStatus = EmpStatus.LOGIN;
  32. System.out.println("枚举的索引" + empStatus.ordinal());
  33. System.out.println("枚举的名称" + empStatus.name());
  34. sqlSession.commit();
  35. sqlSession.close();
  36. }
  37. }
  • 示例:使用自定义的类型处理器处理枚举类型
  • sql 脚本:
  1. DROP TABLE IF EXISTS `employee`;
  2. CREATE TABLE `employee` (
  3. `id` int(11) NOT NULL AUTO_INCREMENT,
  4. `last_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  5. `gender` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  6. `email` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
  7. `emp_status` int(11) NULL DEFAULT NULL,
  8. PRIMARY KEY (`id`) USING BTREE
  9. ) ENGINE = InnoDB AUTO_INCREMENT = 11 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
  10. -- ----------------------------
  11. -- Records of employee
  12. -- ----------------------------
  13. INSERT INTO `employee` VALUES (1, 'jerry', '男', 'jerry@qq.com', NULL);
  14. INSERT INTO `employee` VALUES (2, 'aa', '男', 'aa@11.com', NULL);
  15. INSERT INTO `employee` VALUES (3, 'bb', '男', 'bb@11.com', NULL);
  16. INSERT INTO `employee` VALUES (4, 'aa', '男', 'aa@11.com', NULL);
  17. INSERT INTO `employee` VALUES (5, 'bb', '男', 'bb@11.com', NULL);
  • EmpStatus.java
  1. package com.sunxiaping.enums;
  2. /**
  3. * 用户状态
  4. */
  5. public enum EmpStatus {
  6. LOGIN(100, "用户登录"), LOGOUT(200, "用户登出"), REMOVE(300, "用户不存在");
  7. private Integer code;
  8. private String name;
  9. EmpStatus(Integer code, String name) {
  10. this.code = code;
  11. this.name = name;
  12. }
  13. public Integer getCode() {
  14. return code;
  15. }
  16. public void setCode(Integer code) {
  17. this.code = code;
  18. }
  19. public String getName() {
  20. return name;
  21. }
  22. public void setName(String name) {
  23. this.name = name;
  24. }
  25. }
  • EmployeeMapper.java
  1. package com.sunxiaping.mapper;
  2. import com.sunxiaping.domain.Employee;
  3. import org.apache.ibatis.annotations.*;
  4. @Mapper
  5. public interface EmployeeMapper {
  6. @Insert(" INSERT INTO `employee` (last_name,email,gender,emp_status) VALUES (#{lastName},#{email},#{gender},#{empStatus}) ")
  7. @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
  8. void addEmp(Employee employee);
  9. @Select(" SELECT * FROM employee WHERE id = #{id} ")
  10. @Results({
  11. @Result(id = true, property = "id", column = "id"),
  12. @Result(property = "lastName",column = "last_name"),
  13. @Result(property = "gender",column = "gender"),
  14. @Result(property = "empStatus",column = "emp_status")
  15. })
  16. Employee findById(Integer id);
  17. }
  • SelfTypeHandler.java
  1. package com.sunxiaping.type.handler;
  2. import com.sunxiaping.enums.EmpStatus;
  3. import org.apache.ibatis.type.BaseTypeHandler;
  4. import org.apache.ibatis.type.JdbcType;
  5. import java.sql.CallableStatement;
  6. import java.sql.PreparedStatement;
  7. import java.sql.ResultSet;
  8. import java.sql.SQLException;
  9. /**
  10. * 自定义枚举处理器
  11. */
  12. public class SelfTypeHandler extends BaseTypeHandler<EmpStatus> {
  13. /**
  14. * 定义当前数据如何保存到数据库中
  15. *
  16. * @param ps
  17. * @param i
  18. * @param parameter
  19. * @param jdbcType
  20. * @throws SQLException
  21. */
  22. @Override
  23. public void setNonNullParameter(PreparedStatement ps, int i, EmpStatus parameter, JdbcType jdbcType) throws SQLException {
  24. ps.setInt(i, parameter.getCode());
  25. }
  26. @Override
  27. public EmpStatus getNullableResult(ResultSet rs, String columnName) throws SQLException {
  28. int code = rs.getInt(columnName);
  29. EmpStatus[] empStatuses = EmpStatus.values();
  30. for (EmpStatus empStatus : empStatuses) {
  31. if (empStatus.getCode().equals(code)) {
  32. return empStatus;
  33. }
  34. }
  35. return null;
  36. }
  37. @Override
  38. public EmpStatus getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
  39. int code = rs.getInt(columnIndex);
  40. EmpStatus[] empStatuses = EmpStatus.values();
  41. for (EmpStatus empStatus : empStatuses) {
  42. if (empStatus.getCode().equals(code)) {
  43. return empStatus;
  44. }
  45. }
  46. return null;
  47. }
  48. @Override
  49. public EmpStatus getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
  50. int code = cs.getInt(columnIndex);
  51. EmpStatus[] empStatuses = EmpStatus.values();
  52. for (EmpStatus empStatus : empStatuses) {
  53. if (empStatus.getCode().equals(code)) {
  54. return empStatus;
  55. }
  56. }
  57. return null;
  58. }
  59. }
  • mybatis-config.xml
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <typeHandlers>
  7. <!-- 配置自定义类型处理器 -->
  8. <typeHandler handler="com.sunxiaping.type.handler.SelfTypeHandler" javaType="com.sunxiaping.enums.EmpStatus"></typeHandler>
  9. </typeHandlers>
  10. <environments default="development">
  11. <environment id="development">
  12. <transactionManager type="JDBC"/>
  13. <dataSource type="POOLED">
  14. <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
  15. <property name="url"
  16. value="jdbc:mysql://192.168.134.100:3306/test?useUnicode=true&amp;characterEncoding=UTF-8&amp;autoReconnect=true&amp;useSSL=false&amp;serverTimezone=GMT%2B8&amp;allowPublicKeyRetrieval=true"/>
  17. <property name="username" value="root"/>
  18. <property name="password" value="123456"/>
  19. </dataSource>
  20. </environment>
  21. </environments>
  22. <mappers>
  23. <package name="com.sunxiaping.mapper"/>
  24. </mappers>
  25. </configuration>
  • 测试:
  1. package com.sunxiaping;
  2. import com.sunxiaping.domain.Employee;
  3. import com.sunxiaping.enums.EmpStatus;
  4. import com.sunxiaping.mapper.EmployeeMapper;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import java.io.IOException;
  10. import java.io.InputStream;
  11. public class EmployeeTest {
  12. /**
  13. * 默认情况下,Mybatis在处理枚举对象的时候保存的是枚举的名字:EnumTypeHandler
  14. *
  15. * @param args
  16. * @throws IOException
  17. */
  18. public static void main(String[] args) throws IOException {
  19. String resource = "mybatis-config.xml";
  20. InputStream inputStream = Resources.getResourceAsStream(resource);
  21. SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  22. SqlSession sqlSession = sqlSessionFactory.openSession();
  23. EmployeeMapper employeeMapper = sqlSession.getMapper(EmployeeMapper.class);
  24. Employee employee = new Employee();
  25. employee.setLastName("哈哈");
  26. employee.setGender("男");
  27. employee.setEmail("haha@qq.com");
  28. employee.setEmpStatus(EmpStatus.LOGIN);
  29. employeeMapper.addEmp(employee);
  30. System.out.println("employee = " + employee);
  31. EmpStatus empStatus = EmpStatus.LOGIN;
  32. System.out.println("枚举的索引" + empStatus.ordinal());
  33. System.out.println("枚举的名称" + empStatus.name());
  34. Employee employeeDb = employeeMapper.findById(1);
  35. System.out.println("employeeDb = " + employeeDb);
  36. sqlSession.commit();
  37. sqlSession.close();
  38. }
  39. }