CarMapper.xml,放在类的根路径下:注意namespace必须和接口名一致。id必须和接口中方法名一致。
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.sunsplanter.mybatis.mapper.CarMapper">
<select id="selectByCarType" resultType="com.sunsplanter.mybatis.pojo.Car">
select
id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType
from
t_car
where
car_type = #{carType}
</select>
</mapper>
public class CarMapperTest {
@Test
public void testSelectByCarType(){
CarMapper mapper = (CarMapper) SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = mapper.selectByCarType("燃油车");
cars.forEach(car -> System.out.println(car));
}
通过执行可以清楚的看到,sql语句中是带有 ? 的,这个 ? 就是大家在JDBC中所学的占位符,专门用来接收值的。
把“燃油车”以String类型的值,传递给 ? 。(即带着Java类型传入,形成carType = ‘燃油车’)
但是,若mapper文件中改为${}:
<mapper namespace="com.sunsplanter.mybatis.mapper.CarMapper">
<select id="selectByCarType" resultType="com.sunsplanter.mybatis.pojo.Car">
select
id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType
from
t_car
where
<!--car_type = #{carType}-->
car_type = ${carType}
</select>
</mapper>
则会报错,根本原因是看生成的SQL语句就知道了:$不生成任何东西,因此传入的东西也不带有Java类型, 系统当然也不会帮助生成单引号,因此此时形成carType = 燃油车,根本就不符合语法
解决办法:
car_type = '${carType}'
需求:查询所有汽车的条目,并通过向sql语句中注入asc或desc关键字,来完成数据的升序或降序排列。
<select id="selectAll" resultType="com.sunsplanter.mybatis.pojo.Car">
select
id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType
from
t_car
order by carNum #{key}
</select>
测试程序:
@Test
public void testSelectAll(){
CarMapper mapper = (CarMapper) SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = mapper.selectAll("desc");
cars.forEach(car -> System.out.println(car));
}
如上所述,带着Java类型传入,形成语句 order by carNum ‘desc’ , 那么当然错误,关键不能用单引号括起来.
改为:
order by carNum ${key}
此时, 传入的desc不带有Java类型,不自动生成单引号,形成order by carNum desc ,正确
需求:批量删除id为1,2,3的条目
从所需SQL语句倒推:
delete from t_user where id in(1, 2, 3);
因此mapper中应为:
<delete id="deleteBatch">
delete from t_car where id in(${ids})
</delete>
测试程序为:
@Test
public void testDeleteBatch(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
int count = mapper.deleteBatch("1,2,3");
}
用美元符号${},将1,2,3直接放进去,而非生成单引号(where id in(‘1,2,3’))
需求:查询奔驰系列的汽车。【只要品牌brand中含有奔驰两个字的都查询出来。】
从所需SQL语句倒推:
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 '%奔驰%'
则mapper.xml为:
brand like '%${brand}%'
测试程序为:
List<Car> cars = mapper.selectLikeByBrand("奔驰");
即不带Java类型,直接把奔驰两字替代${brand}.
业务背景:实际开发中,有的表数据量非常庞大,可能会采用分表方式进行存储,比如每天生成一张表,表的名字与日期挂钩,例如:2022年8月1日生成的表:t_user20220108。2000年1月1日生成的表:t_user20000101。此时前端在进行查询的时候会提交一个具体的日期,比如前端提交的日期为:2000年1月1日,那么后端就会根据这个日期动态拼接表名为:t_user20000101。有了这个表名之后,将表名拼接到sql语句当中,返回查询结果。
需求:向SQL语句中注入表名,完成查询特定表
<select id="selectAllByTableName" resultType="car">
select
id,car_num as carNum,brand,guide_price as guidePrice,produce_time as produceTime,car_type as carType
from
${tableName}
</select>
对应接口CarMapper中有方法:
List<Car> selectAllByTableName(String tableName)
测试程序为:
@Test
public void testSelectAllByTableName(){
CarMapper mapper = SqlSessionUtil.openSession().getMapper(CarMapper.class);
List<Car> cars = mapper.selectAllByTableName("t_car");
cars.forEach(car -> System.out.println(car));
}
表名也是关键字,不应被单引号括起,因此应用美元符号${}, 形成from t_car