Ibatis API 查询

 

    先说点基础的内容,iBatis并不是真正意义上的ORM,官方文档中称其为dataMapper,是数据映射器,也就是一种映射查询工具。iBatis不是万能的,在某些它不能处理的问题时,不能放弃使用JDBC API,那才是根本中的根本。
    在iBatis中,建议使用JavaBean,因为我们是面向对象的设计,那么在系统设计时肯定创建了很多刻画具体对象的类,使用JavaBean就可以直接操作getter方法来获取内容。就像是Hibernate中的PO一样。下面来说一种如何获取Bean中属性名称和属性类型的方法,这在开发时可能会用到。
    先定义一个JavaBean,刻画用户模型吗,如下:
Java代码 复制代码   收藏代码
  1. package  ibatis.model;   
  2. public   class  User  implements  java.io.Serializable {   
  3.      private  Integer userId;   
  4.      private  String userName;   
  5.      private  String password;   
  6.      private  String mobile;   
  7.      private  String email;   
  8.      public  User() {   
  9.          super ();   
  10.     }   
  11.      public  User(Integer userId, String userName, String password,   
  12.             String mobile, String email) {   
  13.          super ();   
  14.          this .userId = userId;   
  15.          this .userName = userName;   
  16.          this .password = password;   
  17.          this .mobile = mobile;   
  18.          this .email = email;   
  19.     }   
  20. // 省略getter和setter方法   
  21.      @Override   
  22.      public  String toString() {   
  23.          return   "User [email="  + email +  ", mobile="  + mobile +  ", password="   
  24.                 + password +  ", userId="  + userId +  ", userName="  + userName   
  25.                 +  "]" ;   
  26.     }   
  27. }  
package ibatis.model;
public class User implements java.io.Serializable {
	private Integer userId;
	private String userName;
	private String password;
	private String mobile;
	private String email;
	public User() {
		super();
	}
	public User(Integer userId, String userName, String password,
			String mobile, String email) {
		super();
		this.userId = userId;
		this.userName = userName;
		this.password = password;
		this.mobile = mobile;
		this.email = email;
	}
// 省略getter和setter方法
	@Override
	public String toString() {
		return "User [email=" + email + ", mobile=" + mobile + ", password="
				+ password + ", userId=" + userId + ", userName=" + userName
				+ "]";
	}
}

    写一个方法来测试,如下:
Java代码 复制代码   收藏代码
  1. public   static   void  main(String[] args) {   
  2.      try  {   
  3.         PropertyDescriptor[] pd = Introspector.getBeanInfo(User. class ).getPropertyDescriptors();   
  4.          for  ( int  i =  0 ; i < pd.length; i++) {   
  5.             System.out.println(pd[i].getName() +  " ("   
  6.                     + pd[i].getPropertyType().getName() +  ")" );   
  7.         }   
  8.     }  catch  (IntrospectionException e) {   
  9.         e.printStackTrace();   
  10.     }   
  11. }  
	public static void main(String[] args) {
		try {
			PropertyDescriptor[] pd = Introspector.getBeanInfo(User.class).getPropertyDescriptors();
			for (int i = 0; i < pd.length; i++) {
				System.out.println(pd[i].getName() + " ("
						+ pd[i].getPropertyType().getName() + ")");
			}
		} catch (IntrospectionException e) {
			e.printStackTrace();
		}
	}

    在控制台,我们获得如下输出:
Java代码 复制代码   收藏代码
  1. class  (java.lang.Class)   
  2. email (java.lang.String)   
  3. mobile (java.lang.String)   
  4. password (java.lang.String)   
  5. userId (java.lang.Integer)   
  6. userName (java.lang.String)  
class (java.lang.Class)
email (java.lang.String)
mobile (java.lang.String)
password (java.lang.String)
userId (java.lang.Integer)
userName (java.lang.String)

    在定位BUG时,这是很好的一种手段。
    接下来,我们来说一下三个常用的查询方法,它们的命名和Spring的JdbcTemplate/SqlMapClientTemplate很像,但是要区分开。
首先是queryForObject()方法,它返回数据库查询的一条结果,并放入到Java对象中,这里的一条记录可以是一个JavaBean,也可以是Java的集合类型。它可以根据<select>标签中配置的resultClass属性来确定的,如果不指定resultClass属性,那么查询结果就是null了,因为iBatis不知道怎么处理这个结果,而且我们也没有配置结果映射(resultMap)。
    首先我们根据上面的User类型,将resultClass设置为User,代码如下:
Xml代码 复制代码   收藏代码
  1. < sqlMap   namespace = "User" >   
  2.      < typeAlias   alias = "User"   type = "ibatis.model.User"   />   
  3.      < select   id = "getUserByName"   parameterClass = "java.lang.String"   
  4.          resultClass = "User" >   
  5.         select *   
  6.         from users   
  7.         where  USERNAME =#VARCHAR#   
  8.      </ select >   
  9. </ sqlMap >   

    这时要求User类中必须要有一个默认的构造方法,否则将不能实例化这个对象,抛出异常,这一点不能忘记(如果重载了构造方法的话)。我们写一个程序:
Java代码 复制代码   收藏代码
  1. System.out   
  2.         .println(sqlMap.queryForObject( "User.getUserByName""sarin" ).getClass().getName());  
		System.out
				.println(sqlMap.queryForObject("User.getUserByName", "sarin").getClass().getName());

    此时,输出内容为:ibatis.model.User,这就很清楚的看到了,查询的结果类型是由<select>中的resultClass来确定的。
    queryForObject()的另外一个重载方法是Object queryForObject(String id, Object parameter, Object resultObject) throws Exception,这种方法是为对象不能轻易创建的情况使用的(如没有默认的构造方法的对象),那么使用前面那种格式就会抛出异常,就需要使用这种方法,看下面代码:(这里去掉User类中的默认构造方法)
