ibatis快速入门(三)

很久没做ibaist的系列的东西了,昨天正好在组里分享了一下,所以就顺手把内容再重新整理一下

首先附一下ibatis的源码包,由于ibaits改成了mybatis,所以官网都很难下到了源码,感谢这个博主的分享

http://yizhilong28.iteye.com/blog/850084

首先看下ibatis的代码结构

ibatis快速入门(三)_第1张图片

主要有comomon和sqlmap两个包,另外还有一个sqldao的包是可选的。其中common是公用的工具类,sqlmap是sqlmaps框架

这里我是用maven组织项目的,我们在来看下maven的pom文件,使用ibatis的一个主要特点就是降低jar包的依赖性,所以一个ibatis的测试包只需要3个jar包即可

ibatis快速入门(三)_第2张图片

上一次我么是用autoDao这个插件来生成一个ibatis项目的,其中生成了两个配置文件,一个config文件,一个sqlmap文件。

其中config文件主要用来定义数据源的,这里有一点要注意下,2.0之后每一个config文件只允许一个数据源了,如果一个项目下有多个数据源,要配置多个config文件,其中config文件主要有以下几个节点:

properties(主要定义属性文件)
settings(用来做一些自定义的配置)
typealias(用来设别名,默认的有JDBC,JTA,EXTERNAL,SIMPLE,DBCP,JNDI)
transcationManager(用来定义事务管理)
datasource(用来配置数据源,2.0以后只允许一个数据源)
sqlMap(用来做其他sqlmp文件的引用)
sqlxml文件主要用来定义各个SQLstatement。以及定义输入参数和输出结果的映射,另外还可以用来配置缓存模型。其主要有以下几个节点

mapstatement(用来定义各个sql语句,包括sql,select,update,delete,insert及procedure)
parameterMap(用来定义入参的映射)
resultMap(用来定义输出结果的映射)
cachemodel(用来定义模型)
提到mapstatment,dynamic的节点就要提一下了,这个是ibatis优于传统的SQL的地方之一。ibaits通过各种不同的节点把一个mapstatement动态映射成各种SQL,提高了代码的重用。这里列出ibatis中所有的动态节点:

二元条件
isEqual
isgreaterThan
isLessThan
一元条件
isPropertyAvailale
isnull
isEmpty collection的size(),String的valueof()
其他
isparameterpresent
iterate
简单的动态SQL
$$
说完了配置文件,我们就要看下ibatis即sqlmapclient的主要的api了

1 配置sqlmap,主要的代码如下:

String resource = "sqlmap-config.xml";
Reader reader = Resources.getResourceAsReader(resource);
sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
2执行SQL的update(包括insert,update和delete)

3获取一个对象

queryforobject
4获取一个对象的list

queryforlist
queryformap
quqyerforpaginatedlist
这里还要提一个queryWithRowHandler()这个api,可以用来处理大数据的操作,其和statement中额fetchsize有关,用来约定每次取多少数据。

接下来,我这里粘一下一个完整的测试代码。其中staement的配置已经在注释中了

public class UserDaoTest {


    private static SqlMapClient sqlMapClient = null;

