1. 编写Mapper接口
/**
* 查看详情,通过id查询
*/
Brand selectById(int id);
2. 编写sql语句,sql映射文件
<select id="selectById" resultMap="brandResultMap">
select * from tb_brand where id=#{id};
</select>
3. 执行方法 测试
//4.执行方法
Brand brand = mapper.selectById(id);
System.out.println(brand);
传递的参数id有两种参数占位符。
1.#{}:会将其替换为?,为了防止sql注入
Preparing: select * from tb_brand where id=?;
2.${}:拼sql。会存在sql注入问题
Preparing: select * from tb_brand where id=1;
*参数类型:parameterType:可以省略
*特殊字符处理:(比如小于号,小于号在xml中是注释符号所以sql语句写<会报错)
1.转义字符
<select id="selectById" resultMap="brandResultMap">
select * from tb_brand where id < #{id};
</select>
2.CDATA区
<select id="selectById" resultMap="brandResultMap">
select * from tb_brand where id <![CDATA[
<
]]> #{id};
</select>
- 如果我们想多条件查询那么就是要传递散装参数,需要在接口的方法中添加@Param("sql参数占位符")
List<Brand> selectByCondition(@Param("status")int status, @Param("companyName")String companyName, @Param("brandName")String brandName);
那么我们在sql映射配置文件中就需要用#{"sql参数占位符"}来接收参数了。
<!-- 条件查询-->
<select id="selectByCondition" resultMap="brandResultMap">
select * from tb_brand
where status=#{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
下面进行测试用例的编写
@Test
public void testSelectByCondition() throws IOException {
//接收参数
int status=1;
String companyName="华为";
String brandName="华为";
//因为要进行模糊查询
companyName="%"+companyName+"%";
brandName="%"+brandName+"%";
//1.获取sqlSessionFactory对象
String resources ="mybatis-config.xml";
InputStream resourceAsStream = Resources.getResourceAsStream(resources);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//2.获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.获取mapper接口的处理对象
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4.执行方法
List<Brand> brands = mapper.selectByCondition(status, companyName, brandName);
System.out.println(brands);
//5.释放资源
sqlSession.close();
}
- 当我们传递对象参数时,我们的sql映射配置文件可以像散装参数那样不用变,只要在测试用例中给类设置参数就行了。
mapper接口
List<Brand> selectByCondition(Brand brand);
sql映射配置文件:
<!-- 条件查询-->
<select id="selectByCondition" resultMap="brandResultMap">
select * from tb_brand
where status=#{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
测试用例:
//封装对象
Brand brand=new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
List<Brand> brands = mapper.selectByCondition(brand);
System.out.println(brands);
完整代码:
@Test
public void testSelectByCondition() throws IOException {
//接收参数
int status=1;
String companyName="华为";
String brandName="华为";
//因为要进行模糊查询
companyName="%"+companyName+"%";
brandName="%"+brandName+"%";
//封装对象
Brand brand=new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
//1.获取sqlSessionFactory对象
String resources ="mybatis-config.xml";
InputStream resourceAsStream = Resources.getResourceAsStream(resources);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
//2.获取SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//3.获取mapper接口的处理对象
BrandMapper mapper = sqlSession.getMapper(BrandMapper.class);
//4.执行方法
// List<Brand> brands = mapper.selectByCondition(status, companyName, brandName);
List<Brand> brands = mapper.selectByCondition(brand);
System.out.println(brands);
//5.释放资源
sqlSession.close();
}
- map集合参数
mapper接口:
List<Brand> selectByCondition(Map map);
sql映射文件不变
测试用例:
首先要有个map集合,map集合的键要和sql映射配置文件的值相对应
Map map = new HashMap();
map.put("status",status);
map.put("companyName",companyName);
map.put("brandName",brandName);
但是这个查询是由bug的。比如:
如果用户只输入一个条件时,那么sql语句就会出现null的情况就会报错。
select * from tb_brand where status=? and company_name like ? and brand_name like ?
当用户输入的条件不确定时,我们让sql语句动态随着用户的输入而变化时,这样就不会报错了。
多条件查询
mybatis对动态有很大的支持,比如说if:
在sql语句中加入if标签其实就是if判断,里面的test属性就是if判断语句
<!-- 动态条件查询-->
<select id="selectByCondition" resultMap="brandResultMap">
select * from tb_brand
where
<if test="status!=null">
status=#{status}
</if>
<if test="companyName!=null and companyName!=''">
and company_name like #{companyName}
</if>
<if test="brandName!=null and brandName!=''">
and brand_name like #{brandName}
</if>
</select>
但是呢,这样还是有一些问题的?就像下面这样如果我没有status前面会多出一个and不满足语法,解决方案呢有两个,第一个是恒等式;
<!--
动态条件查询
*if: 条件判断
*test:逻辑表达式
*问题:
*1.恒等式
*2.<where> 替换 where关键字
-->
- 恒等式
select * from tb_brand
where 1=1
<if test="status!=null">
status=#{status}
</if>
<if test="companyName!=null and companyName!=''">
and company_name like #{companyName}
</if>
<if test="brandName!=null and brandName!=''">
and brand_name like #{brandName}
</if>
2. where
~~~xml
select * from tb_brand
/*where 1=1*/
<where>
<if test="status!=null">
status=#{status}
</if>
<if test="companyName!=null and companyName!=''">
and company_name like #{companyName}
</if>
<if test="brandName!=null and brandName!=''">
and brand_name like #{brandName}
</if>
</where>
这里where标签会自动把and去掉,是不是很爽捏。
下面看一下单条件的查询
因为要传的参数不确定,所以传个类的参数。
List<Brand> selectByConditionSingle(Brand brand);
<select id="selectByConditionSingle" resultMap="brandResultMap">
select *
from tb_brand
where
<choose>
<when test="status!=null">/*相当于case*/
status=#{status}
</when>
<when test="companyName!=null and companyName!=''">/*相当于case*/
company_name like #{companyName}
</when>
<when test="brandName!=null and brandName!=''">/*相当于case*/
brand_name like #{brandName}
</when>
</choose>
</select>
如果用户什么都没有传参数过来那么otherwise1=1,即sql语句为select * from tb_brand where 1=1。如果没有otherwise那么语句就为select * from tb_brand where会报错。
<choose>
<when test="status!=null">/*相当于case*/
status=#{status}
</when>
<when test="companyName!=null and companyName!=''">/*相当于case*/
company_name like #{companyName}
</when>
<when test="brandName!=null and brandName!=''">/*相当于case*/
brand_name like #{brandName}
</when>
<otherwise>/*相当于default*/
1=1
</otherwise>
</choose>
当然这里可以把otherwise去掉换成
<select id="selectByConditionSingle" resultMap="brandResultMap">
<!--select *
from tb_brand
where
<choose>
<when test="status!=null">/*相当于case*/
status=#{status}
</when>
<when test="companyName!=null and companyName!=''">/*相当于case*/
company_name like #{companyName}
</when>
<when test="brandName!=null and brandName!=''">/*相当于case*/
brand_name like #{brandName}
</when>
<otherwise>/*相当于default*/
1=1
</otherwise>
</choose>-->
select *
from tb_brand
<where>
<choose>
<when test="status!=null">/*相当于case*/
status=#{status}
</when>
<when test="companyName!=null and companyName!=''">/*相当于case*/
company_name like #{companyName}
</when>
<when test="brandName!=null and brandName!=''">/*相当于case*/
brand_name like #{brandName}
</when>
</choose>
</where>
</select>