Mybatis学习(一)

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>
foreach元素的属性主要有 item,index,collection,open,separator,close。
item表示集合中每一个元素进行迭代时的别名;
index指 定一个名字,用于表示在迭代过程中,每次迭代到的位置;
open表示该语句以什么开始;
separator表示在每次进行迭代之间以什么符号作为分隔 符;
close表示以什么结束;
以前一直以为open、close、separator是为了分隔传入的list参数的,后来才知道是为了分隔sql语句的参数
select * from loginfo where lid in
		<foreach item="item" index="index" collection="lid"
      		open="(" separator="," close=")">
        	#{item}
  		</foreach>

这个open、close、separator的意思应该是:select * from loginfo where lid in (item,item,item) 中的(item,item,item) 
下面的例子可以很简单的表达foreach,choose的用法,open,close等都是可选的,separator可以是任意字符
<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>


执行下来是select bldid,bldno,cmpid from buildinginfo where state!='d' and bldid=**  or bldid=**


在使用foreach的时候最关键的也是最容易出错的就是collection属性,该属性是必须指定的,但是在不同情况 下,该属性的值是不一样的,主要有一下3种情况:
如果传入的是单参数且参数类型是一个List的时候,collection属性值为list。List<Integer> ids = new ArrayList<Integer>();  ids.add(1)...
如果传入的是单参数且参数类型是一个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值

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值