实际开发中应用细节#{}和${}的区别‘#{}’先编译sql语句再给占位符传值底层是PreparedStatement实现可以防止sql注入比较常用。‘#{}’传来的字符串类型的数据会自带单引号比如user_name#{name} 会编译为 user_name‘张三’${}先进行sql语句拼接再编译sql语句底层是Statement实现。存在sql注入现象。只有在需要进行sql关键字拼接的情况下才会用到。${}传来的字符串类型的数据不带单引号比如user_name#{name} 会编译为 user_name张三 。这样会报语法错误。优先使用#{}那么什么时候使用${}呢在使用sql拼接的时候会用到比如一个数据的查询结果是升序还是降序有前端传来的参数决定。因此使用${}更合适order by age${orderType} 会编译为 order by ageasc。如果使用#{}处理的话会编译为order by age‘asc’ 会报语法错误当拼接表名时也会用到。一些数据会分表存储。比如日志表因为日志数据会非常大可以每天生成一个日志表每张表以当天的日期作为名称例如log_2022-02-11、log_2022-02-12、log_2022-02-13.这样查某一天的日志时可以将log_和日期进行拼接 然后查询此时就要用到${}批量删除批量删除时参数一般为字符串比如传来的参数id值为‘1234’。直接用where id in #{id}会失效。这里应该使用$() 。sql会编译为where id in 1234 结果执行成功。模糊查询方案一使用sql语句拼接 where name like %${name}%方案二使用concat函数 where name like concat(%,#{name},%) 此时会编译为 where name like concat(%,涨三,%) 执行成功。方案三where name like %#{name}%别名机制当XxxMapper.xml中resultType的值太长也就是返回值的全限定类名太长可以使用别名机制。先在mybatis-config.xml中配置如下!-- 起别名typeAliases标签要放在properties、settings 标签后面-- typeAliases !-- type:指定给哪个类型起别名 alias:指定别名。别名不区分大小写 然后在CarMapper.xml文件中就可以直接使用别名car来代替全类名com.ali.pojo.Car了 -- typeAlias typecom.ali.pojo.Car aliascar/ /typeAliases这里的alias属性其实可以省略。当alias省略时别名就是类的简名比如typeAlias typecom.ali.pojo.Car/ 的别名就是car、CAR等不区分大小写。 还有更加方便的一种方式可以指定包名mybatis会自动给这个包下的所i有类起别名别名就是类名typeAliases package namecom.ali.pojo/ /typeAliases在CarMapper.xml中就可以使用别名了select idselectCarById resultTypecar 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注意这里的别名不区分大小写。即使写成resultTypeCar 也会执行成功mapper的配置mappers !-- 执行xxxMapper.xml文件中的SQL语句-- !-- resource属性自动从类的路径下加载xxxMapper.xml文件 url属性直接从文件系统绝对路径加载xxxMapper.xml文件,不推荐移植性太差。 class属性指定一个全限定接口名mybaits会去这个接口的同级目录下查找对应Mapepr.xml文件 比如以下配置Mybatis会去com.ali.mapper包下查找CarMapper.xml文件。 -- mapper classcom.ali.mapper.CarMapper/ mapper resourceCarMapper.xml/ !--package:表示从指定的包下查找所有的xxxMapper.xml文件并且自动加载它们。 前提必须把xml文件和接口放在统计目录下。并且名字一致。 实际开发中 使用这种方式-- package namecom.ali.mapper/ /mappers插入数据时获取自动生成的主键!-- useGeneratedKeystrue 表示使用JDBC的getGeneratedKeys方法获取数据库自动生成的主键值 keyPropertyid表示将获取到的主键值封装到Car对象的id属性中。-- insert idinsertCarGetId useGeneratedKeystrue keyPropertyid INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType}) /insert这样设置后在新增时传入的car对象在sql执行完后主键的值可以从car.getId()方法中获得。MyBatis参数处理简单类型参数byte、int、short、long、char、float、double、String、Date及其对应的包装类都适用简单类型参数。下面以Long类型为例!-- 对应的接口方法 Car selectCarById(Long id); parameterType属性指定传入参数的类型。在这个例子中传入参数是一个Long类型的id。 mybatis框架自带类型推断机制所以大部分情况下parameterType属性可以省略不写 -- select idselectCarById resultTypecar parameterTypejava.lang.Long 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} /selectMap参数!-- 对应的接口方法 int insertCar(MapString,Object map); 参数类型时map集合。 -- insert idinsertCar parameterTypemap INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType}) /insert实体类参数!--对应的接口方法 int insertCarByPojo(Car car); 参数类型是Pojo类。-- insert idinsertCarByPojo INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType}) /insert多参数!--对应的接口方法 ListCar selectCarByNameAndCarType(String name,String carType); 这种多参数的情况mybatis框架会将多个参数封装成一个map集合并且map会这样设置 map.put(arg0,第一个参数值); map.put(arg1,第二个参数值); map.put(param1,第一个参数值); map.put(param2,第二个参数值); 所以#{arg0} 和#{param1}都可以获取到第一个参数值#{arg1}和#{param2}都可以获取到第二个参数值。 -- select idselectCarByNameAndCarType resultTypecar parameterTypejava.lang.Long SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType FROM t_car WHERE brand #{arg0} and car_type #{arg1} /selectParam注解!--对应的接口方法 ListCar selectCarByNameAndCarType2(Param(name) String name,Param(carType) String carType); Param注解会将底层封装的map中arg0、arg1替换成我们指定的key值name和carType。 param1、param2不会被替换可以继续使用 -- select idselectCarByNameAndCarType2 resultTypecar parameterTypejava.lang.Long SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType FROM t_car WHERE brand #{name} and car_type #{carType} /selectMyBatis查询语句当sql返回多条记录时不能使用单个pojo对象接收不然会报错。单条查询时用List接收是没有任何问题的。返回Map当返回的数据没有合适的实体类对应的话可以采用Map接收。key是字段名value是字段值。当返回多条数据时使用List 接收。!-- 对应的接口方法 MapString,Object selectCarByIdRetMap(Long id); resultTypemap表示将查询结果封装成一个map集合map的key是列名value是列值。 如果需要查询多条记录并封装成map集合可以使用resultTypelist来封装成一个list集合list集合中的每个元素都是一个map集合。 -- select idselectCarByIdRetMap resultTypemap 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返回MapString,Map以每条记录的主键作为key一条记录作为value!-- 接口对应的方法 MapKey(id) // 这个注解表示map的key是id列的值value是整个记录封装成的map集合。 ListMapLong,MapString,Object selectAllCarRetMap(); -- select idselectAllCarRetMap resultTypemap SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType FROM t_car /selectresultMap结果映射查询结果的列名和Java对象的属性名对应不上怎么办方案一as 起别名方案二使用resultMap进行结果映射方案三开启驼峰命名自动映射!--定义一个结果映射在结果映射中指定数据库表的字段和Java对象的属性之间的映射关系。 id属性是结果映射的唯一标识将来要用在select标签中type属性是结果映射对应的Java类型。-- resultMap idcarResultMap typeCar !--建议配上主键因为主键在结果映射中有特殊的意义 主键会被mybatis框架缓存起来如果查询结果中有重复的主键值mybatis框架会将它们封装成同一个Java对象。-- id propertyid columnid/id !--property指定Java对象的属性column指定数据库表的字段。 当数据库表的字段名和Java对象的属性名一致时可以不配置-- result propertycarNum columncar_num/result result propertyguidePrice columnguide_price/result result propertyproduceTime columnproduce_time/result result propertycarType columncar_type/result /resultMap !--resultMap表示指定使用哪个结果映射resultMap的值时resultMap标签的id-- select idselectAllCarResultMap resultMapcarResultMap SELECT * FROM t_car /select开启驼峰命名自动映射前提时Java的属性名和数据库表的字段名必须符合命名规范。可以将car_type对应为carType在mybatis-config.xml文件中进行如下配置即可开启该功能默认值是falsesettings setting namemapUnderscoreToCamelCase valuetrue/ /settings返回总记录条数!-- 对应的接口方法 long selectTotalCount(); -- select idselectTotalCount resultTypelong SELECT count(*) FROM t_car /select
MyBatis-参数处理与查询结果映射
发布时间:2026/5/31 6:02:54
实际开发中应用细节#{}和${}的区别‘#{}’先编译sql语句再给占位符传值底层是PreparedStatement实现可以防止sql注入比较常用。‘#{}’传来的字符串类型的数据会自带单引号比如user_name#{name} 会编译为 user_name‘张三’${}先进行sql语句拼接再编译sql语句底层是Statement实现。存在sql注入现象。只有在需要进行sql关键字拼接的情况下才会用到。${}传来的字符串类型的数据不带单引号比如user_name#{name} 会编译为 user_name张三 。这样会报语法错误。优先使用#{}那么什么时候使用${}呢在使用sql拼接的时候会用到比如一个数据的查询结果是升序还是降序有前端传来的参数决定。因此使用${}更合适order by age${orderType} 会编译为 order by ageasc。如果使用#{}处理的话会编译为order by age‘asc’ 会报语法错误当拼接表名时也会用到。一些数据会分表存储。比如日志表因为日志数据会非常大可以每天生成一个日志表每张表以当天的日期作为名称例如log_2022-02-11、log_2022-02-12、log_2022-02-13.这样查某一天的日志时可以将log_和日期进行拼接 然后查询此时就要用到${}批量删除批量删除时参数一般为字符串比如传来的参数id值为‘1234’。直接用where id in #{id}会失效。这里应该使用$() 。sql会编译为where id in 1234 结果执行成功。模糊查询方案一使用sql语句拼接 where name like %${name}%方案二使用concat函数 where name like concat(%,#{name},%) 此时会编译为 where name like concat(%,涨三,%) 执行成功。方案三where name like %#{name}%别名机制当XxxMapper.xml中resultType的值太长也就是返回值的全限定类名太长可以使用别名机制。先在mybatis-config.xml中配置如下!-- 起别名typeAliases标签要放在properties、settings 标签后面-- typeAliases !-- type:指定给哪个类型起别名 alias:指定别名。别名不区分大小写 然后在CarMapper.xml文件中就可以直接使用别名car来代替全类名com.ali.pojo.Car了 -- typeAlias typecom.ali.pojo.Car aliascar/ /typeAliases这里的alias属性其实可以省略。当alias省略时别名就是类的简名比如typeAlias typecom.ali.pojo.Car/ 的别名就是car、CAR等不区分大小写。 还有更加方便的一种方式可以指定包名mybatis会自动给这个包下的所i有类起别名别名就是类名typeAliases package namecom.ali.pojo/ /typeAliases在CarMapper.xml中就可以使用别名了select idselectCarById resultTypecar 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注意这里的别名不区分大小写。即使写成resultTypeCar 也会执行成功mapper的配置mappers !-- 执行xxxMapper.xml文件中的SQL语句-- !-- resource属性自动从类的路径下加载xxxMapper.xml文件 url属性直接从文件系统绝对路径加载xxxMapper.xml文件,不推荐移植性太差。 class属性指定一个全限定接口名mybaits会去这个接口的同级目录下查找对应Mapepr.xml文件 比如以下配置Mybatis会去com.ali.mapper包下查找CarMapper.xml文件。 -- mapper classcom.ali.mapper.CarMapper/ mapper resourceCarMapper.xml/ !--package:表示从指定的包下查找所有的xxxMapper.xml文件并且自动加载它们。 前提必须把xml文件和接口放在统计目录下。并且名字一致。 实际开发中 使用这种方式-- package namecom.ali.mapper/ /mappers插入数据时获取自动生成的主键!-- useGeneratedKeystrue 表示使用JDBC的getGeneratedKeys方法获取数据库自动生成的主键值 keyPropertyid表示将获取到的主键值封装到Car对象的id属性中。-- insert idinsertCarGetId useGeneratedKeystrue keyPropertyid INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType}) /insert这样设置后在新增时传入的car对象在sql执行完后主键的值可以从car.getId()方法中获得。MyBatis参数处理简单类型参数byte、int、short、long、char、float、double、String、Date及其对应的包装类都适用简单类型参数。下面以Long类型为例!-- 对应的接口方法 Car selectCarById(Long id); parameterType属性指定传入参数的类型。在这个例子中传入参数是一个Long类型的id。 mybatis框架自带类型推断机制所以大部分情况下parameterType属性可以省略不写 -- select idselectCarById resultTypecar parameterTypejava.lang.Long 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} /selectMap参数!-- 对应的接口方法 int insertCar(MapString,Object map); 参数类型时map集合。 -- insert idinsertCar parameterTypemap INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType}) /insert实体类参数!--对应的接口方法 int insertCarByPojo(Car car); 参数类型是Pojo类。-- insert idinsertCarByPojo INSERT INTO t_car (id, car_num, brand,guide_price,produce_time,car_type) VALUES (null, #{carNum}, #{brand},#{guidePrice},#{produceTime},#{carType}) /insert多参数!--对应的接口方法 ListCar selectCarByNameAndCarType(String name,String carType); 这种多参数的情况mybatis框架会将多个参数封装成一个map集合并且map会这样设置 map.put(arg0,第一个参数值); map.put(arg1,第二个参数值); map.put(param1,第一个参数值); map.put(param2,第二个参数值); 所以#{arg0} 和#{param1}都可以获取到第一个参数值#{arg1}和#{param2}都可以获取到第二个参数值。 -- select idselectCarByNameAndCarType resultTypecar parameterTypejava.lang.Long SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType FROM t_car WHERE brand #{arg0} and car_type #{arg1} /selectParam注解!--对应的接口方法 ListCar selectCarByNameAndCarType2(Param(name) String name,Param(carType) String carType); Param注解会将底层封装的map中arg0、arg1替换成我们指定的key值name和carType。 param1、param2不会被替换可以继续使用 -- select idselectCarByNameAndCarType2 resultTypecar parameterTypejava.lang.Long SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType FROM t_car WHERE brand #{name} and car_type #{carType} /selectMyBatis查询语句当sql返回多条记录时不能使用单个pojo对象接收不然会报错。单条查询时用List接收是没有任何问题的。返回Map当返回的数据没有合适的实体类对应的话可以采用Map接收。key是字段名value是字段值。当返回多条数据时使用List 接收。!-- 对应的接口方法 MapString,Object selectCarByIdRetMap(Long id); resultTypemap表示将查询结果封装成一个map集合map的key是列名value是列值。 如果需要查询多条记录并封装成map集合可以使用resultTypelist来封装成一个list集合list集合中的每个元素都是一个map集合。 -- select idselectCarByIdRetMap resultTypemap 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返回MapString,Map以每条记录的主键作为key一条记录作为value!-- 接口对应的方法 MapKey(id) // 这个注解表示map的key是id列的值value是整个记录封装成的map集合。 ListMapLong,MapString,Object selectAllCarRetMap(); -- select idselectAllCarRetMap resultTypemap SELECT id, car_num AS carNum, brand, guide_price AS guidePrice, produce_time AS produceTime, car_type AS carType FROM t_car /selectresultMap结果映射查询结果的列名和Java对象的属性名对应不上怎么办方案一as 起别名方案二使用resultMap进行结果映射方案三开启驼峰命名自动映射!--定义一个结果映射在结果映射中指定数据库表的字段和Java对象的属性之间的映射关系。 id属性是结果映射的唯一标识将来要用在select标签中type属性是结果映射对应的Java类型。-- resultMap idcarResultMap typeCar !--建议配上主键因为主键在结果映射中有特殊的意义 主键会被mybatis框架缓存起来如果查询结果中有重复的主键值mybatis框架会将它们封装成同一个Java对象。-- id propertyid columnid/id !--property指定Java对象的属性column指定数据库表的字段。 当数据库表的字段名和Java对象的属性名一致时可以不配置-- result propertycarNum columncar_num/result result propertyguidePrice columnguide_price/result result propertyproduceTime columnproduce_time/result result propertycarType columncar_type/result /resultMap !--resultMap表示指定使用哪个结果映射resultMap的值时resultMap标签的id-- select idselectAllCarResultMap resultMapcarResultMap SELECT * FROM t_car /select开启驼峰命名自动映射前提时Java的属性名和数据库表的字段名必须符合命名规范。可以将car_type对应为carType在mybatis-config.xml文件中进行如下配置即可开启该功能默认值是falsesettings setting namemapUnderscoreToCamelCase valuetrue/ /settings返回总记录条数!-- 对应的接口方法 long selectTotalCount(); -- select idselectTotalCount resultTypelong SELECT count(*) FROM t_car /select