所谓的动态SQL就是能动态改变sql语句,那么必定要某控制条件来控制sql语句结构,最常用的控制方法就是在sql配置中添加if条件.
用到的表:
create table news_inf
(
news_id int auto_increment primary key,
news_title varchar(225),
news_content varchar(1000),
status text(100)
);
映射对象:
public class News {
private Integer id ;
private String title;
private String content;
private String status;
//set、get方法,构造器省略。。。
}
用xml配置sql语句:
拿insert举例(select,update,delete中用法一样):
<insert id="insertNews2" databaseId="mysql" >
insert into news_inf (
<if test="title != null">
news_title,
</if>
<if test="content != null">
news_content,
</if>
status
) values (
<if test="title != null">
#{title},
</if>
<if test="content != null">
#{content},
</if>
#{status})
</insert>
要insert的列和insert的列的值都是动态的,当test属性为true才会加载出if标签中的内容。
值得注意的是,if标签中用到参数时,不用#{}。而是直接写参数名,这与sql语句中使用参数有区别,道理很简单,因为if标签中的参数并不是占位符,而是现取现用的。
用注解配置sql语句:
先指用哪个类来包装动态的sql语句,并且指定用该类的哪个方法
@InsertProvider(type=NewsSqlProvider.class,method = "insert")
int insertNews2( News news);
写sql语句包装类
1、在该类中写方法,方法名为注解中指定的(如果指定,那么方法名必须是provideSql)
2、参数与包装sql语句的方法中参数同步。值得注意的是,如果用自定义方法名,并且参数不止一个,那么该方法也需要用@Param修饰,并且指定的方法名与包装sql语句的方法中参数名相同。
3、方法内return字符串作为sql语句
4、org.apache.ibatis.jdbc.SQL中有大量的方法用于动态拼接sql语句,所以我们可以利用SQL子类来完成sql语句拼接,让代码更简洁,逻辑更清晰,一般我们用SQL的匿名内部类,然后调用toString方法(SQL类中已经处理好该方法)。
5、由于类体内不可以直接写我们所需的代码,所以把他们放在实例初始化块里。
public class NewsSqlProvider{
public String insert(News news)
{
//return静态内部类(SQL中有SELECT,INSERT,INTO_COLUMNS等等一系列方法)
return new SQL(){
//实力初始化块
{
INSERT_INTO("news_inf");
if (news != null && news.getTitle() != null )
INTO_COLUMNS("news_title");
if(news != null && news.getContent() != null)
INTO_COLUMNS("news_content");
INTO_COLUMNS("status");
if (news != null && news.getTitle() != null )
INTO_VALUES("#{title}");
if(news != null && news.getContent() != null)
INTO_VALUES("#{content}");
INTO_VALUES("#{status}");
}
}.toString();
}
}