第十三周——MyBatis(二)

一、动态SQL语句

  • 普通SQL语句查询

假设我们需要对Product表进行查询,不仅要查询所有,更要求模糊查询。

通常情况下,我们会写两条SQL语句,执行两次方法来得到我们想要的效果。

TestProduct.java

System.out.println("查询所有的");
List<Product> ps = session.selectList("listProduct");
for(Product p : ps){
	//这里直接输出的就是一个对象的地址
	System.out.println(p);
}
		
System.out.println("模糊查询");
Map<String, Object> params = new HashMap<>();
params.put("name", "果");
List<Product> ps2 = session.selectList("listProductByName", params);
for(Product p : ps2){
	System.out.println(p);
}

Product.xml

其实我们可以发现,这里即使我们传入了参数name,在select标签的属性中也没有parameterType这么一个属性。因此这个背后存在MyBatis的自动赋值的操作。

<select id = "listProduct" resultType = "Product">
	select * from product
</select>
	
<select id = "listProductByName" resultType = "Product">
	select * from product where name like concat('%', #{name}, '%')
</select>

输出结果:

 默认输出的会是一个对象的地址,而不是一个对象的形式。

如果我们想要输出的是一个对象的形式,就需要重写toString()方法。——在Product.java中重写。

@Override
public String toString() {
	return "Product[id=" + id + ",name=" + name + ",price=" + price + "]";
}

重新运行TestProduct.java

  •  if标签

if标签是对前面那种情况的一种更为方便的操作。如果没有传递参数name,那么就是查询所有;如果传递了name参数,那么就是进行模糊查询。

这样只需要定义一条sql语句就可以应付多种情况了,在测试的时候,也只需要调用这么一条语句所对应的id了。

Product.xml

<select id = "listProduct" resultType = "Product">
	select * from product
	<if test = "name != null">
		where name like concat('%', #{name}, '%')
	</if>
</select>

 可以看到,我们其实是将之间的两条SQL语句整合成为了一条。用一个if判断来表示最终执行的真实语句。if标签的test属性中判断的条件。

TestProduct.java

System.out.println("查询所有的");
List<Product> ps = session.selectList("listProduct");
for(Product p : ps){
	System.out.println(p);
}
		
System.out.println("模糊查询");
Map<String, Object> params = new HashMap<>();
params.put("name", "果");
List<Product> ps2 = session.selectList("listProduct", params);
for(Product p : ps2){
	System.out.println(p);
}

 相比于前面的,此处的代码只进行了一处改动,就是将模糊查询中的方法名进行了改变,其他的地方都没有变动。

  •  where标签

多条件的矛盾:

<select id="listProduct" resultType="Product">
	select * from product
	<if test="name!=null">
		where name like concat('%',#{name},'%')
	</if>		 	
	<if test="price!=0">
		and price > #{price}
	</if>		 	
</select>

如果我们在传参时,没有传入name这个参数,而是传入了price。那么我们的SQL语句就变成了“select * from product and price > #{price}”,而这个SQL语句显然是不正确的,缺少了where而多了一个and。where标签就是起这个作用的。

<select id = "listProduct" resultType = "Product">
	select * from product
	<where>
		<if test = "name != null">
			where name like concat('%', #{name}, '%')
		</if>
		<if test = "price != null and price != 0">
			and price > #{price}
		</if>
	</where>
</select>

 <where>标签会进行自动判断,如果任何条件都不成立,那么就在sql语句里就不会出现where关键字;如果有任何条件成立,会自动去掉多出来的 and 或者 or

  •  set标签

set标签的作用与where标签的效果其实具有相似之处。因为在update中我们也会遇到类似的问题,要不要加set,要不要去掉或者补充多余的and和or。

Product.xml

<update id = "updateProduct">
	update product
	<set>
		<if test = "name != null">name = #{name},</if>
		<if test = "price != null">price = #{price}</if>
	</set>
	where id = #{id}
</update>

一定要在在name=#{name}的后面加入一个逗号,否则运行程序的时候会报SQL的错误。

  • trim标签

trim标签可以用来定制想要的功能。例如我们之间的where标签和set标签其实都可以用trim标签来统一。

利用trim标签更改完对应的SQL语句之后,仍然能出来相应的效果。

<select id = "listProduct" resultType = "Product">
	select * from product
	<trim prefix = "where" prefixOverrides = "and|or">
		<if test = "name != null">
			where name like concat('%', #{name}, '%')
		</if>
		<if test = "price != null and price != 0">
			and price > #{price}
		</if>
	</trim>
</select>

<update id = "updateProduct" parameterType = "Product"> 
	update product
	<trim prefix = "set" prefixOverrides = ",">
		<if test = "name != null">name = #{name},</if>
		<if test = "price != null"> price = #{price}</if>
	</trim>
	where id = #{id}
</update>

 我试过了,prefix里面的where和set大小写都可以成功。

  •  choose标签

Mybatis里面没有else标签,但是可以使用when otherwise标签来达到这样的效果。

其作用是: 提供了任何条件,就进行条件查询,否则就使用id>1这个条件。

数据库:

 TestProduct.java

System.out.println("多条件查询");
Map<String, Object> params = new HashMap<>();
params.put("name", "果");
params.put("price", "5");
List<Product> ps3 = session.selectList("listProduct", params);
for(Product p : ps3){
	System.out.println(p);
}

Product.xml 

<select id = "listProduct" resultType = "Product">
	select * from product
	<where>
		<choose>
			<when test = "name != null">
				and name like concat('%', #{name}, '%')
			</when>
			<when test = "price != null">
				and price > #{price}
			</when>
			<otherwise>
				and id > 1
			</otherwise>
		</choose>
	</where>
</select>

查询结果:

 从数据库中存储的数据以及查询的结果来看,when otherwise中的语句只会执行其中的一条,如果前面的when都不满足,就只执行otherwise;而前面的when中,只会对满足条件的第一个when执行,后面的都不再执行。不太像if-else,更像是switch-case。

  • forEach标签
<select id = "listProduct" resultType = "Product">
	select * from product
		where id in
		<foreach item = "item" index = "index" collection="list" open = "("
			separator = ","  close = ")">
			#{item}
		</foreach>
</select>

对于forEach标签中的每个属性:

  1. item:集合中每一个元素进行迭代时的别名
  2. index表示在迭代过程中,每次迭代到的位置
  3. open:表示语句以什么开始
  4. separator:每次进行迭代之间以什么符号作为分隔符
  5. close:表示语句以什么结束
  6. collection:如果传入的参数是单参数且参数类型是一个List时,collection的值是list;如果传入的是单参数且参数类型是一个array数组时,collection的值是array;如果传入的参数是多个的时候,我们就需要把它的类型封装成Map了。 
List<Integer> ids = new ArrayList<>();
ids.add(1);
ids.add(3);
ids.add(5);
		
List<Product> ps = session.selectList("listProduct", ids);
for(Product p : ps){
	System.out.println(p);
}

二、练习分页

Map<String, Object> params = new HashMap<>();
params.put("start", 0);
params.put("count", 5);
List<Category> cs = session.selectList("listCategory", params);
for(Category c : cs){
	System.out.println(c);
}
<select id = "listCategory" resultType = "Category">
	select * from category_
	<if test = "start != null and count != null">
		limit #{start}, #{count}
	</if>
</select>

 不知道为什么,不是按照id的顺序正常的排列下来。

三、PageHelper插件实现分页

mybatis-config.xml

<plugins>
	<plugin interceptor = "com.github.pagehelper.pageInterceptor">
		
	</plugin>
</plugins>
PageHelper.offsetPage(0, 5);
List<Category> cs = session.selectList("listCategory");
for(Category c : cs){
	System.out.println(c.getName());
}
		
PageInfo pageInfo = new PageInfo<>(cs);
System.out.println("总数:" + pageInfo.getTotal());
System.out.println(pageInfo);

在实现分页的时候,突然间发现控制台出现了错误;连前面可以运行出来的结果都在报错;猜测是jar包出现了问题。导致PageHelper实现分页失败。

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值