当前位置:首页 > 开发 > 编程语言 > mybatis,Ibatis > 正文

iBatis查询API

发表于: 2011-10-10   作者:chenglinjava   来源:转载   浏览次数:
摘要:   先说点基础的内容,iBatis并不是真正意义上的ORM,官方文档中称其为dataMapper,是数据映射器,也就是一种映射查询工具。iBatis不是万能的,在某些它不能处理的问题时,不能放弃使用JDBC API,那才是根本中的根本。     在iBatis中,建议使用JavaBean,因为我们是面向对象的设计,那么在系统设计时肯定创建了很多刻画具体对象
  先说点基础的内容,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> 
<sqlMap namespace="User">
<typeAlias alias="User" type="ibatis.model.User" />
<select id="getUserByName" parameterClass="java.lang.String"
resultClass="User">
select *
from users
where USERNAME=#VARCHAR#
</select>
</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(null, null, null, null, null);  
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),以此类推。
    一家之言,仅供参考。欢迎交流。

iBatis查询API

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
BATIS动态查询的实现主要是在iBATIS中使用安全的拼接语句,动态查询   iBATIS比JDBC的优势之一,安
BATIS动态查询的实现主要是在iBATIS中使用安全的拼接语句,动态查询   iBATIS比JDBC的优势之一,安
目前公司的查询结果是关联的数据结构, 酒店列表的酒店对象 有个字段是 价格计划列表 . 对于这种关联
BATIS动态查询的实现主要是在iBATIS中使用安全的拼接语句,动态查询   iBATIS比JDBC的优势之一,安
本例子连接tb_account,tb_order,tb_orderItem三张表进行连接查询。 Account.java代码如下: package
本文系 iBatis开发详解系列文章之在iBatis查询复杂集合 通常我们使用iBatis的select查询都是映射的
本文系 iBatis开发详解系列文章之在iBatis查询复杂集合 通常我们使用iBatis的select查询都是映射的
本文系 iBatis开发详解系列文章之在iBatis查询复杂集合 通常我们使用iBatis的select查询都是映射的
授权成功我的密钥 爱查快递API使用说明文档 API地址: 以前:http://api.ickd.cn/?com=[]&nu=[]&id=[
以下内容翻译自CQRS by Martin Fowler,有一些修改: CQRS(Command Query Responsibility Segregat
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号