Ibatis API 查询

    技术2022-05-19  26

     

    iBatis查询API

    文章分类:Java编程     先说点基础的内容,iBatis并不是真正意义上的ORM,官方文档中称其为dataMapper,是数据映射器,也就是一种映射查询工具。iBatis不是万能的,在某些它不能处理的问题时,不能放弃使用JDBC API,那才是根本中的根本。     在iBatis中,建议使用JavaBean,因为我们是面向对象的设计,那么在系统设计时肯定创建了很多刻画具体对象的类,使用JavaBean就可以直接操作getter方法来获取内容。就像是Hibernate中的PO一样。下面来说一种如何获取Bean中属性名称和属性类型的方法,这在开发时可能会用到。     先定义一个JavaBean,刻画用户模型吗,如下: Java代码   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                    +  "]" ;        }    }   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代码   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();        }    }   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代码   class  (java.lang.Class)    email (java.lang.String)    mobile (java.lang.String)    password (java.lang.String)    userId (java.lang.Integer)    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代码   < 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 >    <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代码   System.out            .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代码   User user= new  User( nullnullnullnullnull );    user = (User) sqlMap.queryForObject( "User.getUserByName""sarin" ,                    user);    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代码   Map map = sqlMap.queryForMap( "User.getAllUsers"null , "userId" );    System.out.println(map);   Map map = sqlMap.queryForMap("User.getAllUsers", null,"userId"); System.out.println(map);     正如你所想,这段代码的输出为: Java代码   { 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代码   System.out.println(map.keySet().iterator().next().getClass());   System.out.println(map.keySet().iterator().next().getClass());     得到结果:class java.lang.Integer,说明这是字段相对应的,因为这里我们没有将查询结果和JavaBean相关联。那么HashMap中存储的value是什么类型呢?我们来看,代码如下: Java代码   System.out.println(map.get( 1 ).getClass());   System.out.println(map.get(1).getClass());     打印得到:class java.util.HashMap,说明存储的还是HashMap。而queryForMap()的第二个重载方法则是指定了value的内容,我们来看: Java代码   Map map = sqlMap.queryForMap( "User.getAllUsers"null"userId" ,             "mobile" );    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代码   List users = sqlMap.queryForList( "User.getAllUsers" );    System.out.println(users);   List users = sqlMap.queryForList("User.getAllUsers"); System.out.println(users);     打印的结果是: Java代码   [{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代码   [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),以此类推。

    最新回复(0)