zoukankan      html  css  js  c++  java
  • mybatis注解实现CURD

    我们来看下面这段代码:

    /** 
     * The user Mapper interface. 
     *  
     * @author Wangzun
     *
     * @version 1.0 
     *  
     *
     */  
    @CacheNamespace(size = 512)  
    public interface UserMapper {  
      
        /** 
         * get user bean by id. 
         *  
         * @param id 
         * @return 
         */  
        @SelectProvider(type = UserSqlProvider.class, method = "getSql")  
        @Options(useCache = true, flushCache = false, timeout = 10000)  
        @Results(value = {  
                @Result(id = true, property = "id", column = "user_id", javaType = String.class, jdbcType = JdbcType.VARCHAR),  
                @Result(property = "userName", column = "user_name", javaType = String.class, jdbcType = JdbcType.VARCHAR) })  
        public UserBean get(@Param("id") String id);  
      
        /** 
         * get all users. 
         *  
         * @return 
         */  
        @SelectProvider(type = UserSqlProvider.class, method = "getAllSql")  
        @Options(useCache = true, flushCache = false, timeout = 10000)  
        @Results(value = {  
                @Result(id = true, property = "id", column = "user_id", javaType = String.class, jdbcType = JdbcType.VARCHAR),  
                @Result(property = "userName", column = "user_name", javaType = String.class, jdbcType = JdbcType.VARCHAR) })  
        public List<UserBean> getAll();  
      
        /** 
         * get users by test userName. 
         *  
         * @param userName
         * @return 
         */  
        @SelectProvider(type = UserSqlProvider.class, method = "getByUserNameSql")  
        @Options(useCache = true, flushCache = false, timeout = 10000)  
        @ResultMap(value = "getByUserName")  
        public List<TestBean> getByUserName(@Param("userName") String userName);  
      
        /** 
         * insert a user bean into database. 
         *  
         * @param userBean
         */  
        @InsertProvider(type = UserSqlProvider.class, method = "insertSql")  
        @Options(flushCache = true, timeout = 20000)  
        public void insert(@Param("userBean") UserBean userBean);  
      
        /** 
         * update a user bean with database. 
         *  
         * @param userBean
         */  
        @UpdateProvider(type = UserSqlProvider.class, method = "updateSql")  
        @Options(flushCache = true, timeout = 20000)  
        public void update(@Param("userBean") UserBean usertBean);  
      
        /** 
         * delete a user by id. 
         *  
         * @param id 
         */  
        @DeleteProvider(type = UserSqlProvider.class, method = "deleteSql")  
        @Options(flushCache = true, timeout = 20000)  
        public void delete(@Param("id") String id);  
    } 

    @CacheNamespace(size = 512) : 定义在该命名空间内允许使用内置缓存,最大值为512个对象引用,读写默认是开启的,缓存内省刷新时间为默认3600000毫秒,写策略是拷贝整个对象镜像到全新堆(如同CopyOnWriteList)因此线程安全。 

    @SelectProvider(type = UserSqlProvider.class, method = "getSql") : 提供查询的SQL语句,也可以直接使用@Select("select * from ....")注解,把查询SQL抽取到一个类里面,方便管理,同时复杂的SQL也容易操作,type = TestSqlProvider.class就是存放SQL语句的类,而method = "getSql"表示get接口方法需要到TestSqlProvider类的getSql方法中获取SQL语句。 

    @Options(useCache = true, flushCache = false, timeout = 10000) : 一些查询的选项开关,比如useCache = true表示本次查询结果被缓存以提高下次查询速度,flushCache = false表示下次查询时不刷新缓存,timeout = 10000表示查询结果缓存10000秒。 

    @Results(value = { 
    @Result(id = true, property = "id", column = "user_id", javaType = String.class, jdbcType = JdbcType.VARCHAR), 
    @Result(property = "userName", column = "user_name", javaType = String.class, jdbcType = JdbcType.VARCHAR) }) : 表示sql查询返回的结果集,@Results是以@Result为元素的数组,@Result表示单条属性-字段的映射关系,如:@Result(id = true, property = "id", column = "user_id", javaType = String.class, jdbcType = JdbcType.VARCHAR)可以简写为:@Result(id = true, property = "id", column = "test_id"),id = true表示这个test_id字段是个PK,查询时mybatis会给予必要的优化,应该说数组中所有的@Result组成了单个记录的映射关系,而@Results则单个记录的集合。另外还有一个非常重要的注解@ResultMap也和@Results差不多,到时会讲到。 

    @Param("id") :全局限定别名,定义查询参数在sql语句中的位置不再是顺序下标0,1,2,3....的形式,而是对应名称,该名称就在这里定义。 

    @ResultMap(value = "getByUserName") :重要的注解,可以解决复杂的映射关系,包括resultMap嵌套,鉴别器discriminator等等。注意一旦你启用该注解,你将不得不在你的映射文件中配置你的resultMap,而value = "getByUserName"即为映射文件中的resultMap ID(注意此处的value = "getByUserName",必须是在映射文件中指定命名空间路径)。@ResultMap在某些简单场合可以用@Results代替,但是复杂查询,比如联合、嵌套查询@ResultMap就会显得解耦方便更容易管理。

    一个映射文件如下所示:

    <?xml version="1.0" encoding="UTF-8" ?>    
    <!DOCTYPE mapper    
    PUBLIC "-//ibatis.apache.org//DTD Mapper 3.0//EN"    
    "http://ibatis.apache.org/dtd/ibatis-3-mapper.dtd">  
      
    <mapper namespace="com.persist.user.mapper.UserMapper">  
        <resultMap id="getByUserName" type="UserBean">  
            <id property="id" column="test_id" javaType="string" jdbcType="VARCHAR" />  
            <result property="userName" column="user_name" javaType="string" jdbcType="VARCHAR" />  
        </resultMap>  
    </mapper>  

    注意文件中的namespace路径必须是使用@resultMap的类路径,此处是UserMapper,文件中 id="getByUserName"必须和@resultMap中的value = "getByUserName"保持一致。 

    @InsertProvider(type = UserSqlProvider.class, method = "insertSql") :用法和含义@SelectProvider一样,只不过是用来插入数据库而用的。 

    @Options(flushCache = true, timeout = 20000) :对于需要更新数据库的操作,需要重新刷新缓存flushCache = true使缓存同步。 

    @UpdateProvider(type = UserSqlProvider.class, method = "updateSql") :用法和含义@SelectProvider一样,只不过是用来更新数据库而用的。 

    @Param("userBean") :是一个自定义的对象,指定了sql语句中的表现形式,如果要在sql中引用对象里面的属性,只要使用userBean.id,userBean.userName即可,mybatis会通过反射找到这些属性值。 

    @DeleteProvider(type =UserSqlProvider.class, method = "deleteSql") :用法和含义@SelectProvider一样,只不过是用来删除数据而用的。 

    现在mybatis注解基本已经讲完了,接下来我们就要开始写SQL语句了,因为我们不再使用映射文件编写SQL,那么就不得不在java类里面写,就像上面提到的,我们不得不在UserSqlProvider这个类里面写SQL,虽然已经把所有sql语句集中到了一个类里面去管理,但听起来似乎仍然有点恶心,幸好mybatis提供SelectBuilder和SqlBuilder这2个小工具来帮助我们生成SQL语句,SelectBuilder专门用来生成select语句,而SqlBuilder则是一般性的工具,可以生成任何SQL语句,我这里选择了SqlBuilder来生成,TestSqlProvider代码如下:

    /* 
     *
     */  
    package com.persist.user.sqlprovider;  
      
    import static org.apache.ibatis.jdbc.SqlBuilder.BEGIN;  
    import static org.apache.ibatis.jdbc.SqlBuilder.FROM;  
    import static org.apache.ibatis.jdbc.SqlBuilder.SELECT;  
    import static org.apache.ibatis.jdbc.SqlBuilder.SQL;  
    import static org.apache.ibatis.jdbc.SqlBuilder.WHERE;  
    import static org.apache.ibatis.jdbc.SqlBuilder.DELETE_FROM;  
    import static org.apache.ibatis.jdbc.SqlBuilder.INSERT_INTO;  
    import static org.apache.ibatis.jdbc.SqlBuilder.SET;  
    import static org.apache.ibatis.jdbc.SqlBuilder.UPDATE;  
    import static org.apache.ibatis.jdbc.SqlBuilder.VALUES;  
      
    import java.util.Map;  
      
    /** 
     * The test sql Provider,define the sql script for mapping. 
     *  
     * @author Wangzun
     *  
     *   
     */  
    public class UserSqlProvider {  
      
        /** table name, here is user */  
        private static final String TABLE_NAME = "user";  
      
        /** 
         * get user by id sql script. 
         *  
         * @param parameters 
         * @return 
         */  
        public String getSql(Map<String, Object> parameters) {  
            String uid = (String) parameters.get("id");  
            BEGIN();  
            SELECT("user_id, user_name");  
            FROM(TABLE_NAME);  
            if (uid != null) {  
                WHERE("user_id= #{id,javaType=string,jdbcType=VARCHAR}");  
            }  
            return SQL();  
        }  
      
        /** 
         * get all users sql script. 
         *  
         * @return 
         */  
        public String getAllSql() {  
            BEGIN();  
            SELECT("user_id, user_name");  
            FROM(TABLE_NAME);  
            return SQL();  
        }  
      
        /** 
         * get test by userName sql script. 
         *  
         * @param parameters 
         * @return 
         */  
        public String getByUserNameSql(Map<String, Object> parameters) {  
            String tText = (String) parameters.get("userName");  
            BEGIN();  
            SELECT("user_id, user_name");  
            FROM(TABLE_NAME);  
            if (tText != null) {  
                WHERE("user_name like #{userName,javaType=string,jdbcType=VARCHAR}");  
            }  
            return SQL();  
        }  
      
        /** 
         * insert a user sql script. 
         *  
         * @return 
         */  
        public String insertSql() {  
            BEGIN();  
            INSERT_INTO(TABLE_NAME);  
            VALUES("user_id", "#{userBean.id,javaType=string,jdbcType=VARCHAR}");  
            VALUES("user_name", "#{userBean.userName,javaType=string,jdbcType=VARCHAR}");  
            return SQL();  
        }  
      
        /** 
         * update a user sql script. 
         *  
         * @return 
         */  
        public String updateSql() {  
            BEGIN();  
            UPDATE(TABLE_NAME);  
            SET("user_name= #{userBean.userName,javaType=string,jdbcType=VARCHAR}");  
            WHERE("user_id= #{userBean.id,javaType=string,jdbcType=VARCHAR}");  
            return SQL();  
        }  
      
        /** 
         * delete a user sql script. 
         *  
         * @return 
         */  
        public String deleteSql() {  
            BEGIN();  
            DELETE_FROM(TABLE_NAME);  
            WHERE("user_id= #{id,javaType=string,jdbcType=VARCHAR}");  
            return SQL();  
        }  
    }  

    BEGIN();表示刷新本地线程,某些变量为了线程安全,会先在本地存放变量,此处需要刷新。 
    SELECT,FROM,WHERE等等都是sqlbuilder定义的公用静态方法,用来组成你的sql字符串。如果你在userMapper中调用该方法的某个接口方法已经定义了参数@Param(),那么该方法的参数Map<String, Object> parameters即组装了@Param()定义的参数,比如userMapper接口方法中定义参数为@Param("userId"),@Param("userText"),那么parameters的形态就是:[key="userId",value=object1],[key="userText",value=object2],如果接口方法没有定义@Param(),那么parameters的key就是参数的顺序小标:[key=0,value=object1],[key=1,value=object2],SQL()将返回最终append结束的字符串,sql语句中的形如 
    #{id,javaType=string,jdbcType=VARCHAR}完全可简写为#{id},我只是为了规整如此写而已。另外,对于复杂查询还有很多标签可用,比如:JOIN,INNER_JOIN,GROUP_BY,ORDER_BY等等,具体使用详情,你可以查看源码。 

    最后记得把你的Mapper接口注入到你的DAO类中,在DAO中引用Mapper接口方法即可。我在BaseDAO中的注解注入如下

    @Repository("userBaseDAO")  
    public class UserBaseDAO { 
    ........
    }
     @Autowired  
        public void setUserMapper(@Qualifier("userMapper")UserMapper userMapper) {  
            this.userMapper =userMapper;  
        }  

    本文参考:http://www.cnblogs.com/ibook360/archive/2012/07/16/2594056.html

  • 相关阅读:
    BestCoder6 1002 Goffi and Squary Partition(hdu 4982) 解题报告
    codeforces 31C Schedule 解题报告
    codeforces 462C Appleman and Toastman 解题报告
    codeforces 460C. Present 解题报告
    BestCoder3 1002 BestCoder Sequence(hdu 4908) 解题报告
    BestCoder3 1001 Task schedule(hdu 4907) 解题报告
    poj 1195 Mobile phones 解题报告
    二维树状数组 探索进行中
    codeforces 460B Little Dima and Equation 解题报告
    通过Sql语句控制SQLite数据库增删改查
  • 原文地址:https://www.cnblogs.com/wangzun/p/7055249.html
Copyright © 2011-2022 走看看