    static {
        try {
            String resource = "sqlmap-config.xml";
            Reader reader = Resources.getResourceAsReader(resource);
            sqlMapClient = SqlMapClientBuilder.buildSqlMapClient(reader);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注:当parameterClass="string"的时侯,sql语句中的参数没有限制, 如:SELECT * FROM t_user WHERE NAME=#name#,
    // 其中#name#中name可以是任何名称,不过通常情况下,我们习惯于只有一个参数的时候用#value#或者是#熟悉名#
//    <!-- example 1: 无映射 -->
//    <select id="getUserByName1" resultClass="user" parameterClass="string">
//    <![CDATA[
//    SELECT * FROM t_user WHERE NAME=#name#
//            ]]>
//    </select>.
    public static void example1() throws Exception {
        try {
            List<User> list = sqlMapClient.queryForList("getUserByName1", "zxx");
            for (User user : list) {
                System.out.println(user.getId() + "-" + user.getName() + "-" + user.getPass());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注:当使用内联映射 ->实体类的时侯,sql语句中的映射名可以没有限制, 如:SELECT ID as id, NAME as name, PASS as pass FROM t_user WHERE NAME=#name#,
    // 通常情况下映射名就是bean的属性的名字,如果改成这样
    // SELECT ID as iid, NAME as name, PASS as pass FROM t_user WHERE NAME=#name#,其中iid不是bean的属性,那么我们就无法获取id的值,
    // 其实这样写也是没意义的,所以通常情况下映射的名字就是bean的属性的名字。
//    <!-- example 2: 内联映射 -> 实体类 -->
//    <select id="getUserByName2" resultClass="user" parameterClass="string">
//    <![CDATA[
//    SELECT ID as id, NAME as name, PASS as pass FROM t_user WHERE NAME=#name#
//            ]]>
//    </select>
    public static void example2() throws Exception {
        try {
            List<User> list = sqlMapClient.queryForList("getUserByName2", "zxx");
            for (User user : list) {
                System.out.println(user.getId() + "-" + user.getName() + "-" + user.getPass());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注:当使用内联映射 ->MAP类的时侯,即resultClass="hashmap"或者resultClass="java.util.Map"; 它会返回一个Map的集合,
    // Map中的键对应的数据库中的字段名,非bean中的属性名,所以获取的时候get()中的应该是字段名。
//    <!-- example 3: 内联映射 -> MAP类 -->
//    <select id="getUserByName3" resultClass="hashmap" parameterClass="string">
//    <![CDATA[
//    SELECT * FROM t_user WHERE NAME=#name#
//            ]]>
//    </select>
    public static void example3() throws Exception {
        try {
            List<User> list = sqlMapClient.queryForList("getUserByName3", "zxx");
            Iterator iterator = list.iterator();
            while (iterator.hasNext()) {
                Map map = (Map) iterator.next();
                System.out.println(map.get("ID") + ":" + map.get("NAME") + ":" + map.get("PASS"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注:当使用显示映射 ->实体类的时侯,即返回的结果在resultMap中,而非resultClass中,类如上面一个最简单的resultMap,
    // column对应的是字段名,此时字段名不区分大小写, property对应的是bean中的属性名,与example2的内联映射 ->实体类不同的是,
    // 该属性必须在bean中存在,否则就会报错,它的检查更严格..
//    <!-- example 4: 显示映射 -> 实体类 -->
//    <resultMap id="userResult" class="user">
//    <result property="id" column="Id" />
//    <result property="name" column="NAME" />
//    <result property="pass" column="PASS" />
//    </resultMap>
//    <select id="getUserByName4" resultMap="userResult" parameterClass="string">
//    <![CDATA[
//    SELECT * FROM t_user WHERE NAME=#name#
//            ]]>
//    </select>
    public static void example4() throws Exception {
        try {
            List<User> list = sqlMapClient.queryForList("getUserByName4", "zxx");
            for (User user : list) {
                System.out.println(user.getId() + "-" + user.getName() + "-" + user.getPass());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
    // 注:当使用显示映射 ->MAP类的时侯,即resultMap的class不是我们定义的bean而是hashmap或者java.util.Map的时候,类如上面一个最简单的MAP类,
    // column对应的是字段名,此时字段名不区分大小写, property对应的是bean中的属性名,与example3的内联映射 ->MAP类不同的是,它的键值是属性名而非字段名.
//    <!-- example 5: 显示映射 -> MAP类 -->
//    <resultMap id="userMapResult" class="hashmap">
//    <result property="id" column="ID" />
//    <result property="name" column="NAME" />
//    <result property="pass" column="PASS" />
//    </resultMap>
//    <select id="getUserByName5" resultMap="userMapResult" parameterClass="string">
//    <![CDATA[
//    SELECT * FROM t_user WHERE NAME=#name#
//            ]]>
//    </select>
    public static void example5() throws Exception {
        try {
            List<User> list = sqlMapClient.queryForList("getUserByName5", "zxx");
            Iterator iterator = list.iterator();
            while (iterator.hasNext()) {
                Map map = (Map) iterator.next();
                System.out.println(map.get("id") + ":" + map.get("name") + ":" + map.get("pass"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注:xmlResultName="info",xmlResultName定义返回的结果信息保存在xml的那个元素中,如果返回有多个xml对象那么就会产生多个<?Xml ,而不是整合在一个<?xml中。
//    <!-- example 6: XML -->
//    <select id="getUserByName6" parameterClass="string" resultClass="xml" xmlResultName="info">
//    <![CDATA[
//    SELECT * FROM t_user WHERE name=#name#
//            ]]>
//    </select>
    public static void example6() throws Exception {
        try {
            List list = sqlMapClient.queryForList("getUserByName6", "zxx");
            System.out.println(list.get(0));
            // 输出: <?xml version="1.0" encoding="UTF-8"?><info><ID>7</ID><NAME>zxx</NAME><PASS>xfmn123456</PASS></info>
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注: 自动参数映射 插入操作
//    <!-- example 7: 自动参数映射 -->
//    <insert id="insertUser7" parameterClass="user">
//    <![CDATA[
//    INSERT INTO t_user ( ID, NAME, PASS )VALUES( #id#,#name#,#pass# )
//            ]]>
//    </insert>
    public static void example7() throws Exception {
        try {
            User user = new User();
            user.setName("example7");
            sqlMapClient.insert("insertUser7", user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注:内联参数映射 插入操作
//    <!-- example 8: 内联参数映射 -->
//    <insert id="insertUser8" parameterClass="user">
//    <![CDATA[
//    INSERT INTO t_user ( ID, NAME, PASS ) VALUES( #id:INT#, #name:VARCHAR#, #pass:VARCHAR# )
//            ]]>
//    </insert>
    public static void example8() throws Exception {
        try {
            User user = new User();
            user.setName("example8");
            sqlMapClient.insert("insertUser8", user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注:外联参数映射 插入操作,如上述所示:SQL语句中有多少个参数,那么在parameterMap中必须定义多少个,而且要一一对应,参数定义顺序也不要错。
//    <!-- example 9: 外联参数映射 -->
//    <parameterMap id="parameterMap" class="user">
//    <parameter property="id" jdbcType="INTEGER" />
//    <parameter property="name" jdbcType="VARCHAR" />
//    <parameter property="pass" jdbcType="VARCHAR" />
//    </parameterMap>
//    <insert id="insertUser9" parameterMap="parameterMap">
//    <![CDATA[
//    INSERT INTO t_user ( ID, NAME, PASS )VALUES( ?,?,? )
//            ]]>
//    </insert>
    public static void example9() throws Exception {
        try {
            User user = new User();
            user.setName("example9");
            user.setPass("123456");
            sqlMapClient.insert("insertUser9", user);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // 注:该方法插入数据,并返回id的值
//    <!-- example 10: 自动生成的键 -->
//    <insert id="insertUser10" parameterClass="user">
//    <![CDATA[
//    INSERT INTO t_user ( ID,NAME,PASS )VALUES( #id#, #name#, #pass# )
//            ]]>
//    <selectKey resultClass="int" keyProperty="id">
//    <![CDATA[
//    SELECT LAST_INSERT_ID()
//    ]]>
//    </selectKey>
//    </insert>
    public static void example10() throws Exception {
        try {
            User user = new User();
            user.setName("example10");
            user.setPass("123456");
            Integer returnValue = (Integer) sqlMapClient.insert("insertUser10", user);
            System.out.println(returnValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //注:调用存储过程的参数个数必须和写存储过程的时候参数(输入和输出)个数相同.
//    <!-- example 11: 存储过程 -->
//    <resultMap id="returnResultMap" class="user">
//    <result property="id" column="ID" />
//    </resultMap>
//    <parameterMap id="paramUser" class="java.util.Map">
//    <parameter property="name" jdbcType="VARCHAR" javaType="string" mode="IN" />
//    <parameter property="pass" jdbcType="VARCHAR" javaType="string" mode="IN" />
//    <parameter property="id" jdbcType="INT" javaType="Integer" mode="INOUT" resultMap="returnResultMap" />
//    </parameterMap>
//    <procedure id="pro_insertUser11" parameterMap="paramUser" resultClass="int">
//    <![CDATA[
//    {call proc_userinsert(?,?,?)}
//    ]]>
//    </procedure>
    public static void example11() throws Exception {
        try {
            Map map = new HashMap();
            map.put("name", "procedure");
            map.put("pass", "123456");
            Integer returnValue = (Integer)sqlMapClient.insert("pro_insertUser11", map);
            System.out.println(returnValue);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //分页写法
    public static void example12() throws Exception {
        try {
            List<User> list = sqlMapClient.queryForPaginatedList("getUserByName1", "zxx",1);
            for (User user : list) {
                System.out.println(user.getId() + "-" + user.getName() + "-" + user.getPass());
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    public static void main(String[] args) throws Exception {
        Logger logger = Logger.getLogger(UserDaoTest.class);
        logger.debug("开始");
        example1();
        logger.debug("结束");
    }
}

总结一下,这里接着前两个博客,继续深入了一下ibatis的代码结构及主要的两个配置文件,另外熟悉了一下sqlmapclient的常用api

你可能感兴趣的:(ibatis快速入门(三))