• 小黑子—MyBatis:第四章


    十 小黑子进行MyBatis参数处理

    10.1 单个简单类型参数

    简单类型包括:

    • byte short int long float double char
    • Byte Short Integer Long Float Double Character
    • String
    • java.util.Date
    • java.sql.Date

    简单类型对于mybatis来说都是可以自动类型识别的:

    • 也就是说对于mybatis来说,它是可以自动推断出ps.setXxxx()方法的。ps.setString()还是ps.setInt()。它可以自动推断。

    其实SQL映射文件中的配置比较完整的写法是:

    <select id="selectByName" resultType="student" parameterType="java.lang.String">
      select * from t_student where name = #{name, javaType=String, jdbcType=VARCHAR}
    select>
    
    • 1
    • 2
    • 3

    其中sql语句中的javaType,jdbcType,以及select标签中的parameterType属性,都是用来帮助mybatis进行类型确定的。不过这些配置多数是可以省略的。因为mybatis它有强大的自动类型推断机制。

    • javaType:可以省略
    • jdbcType:可以省略
    • parameterType:可以省略

    准备数据库:
    在这里插入图片描述
    目录展示:
    在这里插入图片描述

    10.1.1 单个参数Long类型

    • StudentMapper
    package com.powernode.mybatis.mapper;
    
    import com.powernode.mybatis.pojo.Student;
    
    import java.util.Date;
    import java.util.List;
    
    public interface StudentMapper {
        /**
         * 当接口中的方法的参数只有一个(单给参数),并且参数的数据类型都是简单类型
         * 根据id查询、name查询、birth查询、sex查询
         * @version 1.0
        */
    
        List<Student> selectById(Long id);
        List<Student> selectByName(String name);
        List<Student> selectByBirth(Date birth);
        List<Student> selectBySex(Character sex);
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • StudentMappper.xml
    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.powernode.mybatis.mapper.StudentMapper">
    
    
        <select id="selectById" resultType="Student" parameterType="java.lang.Long">
            select * from t_student where id = #{id}
        select>
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 测试
    package com.powernode.mybatis.test;
    
    import com.powernode.mybatis.mapper.StudentMapper;
    import com.powernode.mybatis.pojo.Student;
    import com.powernode.mybatis.utils.SqlSessionUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    import java.util.List;
    
    public class StudentMapperTest {
        @Test
        public void SelectById(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> students = mapper.selectById(1L);
    
            students.forEach(student -> System.out.println(student));
    
            sqlSession.commit();
            sqlSession.close();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    在这里插入图片描述

    10.1.2 单个参数Date类型

    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.powernode.mybatis.mapper.StudentMapper">
    
    
        <select id="selectById" resultType="Student" parameterType="java.lang.Long">
            select * from t_student where id = #{id}
        select>
        
        <select id="selectByName" resultType="Student">
            select * from t_student where name = #{name,javaType=String,jdbcType=VARCHAR}
        select>
    
        <select id="selectByBirth" resultType="Student">
            select * from t_student where birth = #{birth}
        select>
    
        <select id="selectBySex" resultType="Student">
            select * from t_student where sex = #{sex}
        select>
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 测试
    package com.powernode.mybatis.test;
    
    import com.powernode.mybatis.mapper.StudentMapper;
    import com.powernode.mybatis.pojo.Student;
    import com.powernode.mybatis.utils.SqlSessionUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    
    public class StudentMapperTest {
    
        @Test
        public void SelectBySex(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            Character sex = Character.valueOf('男');
    
            List<Student> students = mapper.selectBySex(sex);
            students.forEach(student -> System.out.println(student));
    
            sqlSession.commit();
            sqlSession.close();
        }
    
        @Test
        public void SelectByBirth() throws ParseException {
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
            Date birth = sdf.parse("1980-10-11");
    
            List<Student> students = mapper.selectByBirth(birth);
            students.forEach(student -> System.out.println(student));
    
            sqlSession.commit();
            sqlSession.close();
        }
    
        @Test
        public void SelectByName(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> students = mapper.selectByName("李四");
            students.forEach(student -> System.out.println(student));
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    
        @Test
        public void SelectById(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> students = mapper.selectById(1L);
    
            students.forEach(student -> System.out.println(student));
    
            sqlSession.commit();
            sqlSession.close();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68

    10.2 Map参数

    这种方式是手动封装Map集合,将每个条件以key和value的形式存放到集合中。然后在使用的时候通过#{map集合的key}来取值

    需求:根据map集合保存学生信息

    • StudentMapper接口:
        int insertStudentByMap(Map<String,Object> map);
    
    • 1
    • StudentMapper.xml
        <insert id="insertStudentByMap" parameterType="map">
            insert into t_student(id,name,age,sex,birth,height) value (null,#{姓名},#{年龄},#{性别},#{生日},#{身高})
        insert>
    
    • 1
    • 2
    • 3
    • 测试
    @Test
        public void InsertStudentByMap(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            Map<String,Object> map = new HashMap<>();
            map.put("姓名","麻瓜");
            map.put("年龄",25);
            map.put("身高",1.82);
            map.put("性别",'男');
            map.put("生日",new Date());
    
            mapper.insertStudentByMap(map);
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述
    在这里插入图片描述

    10.3 实体类参数(POJO参数)

    使用实体类参数这里需要注意的是:#{} 里面写的是属性名字。这个属性名其本质上是:set/get方法名去掉set/get之后的名字

    • StudentMapper.xml
        <insert id="insertStudentByPOJO">
            insert into t_student(id,name,age,sex,birth,height) value (null,#{name},#{age},#{sex},#{birth},#{height})
        insert>
    
    • 1
    • 2
    • 3
    • StudentMapper接口
    /*
         * @description: 保存学生信息,通过实体类参数
         * @param student
         * @version 1.0
        */
        int insertStudentByPOJO(Student student);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 测试
     @Test
        public void InsertStudentByPOJO(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    
            Student student = new Student();
            student.setName("小老板");
            student.setAge(24);
            student.setSex('男');
            student.setBirth(new Date());
            student.setHeight(1.78);
    
            mapper.insertStudentByPOJO(student);
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    在这里插入图片描述
    在这里插入图片描述

    10.4 多参数

    需求:通过name和sex查询

    • StudentMapper.xml
        <select id="selectByNameAndSex" resultType="Student">
            select * from t_student where name = #{name} and sex = #{sex}
        select>
    
    • 1
    • 2
    • 3
    • StudentMapper接口
    
        /*
         * 这是多参数
         * 根据name和sex查询Student信息
         * 如果是多个参数的话,mybatis框架底层是怎么做到的呢?
         *      mybatis框架会自动创建一个Map集合,并且Map集合是以这种方式储存参数的:
         *          map.put("arg0",name);
         *          map.put("arg1",sex);
         *          map.put("arg1",sex);
         *          map.put("param1",name);
         *          map.put("param2",sex);
        */
        List<Student> selectByNameAndSex(String name,Character sex);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 测试
      @Test
        public void selectByNameAndSex(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> students = mapper.selectByNameAndSex("张三", '男');
            students.forEach(student -> System.out.println(student));
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    异常信息描述了:name参数找不到,可用的参数包括[arg1, arg0, param1, param2]
    修改StudentMapper.xml配置文件:尝试使用[arg1, arg0, param1, param2]去参数

    • 修改StudentMapper.xml文件
        <select id="selectByNameAndSex" resultType="Student">
           
                select * from t_student where name = #{arg0} and sex = #{param2}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 再次尝试修改StudentMapper.xml文件
    <select id="selectByNameAndSex" resultType="Student">
      
      
      
      select * from t_student where name = #{arg0} and sex = #{param2}
    select>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述
    通过测试可以看到:

    • arg0 是第一个参数
    • param1是第一个参数
    • arg1 是第二个参数
    • param2是第二个参数

    实现原理:实际上在mybatis底层会创建一个map集合,以arg0/param1为key,以方法上的参数为value,例如以下代码:

    Map<String,Object> map = new HashMap<>();
    map.put("arg0", name);
    map.put("arg1", sex);
    map.put("param1", name);
    map.put("param2", sex);
    
    // 所以可以这样取值:#{arg0} #{arg1} #{param1} #{param2}
    // 其本质就是#{map集合的key}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    注意:使用mybatis3.4.2之前的版本时:要用#{0}和#{1}这种形式。

    10.5 @Param注解(命名参数)

    可以不用arg0 arg1 param1 param2吗?这个map集合的key我们自定义可以吗?当然可以。使用@Param(" 注解的名称 ")注解即可。这样可以增强可读性。

    需求:根据name和age查询

    • StudentMapper接口
        /*
         * Param注解
         *
         * mybatis框架底层的实现原理:
         *    map.put("name",name);
         *    map.put("sex",sex);
         * @param name
         * @param sex
         *
        */
        List<Student> selectByNameAndSex2(@Param("name")String name,@Param("sex") Character sex);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • StudentMapper.xml
        <select id="selectByNameAndSex2" resultType="Student">
            
            select * from t_student where name = #{name} and sex and #{sex}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 测试
    @Test
        public void SelectByNameAndSex2(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
            List<Student> students = mapper.selectByNameAndSex2("张三", '男');
            students.forEach(student -> System.out.println(student));
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    核心:@Param(“这里填写的其实就是map集合的key”)

    10.6 @Param注解源码分析

    做个了解
    在这里插入图片描述

    十一 小黑子的MyBatis查询专题

    模块名:mybatis-007-select
    打包方式:jar
    引入依赖:mysql驱动依赖、mybatis依赖、logback依赖、junit依赖。
    引入配置文件:jdbc.properties、mybatis-config.xml、logback.xml
    创建pojo类:Car
    创建Mapper接口:CarMapper
    创建Mapper接口对应的映射文件:com/powernode/mybatis/mapper/CarMapper.xml
    创建单元测试:CarMapperTest
    拷贝工具类:SqlSessionUtil

    11.1 返回Car

    当查询的结果,有对应的实体类,并且查询结果只有一条时:

    • CarMapper.xml
    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    
        <select id="selectById" resultType="Car">
            select
                   id,
                   car_num as carNum,
                   brand,
                   guide_price as guidePrice,
                   produce_time as produceTime,
                   car_type as carType
            from t_car
            where
                id = #{id}
        select>
    
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • CarMapper接口
    package com.powernode.mybatis.mapper;
    
    import com.powernode.mybatis.pojo.Car;
    
    public interface CarMapper {
    
        /**
         * 根据id主键查询:结果最多只有一条
         * @param id
         * @return
         */
        Car selectById(Long id);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 测试
    package com.powernode.mybatis.test;
    
    import com.powernode.mybatis.mapper.CarMapper;
    import com.powernode.mybatis.pojo.Car;
    import com.powernode.mybatis.utils.SqlSessionUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    public class CarMapperTest {
        @Test
        public void testSelectById(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            Car car = mapper.selectById(1L);
            System.out.println(car);
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    在这里插入图片描述

    当返回记录结果有多条,却用单个实体类接收时:

    • CarMapper接口
    /*
         * @description: 根据品牌进行模糊查询
         * 查询的结果可能有多个,但是采用一个POJO对象来接收的问题
         * @param brand
         * @version 1.0
        */
        Car selectByBrandLike(String brand);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • CarMapper.xml
    <select id="selectByBrandLike" resultType="Car">
            select
                id,
                car_num as carNum,
                brand,
                guide_price as guidePrice,
                produce_time as produceTime,
                car_type as carType
            from t_car
            where
                brand like "%"#{brand}"%"
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 测试
     @Test
        public void testSelectByBrandLike(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    
            //出现异常TooManyResultsException
            //什么意思?你期望的结果是返回一条记录,但是实际的SQL语句在执行的时候,返回的记录条数不是一条,是多条
            Car car = mapper.selectByBrandLike("byd");
            System.out.println(car);
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    在这里插入图片描述

    11.2 返回List< Car >

    一、采用List集合接收多条数据,模糊查询

    • CarMappper接口
    List<Car> selectByBrandLike2(String brand);
    
    • 1
    • CarMapper.xml
      <select id="selectByBrandLike2" resultType="Car">
            select
                id,
                car_num as carNum,
                brand,
                guide_price as guidePrice,
                produce_time as produceTime,
                car_type as carType
            from t_car
            where
                brand like "%"#{brand}"%"
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 测试
    @Test
        public void testSelectByBrandLike2(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            List<Car> cars = mapper.selectByBrandLike2("byd");
            cars.forEach(car -> System.out.println(car));
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述

    二、
    根据id查询Car,id是主键。这个结果一定是一条,不可能有多条数据。所以返回可以用List< Car >集合进行接收。

    • CarMapper.xml
        <select id="selectById2" resultType="Car">
            select
                id,
                car_num as carNum,
                brand,
                guide_price as guidePrice,
                produce_time as produceTime,
                car_type as carType
            from t_car
            where
                id = #{id}
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • CarMapper接口
        /*
         * @description: 根据id查询Car,id是主键。这个结果一定是一条,不可能有多条数据。
         * @param id
         * @version 1.0
        */
        List<Car> selectById2(Long id);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 测试
      @Test
        public void testSelectById2(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            List<Car> cars = mapper.selectById2(2L);
            System.out.println(cars);
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    11.3 返回Map

    当返回的数据,没有合适的实体类对应的话,可以采用Map集合接收。字段名做key,字段值做value。
    查询如果可以保证只有一条数据,则返回一个Map集合即可。
    在这里插入图片描述

    • CarMappper.xml
        
        <select id="selectByIdRetMap" resultType="map">
            select * from t_car where id = #{id}
        select>
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • CarMapper接口
        /*
         * @description: 根据id获取汽车信息。将汽车信息放到Map集合中
         * @param id
         * @version 1.0
        */
        Map<String,Object> selectByIdRetMap(Long id);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 测试
        @Test
        public void testSelectByIdRetMap(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            Map<String, Object> car = mapper.selectByIdRetMap(34L);
            System.out.println(car);
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    11.3.1 返回List< Map >

    查询结果条数大于等于1条数据,则可以返回一个存储Map集合的List集合
    在这里插入图片描述

    resultMap=“map”,这是因为mybatis内置了很多别名。【参见mybatis开发手册】

    • CarMapper.xml
        
        <select id="selectAllRetListMap" resultType="map">
            select * from t_car
        select>
    
    • 1
    • 2
    • 3
    • 4
    • CarMapper接口
     /*
         * 查询所有的Car信息,返回一个存放Map集合的List集合
         * @version 1.0
        */
        List<Map<String,Object>> selectAllRetListMap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 测试
        @Test
        public  void testSelectAllRetListMap(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            List<Map<String, Object>> maps = mapper.selectAllRetListMap();
            maps.forEach(map -> System.out.println(map));
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    当然,如果返回一个Map集合,可以将Map集合放到List集合中吗?当然可以,这里就不再测试了。
    反过来,如果返回的不是一条记录,是多条记录的话,只采用单个Map集合接收,这样同样会出现之前的异常:TooManyResultsException

    11.4 返回Map

    拿Car的id做key,以后取出对应的Map集合时更加方便
    在这里插入图片描述

    • CarMapper接口
        /*
         * 查询所有的Car,返回一个大Map集合
         * Map集合的key是每条记录的主键值
         * map集合的value是每条记录
        */
        @MapKey("id")//将查询结果的id值作为整个大Map集合的key
        Map<Long,Map<String,Object>> selectAllRetMap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 测试
    @Test
        public void testSelectAllRetMap(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            Map<Long, Map<String, Object>> maps = mapper.selectAllRetMap();
            System.out.println(maps);
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • CarMapper.xml
        <select id="selectAllRetMap" resultType="map">
            select * from t_car
        select>
    
    
    • 1
    • 2
    • 3
    • 4

    返回结果一个大Map集合:

    {1={car_num=1001, id=1, guide_price=10, produce_time=2022-10-11, brand=宝马520, car_type=燃油车}, 
    2={car_num=1111, id=2, guide_price=10, produce_time=2020-11-11, brand=byd, car_type=电车}, 
    34={car_num=9991, id=34, guide_price=40, produce_time=2022-11-11, brand=凯迪, car_type=能源车}, 
    3={car_num=1111, id=3, guide_price=10, produce_time=2020-11-11, brand=byd, car_type=电车}, 
    4={car_num=9999, id=4, guide_price=30, produce_time=1999-11-10, brand=magua, car_type=旧能源}, 
    6={car_num=8888, id=6, guide_price=30, produce_time=2000-11-66, brand=法克鱿, car_type=捞车}, 
    7={car_num=8888, id=7, guide_price=30, produce_time=2000-11-66, brand=法克鱿, car_type=捞车}, 
    8={car_num=8888, id=8, guide_price=30, produce_time=2000-11-66, brand=法克鱿, car_type=捞车}, 
    9={car_num=8888, id=9, guide_price=30, produce_time=2000-11-66, brand=法克鱿, car_type=捞车}, 
    10={car_num=8888, id=10, guide_price=30, produce_time=2000-11-66, brand=法克鱿, car_type=捞车}, 
    15={car_num=22222, id=15, guide_price=3, produce_time=2022-10-1, brand=小老板, car_type=新能源}}
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    11.5 resultMap结果映射

    查询结果的列名和java对象的属性名对应不上怎么办?

    1. 第一种方式:as 给列起别名
    2. 第二种方式:使用resultMap进行结果映射
    3. 第三种方式:是否开启驼峰命名自动映射(配置settings)

    使用resultMap进行结果映射:

    • CarMapper接口
        /**
         * 查询所有Car,使用resultMap进行结果映射
         * @return
         */
        List<Car> selectAllByResultMap();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • CarMapper.xml
        
        <resultMap id="carResultMap" type="Car">
            
            
    
            <id property="id" column="id">id>
    
            
            
    
            <result property="carNum" column="car_num" javaType="java.lang.String" jdbcType="VARCHAR"/>
            
            
            <result property="guidePrice" column="guide_price"/>
            <result property="produceTime" column="produce_time"/>
            <result property="carType" column="car_type" javaType="string" jdbcType="VARCHAR"/>
    
    
        resultMap>
    
        
        <select id="selectAllByResultMap" resultMap="carResultMap">
            select * from t_car
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 测试
      @Test
        public void testSelectAllByResultMap(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            List<Car> cars = mapper.selectAllByResultMap();
            cars.forEach(car -> System.out.println(car));
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    11.5.1 开启驼峰命名自动映射

    使用这种方式的前提是:属性名遵循Java的命名规范,数据库表的列名遵循SQL的命名规范。
    Java命名规范:首字母小写,后面每个单词首字母大写,遵循驼峰命名方式。
    SQL命名规范:全部小写,单词之间采用下划线分割。

    比如以下的对应关系:

    实体类中的属性名数据库表的别名
    carNumcar_num
    carTypecar_type
    produceTimeproduce_time
    • 如何启用该功能,在mybatis-config.xml文件中进行配置:
    
    <settings>
      <setting name="mapUnderscoreToCamelCase" value="true"/>
    settings>
    
    • 1
    • 2
    • 3
    • 4
    • CarMapper接口
    /**
    * 查询所有Car,启用驼峰命名自动映射
    * @return
    */
    List<Car> selectAllByMapUnderscoreToCamelCase();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • CarMapper.xml
        <select id="selectAllByMapUnderscoreToCamelCase" resultType="car">
            select * from t_car
        select>
    
    • 1
    • 2
    • 3
    • 测试
    @Test
        public void testSelectAllByMapUnderscoreToCamelCase (){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            List<Car> cars = mapper.selectAllByMapUnderscoreToCamelCase();
            cars.forEach(car -> System.out.println(car));
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    在这里插入图片描述

    11.6返回总记录条数

    需求:查询总记录条数

    • CarMapper.xml
     <select id="selectTotal" resultType="Long">
            select count(*) from t_car
        select>
    
    • 1
    • 2
    • 3
    • CarMapper接口
        /*
         * @description: 获取Car的总记录条数
         * @version 1.0
        */
        Long selectTotal();
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 测试
     @Test
        public void testSelectTotal(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            Long total = mapper.selectTotal();
            System.out.println(total);
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    十二 小黑子的动态SQL

    什么是动态SQL?

    有的业务场景,也需要SQL语句进行动态拼接,例如:

    • 批量删除 在这里插入图片描述

    12.1 if标签

    1. if标签中test属性是必须的。
    2. if标签中test属性的值是false或者true。
    3. 如果test是true,则if标签中的sql语句就会拼接。反之,则不会拼接。
    4. test属性中可以使用的是:
      • 当使用了@Param注解,那么test中要出现的是@Param注解指定的参数名。@Param("brand"),那么这里只能使用brand
      • 当没有使在这里插入代码片@Param注解,那么test中要出现的是: param1 param2 param3 arg0 arg1 arg2. . . .
      • 当使用了POJO,那么test中出现的是POJO类的属性名。
    5. 在mybatis的动态SQL当中,不能使用&&,只能使用and。
    • CarMapper.xml
    
    DOCTYPE mapper
            PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.powernode.mybatis.mapper.CarMapper">
    
        <select id="selectByMultiCondition" resultType="Car">
            select * from t_car
            where
            <if test="brand != null and brand != ''">
                brand like "%"#{brand}"%"
            if>
            <if test="guidePrice != null and guidePrice != ''">
                and guide_price > #{guidePrice}
            if>
            <if test="carType != null and carType != ''">
                and car_type = #{carType}
            if>
        select>
    mapper>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • CarMapper接口
    package com.powernode.mybatis.mapper;
    
    import com.powernode.mybatis.pojo.Car;
    import org.apache.ibatis.annotations.Param;
    
    import java.util.List;
    
    public interface CarMapper {
        /*
         * 多条件查询
         * @param brand
         * @param guidePrice
         * @param carType
         * @version 1.0
        */
        List<Car> selectByMultiCondition(@Param("brand") String brand,@Param("guidePrice") Double guidePrice, @Param("carType") String carType);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 测试
    package com.powernode.mybatis.test;
    
    import com.powernode.mybatis.mapper.CarMapper;
    import com.powernode.mybatis.pojo.Car;
    import com.powernode.mybatis.utils.SqlSessionUtil;
    import org.apache.ibatis.session.SqlSession;
    import org.junit.Test;
    
    import java.util.List;
    
    public class CarMapperTest {
        @Test
        public void testSelectByMultiCondition(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    
            //假设三个条件都不是空
            List<Car> cars = mapper.selectByMultiCondition("byd", 2.0, "电车");
            cars.forEach(car -> System.out.println(car));
    
            sqlSession.commit();
            sqlSession.close();
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    在这里插入图片描述

    12.2 where标签

    where标签的作用:让where子句更加动态智能。

    所有条件都为空时,where标签保证不会生成where子句。
    自动去除某些条件前面多余的andor。后面的无法去除
    继续使用if标签中的需求。

    • CarMapper接口
        /*
         * @description: where标签,让where子句更加的智能
         * @version 1.0
        */
        List<Car> selectByMultiConditionWithWhere(@Param("brand") String brand,@Param("guidePrice") Double guidePrice, @Param("carType") String carType);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • CarMapper接口
      <select id="selectByMultiConditionWithWhere" resultType="Car">
            select * from t_car
            
            <where>
                <if test="brand != null and brand != ''">
                    brand like "%"#{brand}"%"
                if>
                <if test="guidePrice != null and guidePrice != ''">
                    and guide_price > #{guidePrice}
                if>
                <if test="carType != null and carType != ''">
                    and car_type = #{carType}
                if>
            where>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 测试
    
        @Test
        public void selectByMultiConditionWithWhere(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    
            //假设三个条件都不是空
    //        List cars = mapper.selectByMultiConditionWithWhere("byd", 2.0, "电车");
    
            //假设三个条件都是空,where标签可以自动判断是否符合条件
    //        List cars = mapper.selectByMultiConditionWithWhere("", null, "");
    
            //假设一个条件为空,where标签也会自动判断消去and
            List<Car> cars = mapper.selectByMultiConditionWithWhere("", 2.0, "电车");
            cars.forEach(car -> System.out.println(car));
    
            //但是后面两个条件是空时,后面有and,where标签就无法去除
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    12.3 trim标签

    trim标签的属性:

    • prefix:再trim标签中的语句前添加内容
    • suffix:再trim标签中的语句后添加内容
    • prefixOverrides:前缀覆盖掉(去掉)
    • suffixOverrides:后缀覆盖掉(去掉)
        /*
         * @description: 使用trim标签
         * @version 1.0
         */
        List<Car> selectByMultiConditionWithTrim(@Param("brand") String brand,@Param("guidePrice") Double guidePrice, @Param("carType") String carType);
    
    • 1
    • 2
    • 3
    • 4
    • 5
     <select id="selectByMultiConditionWithTrim" resultType="Car">
            
            
            select * from t_car
            <trim prefix="where" suffixOverrides="and|or">
                <if test="brand != null and brand != ''">
                    brand like "%"#{brand}"%" and
                if>
                <if test="guidePrice != null and guidePrice != ''">
                     guide_price > #{guidePrice} and
                if>
                <if test="carType != null and carType != ''">
                     car_type = #{carType}
                if>
            trim>
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
       @Test
        public void testSelectByMultiConditionWithTrim(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            List<Car> cars = mapper.selectByMultiConditionWithTrim("", null, "");
            cars.forEach(car -> System.out.println(car));
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    12.4 set标签

    主要使用在update语句当中,用来生成set关键字,同时去掉最后多余的“,”

    比如我们只更新提交的不为空的字段,如果提交的数据是空或者"",那么这个字段我们将不更新。

        /*
         * @description: 使用set标签
         * @version 1.0
        */
        int updateBySet(Car car);
    
    • 1
    • 2
    • 3
    • 4
    • 5
        <update id="updateBySet">
            update t_car
            <set>
                <if test="carNum != null and carNum != '' ">car_num = #{carNum},if>
                <if test="brand != null and brand != '' ">brand = #{brand},if>
                <if test="guidePrice != null and guidePrice != '' ">guide_price = #{guidePrice},if>
                <if test="produceTime != null and produceTime != '' ">produce_time = #{produceTime},if>
                <if test="carType != null and carType != '' ">car_type = #{carType}if>
            set>
            where
                    id = #{id}
        update>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
        @Test
        public void testUpdateBySet(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
            Car car = new Car(34L, null, "麻瓜霸道", null, null, null);
            mapper.updateBySet(car);
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在这里插入图片描述

    12.5 chose when otherwise标签

    这三个标签是在一起使用的:

    语法格式:

    <choose>
      <when>when>
      <when>when>
      <when>when>
      <otherwise>otherwise>
    choose>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    等同于:

    if(){
        
    }else if(){
        
    }else if(){
        
    }else if(){
        
    }else{
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    只有一个分支会被选择!!!!

    案例需求:先根据品牌查询,如果没有提供品牌,再根据指导价查询,如果没有提供指导架构,就根据生产日期查询

        /**
         * 使用choose when otherwise标签查询
         * @param brand
         * @param guidePrice
         * @param carType
         * @return
         */
        List<Car> selectWithChoose(@Param("brand") String brand, @Param("guidePrice") Double guidePrice, @Param("carType") String carType);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
     <select id="selectWithChoose" resultType="Car">
            select * from t_car
            <where>
                <choose>
                    <when test="brand != null and brand != ''">
                        brand like "%"#{brand}"%"
                    when>
                    <when test="guidePrice != null and guidePrice != ''">
                        guide_price > #{guidePrice}
                    when>
                    <otherwise>
                        car_type = #{carType}
                    otherwise>
                choose>
            where>
        select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
     @Test
        public void testSelectWithChoose(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    
            //三个条件都不为空
    //        List cars = mapper.selectWithChoose("麻瓜霸道", 1.0, "新能源");
            //第一个条件是空
            // List cars = mapper.selectWithChoose(null, 1.0, "新能源");
            //前两个条件是空
            // List cars = mapper.selectWithChoose(null, null, "新能源");
            //全都是空
             List<Car> cars = mapper.selectWithChoose(null, null, null);
            cars.forEach(car -> System.out.println(car));
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    12.6 foreach标签

    循环数组或集合,动态生成sql,比如这样的SQL:

    • 批量删除
    delete from t_car where id in(1,2,3);
    delete from t_car where id = 1 or id = 2 or id = 3;
    
    • 1
    • 2
    • 批量增加
    insert into t_car values
      (null,'1001','凯美瑞',35.0,'2010-10-11','燃油车'),
      (null,'1002','比亚迪唐',31.0,'2020-11-11','新能源'),
      (null,'1003','比亚迪宋',32.0,'2020-10-11','新能源')
    
    • 1
    • 2
    • 3
    • 4

    12.6.1 批量删除

    1. in来删除

    foreach标签属性:

    • collection:集合或数组
    • item:集合或数组中的元素
    • separator:循环之间的分隔符
    • open:foreach标签中所有内容的开始
    • close:foreach标签中所有内容的结束
        /**
         * 通过foreach完成批量删除
         * @param ids
         * @return
         */
        int deleteBatchByForeach(@Param("ids") Long[] ids);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
        <delete id="deleteBatchByForeach">
            delete from t_car where id in
            <foreach collection="ids" item="id" separator="," open="(" close=")">
                #{id}
            foreach>
        delete>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
        @Test
        public void testDeleteBatchByForeach(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    
            Long[] ids = {8L,9L,10L};
            mapper.deleteBatchByForeach(ids);
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    在这里插入图片描述

    1. 用or来删除
        <delete id="deleteById2" >
            delete from t_car where
            <foreach collection="ids" item="id" separator="or">
               id = #{id}
            foreach>
        delete>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
        /**
         * 通过id批量删除,使用or关键字
         * @param ids
         * @return
         */
        int deleteById2(@Param("ids") Long[] ids);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
      @Test
        public void testDeleteById2(){
            SqlSession sqlSession = SqlSessionUtil.openSession();
            CarMapper mapper = sqlSession.getMapper(CarMapper.class);
    
            Long[] ids = {35L,36L,37L};
            int count = mapper.deleteById2(ids);
            System.out.println(count);
    
            sqlSession.commit();
            sqlSession.close();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    12.6.2 批量插入

        <insert id="insertBatch">
            insert into t_car values
            <foreach collection="cars" item="car" separator=",">
                (null,#{car.carNum},#{car.brand},#{car.guidePrice},#{car.produceTime},#{car.carType})
            foreach>
        insert>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
        /**
         * 通过foreach批量插入,一次插入多条car信息
         * @param cars
         * @return
         */
        int insertBatch(@Param("cars") List<Car> cars);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    @Test
        public void testInsertBatchByForeach(){
            CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
            Car car1 = new Car(null, "2001", "兰博基尼", 100.0, "1998-10-11", "燃油车");
            Car car2 = new Car(null, "2001", "兰博基尼", 100.0, "1998-10-11", "燃油车");
            Car car3 = new Car(null, "2001", "兰博基尼", 100.0, "1998-10-11", "燃油车");
            List<Car> cars = Arrays.asList(car1, car2, car3);
            int count = mapper.insertBatch(cars);
            System.out.println("插入了几条记录" + count);
            SqlSessionUtil.openSession().commit();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    在这里插入图片描述
    在这里插入图片描述

    12.7 sql标签和include标签

    sql标签用来声明sql片段

    include标签用来将声明的sql片段包含到某个sql语句当中

    作用:代码复用。易维护。

    
    <sql id="carCols">
    	id,
    	car_num as carNum,
    	brand,
    	guide_price as guidePrice,
    	produce_time as produceTime,
    	car_type as carType
    sql>
    
    <select id="selectAllRetMap" resultType="map">
      select 
      	
      	<include refid="carCols"/> 
      	from t_car
    select>
    
    <select id="selectAllRetListMap" resultType="map">
      select 
      <include refid="carCols"/> 
      carType from t_car
    select>
    
    <select id="selectByIdRetMap" resultType="map">
      select 
      <include refid="carCols"/> 
      from t_car 
      where id = #{id}
    select>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
  • 相关阅读:
    【重温基础算法】内部排序之计数排序法
    HCNP Routing&Switching之组播技术-组播路由协议PIM
    机器人革命:你一定没见过这些全新的机器人技术!
    实验二 分支结构程序设计(Python)
    SaaS架构:多租户系统架构设计
    C/C++数字与字符串互相转换
    mac添加Chrome插件的方法
    Java 筆記
    露点温度介绍
    【博学谷学习记录】超强总结,用心分享|架构师-Reactor线程模型
  • 原文地址:https://blog.csdn.net/VanWot/article/details/133715054