1.几个不常用的类
ObjectFactory:从结果中获得一个新的实例时,比如resultType='User',此User实例由ObjectFactory创建
SelectBuilder:Mybatis中比较特别的动态创建SQL的方式。动态创建SQL可以在XML配置文件中创建,但如果是通过Mapper方式,可以使用SeletctBuilder,基于Mapper的动态sql还可以利用SqlBuilder。用户指南中有例子。
2.基于XML的动态SQL
主要是利用一些标签:<if>,<where>,<when>,<choose>,<otherwise>,<set>,<trim>,<foreach>
- <if>,<when>标签只能做一些基本的条件判断,如"=",">","<",但如果要进行复杂条件判断,比如调用一个Java对象的方法,则显得力不从心,如果是基于Mapper的sql实现,SelectBuilder可以做的很好,但如果基于XML,就要求助于强大的表达式工具:ognl
比如现有一个OgnlHelper类,其中有一个判断是否有特殊字符的static方法hasSpecialChar,则可以通过ognl表示给出
<where>
<choose>
<when test="@com.test.OgnlHelper@hasSpecialChar(name)">
and name like '%'||#{name}||'%' escape '\'
</when>
<otherwise>
and name like '%'||#{name}||'%'
</otherwise>
</choose>
</where>
tips:
1、sql中like匹配时的用法为like ‘%’||#{}||‘%’
2、SqL中使用 ESCAPE 关键字定义转义符。当转义符置于通配符之前时,该通配符就解释为普通字符
例1,要搜索“A_”开头的所有内容,请使用下列语句。句中通过escap将“_”转义,否则“_"为一个字符的通配符。
WHERE ColumnX LIKE '%A_' ESCAPE '_'
例2,查找"%aa"开头的所有内容,语为如下。下例语句中第一个"%"仍为通配符“%”,第二个通过“/”将后边的“%”转义为“%”,而不是通配符。
WHERE ColumnX LIKE '%/%aa' ESCAPE '/'
- <selectKey>
<insert>插入。如果数据库库支持自动生成主键,可简单的将useGeneratedKeys设置为true,然后使用keyProperty设置希望自动生成主键的字段。
还有另外一种为不支持自动生成主键的数据库及JDBC驱动来生成键值
<insert ...>
<selectKey keyProperty='id'...>
select max(id)+1 from somedb
</selectKey>
</insert>
- <foreach>
select * from loginfo where lid in
<foreach item="item" index="index" collection="lid"
open="(" separator="," close=")">
#{item}
</foreach>
<select id="sel_buildinginfo" parameterType="java.util.List" resultType="Buildinginfo">
select bldid,bldno,cmpid from buildinginfo
<where>
state!='d' and
<foreach item="item" index="index" collection="list"
separator="or" >
<choose>
<when test="item!=0">
bldid=#{item}
</when>
<when test="item==0">
bldid!=0
</when>
</choose>
</foreach>
</where>
</select>
如果传入的是单参数且参数类型是一个array数组的时候,collection的属性值为array; int[] ids = new int[] {1,3,6,9};
如果传入的参数是多个的时候,我们就需要把它们封装成一个Map了,collection的值为Map的key,参见下例.
3.hashmap
resultType分别为javabean,hashmap,parameterType分别为基本类型、hashmap时的example
<select id="sel_login_by_bean" parameterType="int" resultType="LoginPojo">
select * from loginfo where lid=#{lid}
</select>
<select id="sel_login" parameterType="int" resultType="hashmap">
select lid,logname,password from loginfo where lid=#{lid}
</select>
<select id="sel_login_by_map" parameterType="hashmap" resultType="LoginPojo">
select * from loginfo where lid=#{lid}
</select>
<select id="sel_login_by_hashmap_list" parameterType="hashmap" resultType="LoginPojo">
select * from loginfo where lid in
<foreach item="item" index="index" collection="lid"
open="(" separator="," close=")">
#{item}
</foreach>
</select>
LogPojo.java三个字段:lid,logname,password
public void test(){
SqlSession session=databaseOperator.getSession();
LoginPojo login1=new LoginPojo();
LoginPojo login2=new LoginPojo();
HashMap<String,String> result=new HashMap<String, String>();
ArrayList rlt=new ArrayList ();
HashMap<String,Integer> hs=new HashMap<String,Integer>();
hs.put("lid", 4);
HashMap<String, ArrayList<Integer>> hslist=new HashMap<String, ArrayList<Integer>>();
ArrayList<Integer> in=new ArrayList<Integer>();
in.add(2);
in.add(4);
hslist.put("lid", in);
try{
//resultType为javabean
login1=(LoginPojo) session.selectOne("test.sel_login_by_bean",2);
//resultType为hashmap
result=(HashMap<String, String>) session.selectOne("test.sel_login",2);
//parameterType为hashmap<String,String>,结果为pojo对象
login2=(LoginPojo) session.selectOne("test.sel_login_by_map", hs);
//result:{lid=2, password=666666, logname=sysadmin}
//parameterType为HashMap<String, ArrayList<Integer>>,结果为arraylist
rlt=(ArrayList) session.selectList("test.sel_login_by_hashmap_list", hslist);
}catch(Exception e){
e.printStackTrace();
}
System.out.println(login1);
System.out.println(result);
System.out.println(login2);
System.out.println(rlt);
}
}
输出结果为:
{"lid":2,"password":"666666","logname":"sysadmin"}
{lid=2, password=666666, logname=sysadmin}
{"lid":4,"password":"666666","logname":"cmpadmin"}
[{"lid":2,"password":"666666","logname":"sysadmin"}, {"lid":4,"password":"666666","logname":"cmpadmin"}]
注意事项:
1.由输出的result可知,结果为hashmap时,查询出的每个字段名称为key,查出的值为value.
2.如果parameterType为hashmap,那么hashmap<k,v>的key必须与#{id}中#{}里的内容一致,比如上述情况hashmap的key为lid,且只能使用selectOne(),想要使用selectList选出集合,那么hashmap必须为hashmap<k,ArrayList<v>>,且需要用到<foreach>标签,foreach标签的collection是传入hashmap参数的key值比如上例中collection="lid".
4.selectMap
<resultMap type="LoginPojo" id="login">
<id property="lid" column="lid" javaType="java.lang.Integer"/>
<result property="logname" column="logname" javaType="java.lang.String"/>
<result property="password" column="password" javaType="java.lang.String"/>
</resultMap>
<select id="selectByIdToMap" parameterType="int" resultMap="login">
select lid, logname, password
from loginfo where lid = #{lid}
</select>
property:需要映射到javabean的属性名称
column:数据库中数据表相对应的列名
<resultMap>标签的id为了标识唯一性,id、result是最简单的映射,id为主键映射;result其他基本数据库表字段到实体类属性的映射
public Map<String, LoginPojo> selectMap(int id){
Map<String, LoginPojo> LoginPojoMap = new HashMap<String, LoginPojo>() ;
LoginPojoMap = session.selectMap("test2.selectByIdToMap", id, "logname") ;
return LoginPojoMap ;
}
public static void main(String[] args) {
SqlSession session=databaseOperator.getSession();
test2 maintest = new test2() ;
Map<String, LoginPojo> LoginPojoMap = maintest.selectMap(2) ;
System.out.println(LoginPojoMap.get("sysadmin"));
System.out.println(LoginPojoMap);
}
输出结果:
{"lid":2,"password":"666666","logname":"sysadmin"}
{sysadmin={"lid":2,"password":"666666","logname":"sysadmin"}}
selectMap(String statement, Object parameter, String mapKey),Object parameter是传入的参数,String mapKey是指定查询出的对象中某字段为map的key值,上例中指定查询出的LoginPojo对象的字段logname为key,对应LoginPojo对象是value值