动态SQL
if和where
- if标签:作为判断入参来使用的,如果符合条件,则把if标签体内的SQL拼接上。
==注意:==用if进行判断是否为空时,不仅要判断null,也要判断空字符串。 - where标签:会去掉条件中的第一个and符号。
<select id="findUserList" parameterType="vo.UserQueryVO" resultType="user">
SELECT * FROM user
<where>
<if test="user != null">
<if test="user.sex != null and user.sex != ''">
sex=#{user.sex}
</if>
<if test="user.username != null and user.username != ''">
AND username LIKE '%${user.username}%'
</if>
</if>
</where>
</select>
SQL片段
MyBatis提供了SQL片段的功能,可以提高SQL的可重用性。
<!--声明一个SQL片段-->
<sql id="select_user_where">
<if test="user != null">
<if test="user.sex != null and user.sex != ''">
sex=#{user.sex}
</if>
<if test="user.username != null and user.username != ''">
AND username LIKE '%${user.username}%'
</if>
</if>
</sql>
<select id="findUserList" parameterType="vo.UserQueryVO" resultType="user">
SELECT * FROM USER
<where>
<!--引用SQL片段-->
<include refid="select_user_where"/>
</where>
</select>
foreach遍历
案例:查询指定id的用户
select * from user where id in (64,65,66);
//定义包装类
package vo;
import model.User;
import java.util.List;
//定义查询包装类,以后.xml的参数从这个对象取
public class UserListQuery {
private User user;
private List<Integer> ids;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public List<Integer> getIds() {
return ids;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
}
<!--UserMapper.xml-->
<select id="findListUser" parameterType="vo.UserListQuery" resultType="user">
SELECT * FROM USER
<where>
<if test="ids != null and ids.size > 0">
<!--
collection:集合,写集合属性
item:遍历接收变量
open:遍历开始
close:遍历结束
separator:拼接格式
-->
<foreach collection="ids" item="id" open="AND id in(" close=")" separator=",">
${id}
</foreach>
</if>
</where>
</select>
//测试类
@Test
public void test4(){
SqlSession session = ssf.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
UserListQuery ulq = new UserListQuery();
List<Integer> list = new ArrayList<Integer>();
list.add(64);
list.add(65);
list.add(66);
ulq.setIds(list);
System.out.println(mapper.findListUser(ulq));
session.close();
}
另一种遍历,参数直接传入id集合
<select id="findListUser" parameterType="java.util.List" resultType="user">
SELECT * FROM USER
<where>
<!--如果是直接传入集合参数,则该处的参数名称只能填写list-->
<if test="list != null and list.size > 0">
<foreach collection="list" item="id" open="AND id IN (" close=")" separator=",">
#{id}
</foreach>
</if>
</where>
</select>
//测试类
@Test
public void test4(){
SqlSession session = ssf.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<Integer> list = new ArrayList<Integer>();
list.add(10);
list.add(16);
list.add(22);
System.out.println(mapper.findListUser(list));
session.close();
}
MyBatis与Hibernate的区别【面试题】
MyBatis技术特点:
好处
- 通过直接编写SQL语句,可以直接对SQL进行性能的优化。
- 学习门槛低,学习成本低。只要有SQL基础,就可以学习MyBatis,而且很容易上手。
- 由于直接编写SQL语句,所以灵活多变,代码维护性更好。
缺点
- 不能支持数据库无关性,即数据库发生变更,要写多套代码进行支持,移植性不好。
- 需要编写结果映射。
Hibernate技术特点:
好处
- 标准的ORM框架,程序员不需要编写SQL语句。
- 具有良好的数据库无关性,即数据库发生变化的话,代码无需再次编写。
缺点
- 学习门槛高,需要对数据关系模型有良好的基础,而且在设置OR映射的时候,需要考虑好性能和对象模型的权衡。
- 程序员不能自主的去进行SQL性能优化。
MyBatis应用场景:
需求多变的互联网项目,例如电商项目。
Hibernate应用场景:
需求明确,业务固定的项目,例如OA项目、ERP项目等。
关联查询
一对一 resultType实现(扩展类实现)
复杂查询时,单表对应的po类已不能满足输出结果集的映射。所以要根据需求建立一个扩展类来作为resultType的类型.
例子
查找某个订单id的信息,包括用户名字和地址。
- 第一步:写个订单的扩展类
//订单类
package model;
import java.util.Date;
public class Orders {
private Integer id;
private Integer user_id;
private String note;
private String number;
private Date createtime;
public Orders() {
}
public Orders(Integer id, Integer user_id, String note, String number, Date createtime) {
this.id = id;
this.user_id = user_id;
this.note = note;
this.number = number;
this.createtime = createtime;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUser_id() {
return user_id;
}
public void setUser_id(Integer user_id) {
this.user_id = user_id;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
@Override
public String toString() {
return "Orders{" +
"id=" + id +
", user_id=" + user_id +
", note='" + note + '\'' +
", number='" + number + '\'' +
", createtime=" + createtime +
'}';
}
}
//订单扩展类
package model;
import java.util.Date;
public class OrdersExt extends Orders{
private String username;
private String address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "OrdersExt{" +
"username='" + username + '\'' +
", address='" + address + '\'' +
'}'+super.toString();
}
}
- 第二步:声明订单接口
package mapper;
import model.OrdersExt;
public interface OrderMapper {
public OrdersExt findOrderById(int 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="mapper.OrderMapper">
<select id="findOrderById" parameterType="int" resultType="model.OrdersExt">
select
o.*,u.username,u.address
from
orders o ,user u
where
o.user_id = u.id
and u.id= #{id};
</select>
</mapper>
- 第四步:加载映射文件
<!--告诉mybatis加载映射文件-->
<mappers>
<package name="mapper"/>
</mappers>
- 第五步:测试
package test;
import mapper.OrderMapper;
import model.OrdersExt;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import java.io.InputStream;
public class one {
SqlSessionFactory ssf;
@Before
public void setup()throws Exception{
InputStream is =
Resources.getResourceAsStream("SqlMapConfig.xml");
ssf = new SqlSessionFactoryBuilder().build(is);
}
@Test
public void test(){
SqlSession session = ssf.openSession();
OrderMapper mapper = session.getMapper(OrderMapper.class);
OrdersExt res = mapper.findOrderById(10);
System.out.println(res);
session.close();
}
}