Java代码 复制代码   收藏代码
  1. User user= new  User( nullnullnullnullnull );   
  2. user = (User) sqlMap.queryForObject( "User.getUserByName""sarin" ,   
  3.                 user);   
  4. System.out.println(user);  
User user=new User(null, null, null, null, null);
user = (User) sqlMap.queryForObject("User.getUserByName", "sarin",
				user);
System.out.println(user);

    这样才能获得user对象。
    第二个方法是queryForMap()方法,返回结果可以是一条,也可以是多条。它的方法签名有两种形式:第一种是Map queryForMap(String id, Object parameter, String key) throws SQLException,第二种是再多一个参数String value。前面两个参数好理解,就是select标签的id和传入的参数,而后面的key和value是什么意思呢?key指定了Map中存储的键,而value确定了存储的值,不设置value时则存储查询的一个对象,如下面代码(此时已经将select的resultClass设置为hashmap了):
Java代码 复制代码   收藏代码
  1. Map map = sqlMap.queryForMap( "User.getAllUsers"null , "userId" );   
  2. System.out.println(map);  
Map map = sqlMap.queryForMap("User.getAllUsers", null,"userId");
System.out.println(map);

    正如你所想,这段代码的输出为:
Java代码 复制代码   收藏代码
  1. { 1 ={email=gmail @gmail .com, userId= 1 , userName=sarin, password= 123 , mobile= 15940912345 },  2 ={email=gmail @gmail .com, userId= 2 , userName=sarin, password= 123 , mobile= 15940912345 }}  
{1={email=gmail@gmail.com, userId=1, userName=sarin, password=123, mobile=15940912345}, 2={email=gmail@gmail.com, userId=2, userName=sarin, password=123, mobile=15940912345}}

    这里的1和2就是key,是键,那么它们是什么类型的呢?我们使用如下代码来看看:
Java代码 复制代码   收藏代码
  1. System.out.println(map.keySet().iterator().next().getClass());  
System.out.println(map.keySet().iterator().next().getClass());

    得到结果:class java.lang.Integer,说明这是字段相对应的,因为这里我们没有将查询结果和JavaBean相关联。那么HashMap中存储的value是什么类型呢?我们来看,代码如下:
Java代码 复制代码   收藏代码
  1. System.out.println(map.get( 1 ).getClass());  
System.out.println(map.get(1).getClass());

    打印得到:class java.util.HashMap,说明存储的还是HashMap。而queryForMap()的第二个重载方法则是指定了value的内容,我们来看:
Java代码 复制代码   收藏代码
  1. Map map = sqlMap.queryForMap( "User.getAllUsers"null"userId" ,   
  2.          "mobile" );   
  3. System.out.println(map);  
Map map = sqlMap.queryForMap("User.getAllUsers", null, "userId",
		"mobile");
System.out.println(map);

    这将打印:{1=15940912345, 2=15940912345},这回就清楚了吧,而且得到的mobile的类型是String,也就容易理解了。记住一点,queryForMap()方法返回的可以是一条也可以是多条记录。但是在实践中往往用它来获取一条完整的记录,那么使用Map的get()方法就能获取到其中的值了,非常方便。
    下面来看queryForList()方法,同样,该方法的方法签名也有两类形式:第一类是queryForList(String id, Object parameter) throws SQLException,或者不需要参数,这很好理解了。看个例子:(SqlMap中的resultClass设置为hashmap)
Java代码 复制代码   收藏代码
  1. List users = sqlMap.queryForList( "User.getAllUsers" );   
  2. System.out.println(users);  
List users = sqlMap.queryForList("User.getAllUsers");
System.out.println(users);

    打印的结果是:
Java代码 复制代码   收藏代码
  1. [{email=gmail @gmail .com, userId= 1 , userName=sarin, password= 123 , mobile= 15940912345 }, {email=gmail @gmail .com, userId= 2 , userName=sarin, password= 123 , mobile= 15940912345 }]  
[{email=gmail@gmail.com, userId=1, userName=sarin, password=123, mobile=15940912345}, {email=gmail@gmail.com, userId=2, userName=sarin, password=123, mobile=15940912345}]

    就是List中装入的是HashMap对象,在SqlMap中将hashmap换为User,那么得到:
Java代码 复制代码   收藏代码
  1. [User [email=gmail @gmail .com, mobile= 15940912345 , password= 123 , userId= 1 , userName=nanlei], User [email=gmail @gmail .com, mobile= 15940912345 , password= 123 , userId= 2 , userName=sarin]]  
[User [email=gmail@gmail.com, mobile=15940912345, password=123, userId=1, userName=nanlei], User [email=gmail@gmail.com, mobile=15940912345, password=123, userId=2, userName=sarin]]

    queryForList()的第二类方法是queryForList(String id, Object parameter, int skip, int max) throws SQLException,可以看出后面多了两个int类型的参数,那么SQL中使用两个int类型的参数能干什么?分页,没错,这是主要应用。iBatis在queryForList()中提供了为分页提供支持的方法。记着skip是从0开始计算的,而max就是取出的条数,那么取前10条就是(0,10),取11~20条就是(10,10),以此类推。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值