MyBatis
Mybatis笔记连载上篇连接MyBatis缓存
Mybatis笔记连载下篇连接
动态SQL
动态SQL可以根据条件智能生成SQL语句。通过if,choose,when,otherwise,trim,where,set,foreach等标签,可组成比较灵活的sql语句。
较多例子,需要使用到sqlsession,写出一个可复用的getSession方法
SqlSession getSession() throws IOException {
String resource = "Mybatis/mybatis-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sqlSessionFactory.openSession();
return session;
}
一、if语句
以上例子是使用了if语句来使用模糊搜索,注意到有1=1的条件,是防止无传入条件时没有生成任何语句导致的where结尾造成的错误,当没有传入条件时默认查询全部。
_parameter这个属性,表示的是传入的参数,如果传入的参数有多个,如果是list那么使用_parameter.get(i)来获取参数,如果是map的参数有key值,可以使用_parameter.key来获取key对应的value参数。
在finduserbylikename1中使用的是String参数,传入参数只有一个,直接用_parameter来判断,如果是空就不需要增加语句,反之使用这个String参数来生成一个模糊查询语句。
在finduserbylikename2中使用的是Map参数,传入的参数可以为多个,_parameter.name相当于map.get("name")获得这里的value,来进行判断。如果是空就不需要增加语句,反之使用这个value来生成一个模糊查询语句。其中的bind属性是将传入的参数进行增强处理,这里的bind是将传入的name前面后加%号并起一个别名为pattern,这样在java程序中填写程序就不需要再加%号并且在下方使用这个参数时可以直接使用这个别名。
测试代码
@Test
public void likenameTest() throws IOException {
SqlSession session = getSession();
String stat = "test.mybatis.DBMapping.UserMapper.finduserbylikename1";
List users = session.selectList(stat,"%张%");
for (User user : users) {
System.out.println(user.toString());
}
stat = "test.mybatis.DBMapping.UserMapper.finduserbylikename2";
Map map = new HashMap<>();
map.put("name","张");
users = session.selectList(stat,map);
for (User user : users) {
System.out.println(user.toString());
}
}
运行结果:
Id:1 Name:张三 Age:24 Money:666.66
Id:1 Name:张三 Age:24 Money:666.66
二、choose语句
这个语句相当于java中的switch语句。
@Test
public void findcard() throws IOException {
SqlSession session = getSession();
String stat = "test.mybatis.DBMapping.UserMapper.findcard";
Map map = new HashMap();
map.put("value","city");
map.put("type","city");
List cards = session.selectList(stat,map);
for (Card card : cards) {
System.out.println(card.toString());
}
map = new HashMap();
map.put("type","other");
map.put("city","city");
map.put("address","address");
cards = session.selectList(stat,map);
for (Card card : cards) {
System.out.println(card.toString());
}
}
这里根据使用的哪个查询来生成对应的代码在map中放置两个属性,一个type代表程序使用哪个类型来查询,一个value代表这个类型时使用的参数。
还有一种情况,就是有时候对对象的修改操作时,需要两个以上的条件来修改这个行,有时要根据id修改name,有时需要根据id修改age,有时要根据age和name来修改city。这个时候就要使用到trim。
prefix:在trime标签内为sql语句加上前缀。
suffix:在trime标签内为sql语句加上后缀。
suffixOverrides:指定去除多余的后缀内容。
prefixOverrides:指定去除多余的前缀内容。
以上例子就是在update card后增加以set为前缀的判断修改参数是否为空来增加参数和去除尾巴多余的逗号,再增加以where为前缀的判断查询参数是否为空来增加参数和去除多余前缀and|or。
@Test
public void updatecard() throws IOException {
SqlSession session = getSession();
String stat = "test.mybatis.DBMapping.UserMapper.findcard";
Map map = new HashMap();
map.put("cradNo","cardNo1");
map.put("city","city1");
map.put("id",1);
map.put("address","address");
session.update(stat,map);
session.commit();
stat = "test.mybatis.DBMapping.UserMapper.findcard";
map = new HashMap();
map.put("type","address");
map.put("value","address");
List cards = session.selectList(stat,map);
System.out.println("更改后通过查询\n");
for (Card card : cards) {
System.out.println(card.toString());
}
}
执行更改后,再通过findcard进行查询输出。
三、foreach语句
有时候sql需要使用到in查询,例如
这个时候就需要使用到foreachh语句。
- Item:表示集合中每一个元素进行迭代时的别名。
- Index:指定一个名字,用于表示在迭代过程中每次迭代到的位置。
- Open:表示该语句以什么开始。
- Separator:表示在每次进行迭代之间以什么符号作为分隔符。
- Close:表示以什么结束。
foreach中使用传进来的map类型的ids来进行迭代,使用index来代表迭代到的位置,使用item来代表单个元素的别名。在迭代开始时增加一个(,在结束时增加一个)。
@Test
public void foreachTest() throws IOException {
SqlSession session = getSession();
String stat = "test.mybatis.DBMapping.UserMapper.findcardbyuserids";
List ids = new ArrayList();
ids.add("1");
ids.add("2");
ids.add("3");
Map map = new HashMap();
map.put("ids",ids);
List users = session.selectList(stat,map);
for (User user : users) {
System.out.println(user.toString());
}
}
传入ids后,生成的语句就是
select * from t_user id in(1,2,3)
执行结果
Id:1 Name:张三 Age:24 Money:666.66
Id:2 Name:李四 Age:25 Money:888.88
Id:3 Name:王二 Age:26 Money:999.99