zoukankan      html  css  js  c++  java
  • mybatis3温故

    MyBatis可以利用SQL映射文件来配置,也可以利用Annotation来设置。MyBatis提供的一些基本注解如下表所示。

    注解

    目标

    相应的XML

    描述

    @CacheNamespace

    <cache>  

    为给定的命名空间(比如类)配置缓存。属性:

    implemetation,eviction,

    flushInterval , size 和 readWrite 。

    @CacheNamespaceRef

    <cacheRef>

    参照另外一个命名空间的缓存来使用。

    属性:value,也就是类的完全限定名。

    @ConstructorArgs

    方法

    <constructor>

    收集一组结果传递给对象构造方法。

    属性:value,是形式参数的数组

    @Arg

    方法

    <arg>

    <idArg>

    单独的构造方法参数,是ConstructorArgs  集合的一部分。属性:id,column,javaType,typeHandler。

    id属性是布尔值,来标识用于比较的属性,和<idArg>XML 元素相似

    @TypeDiscriminator

    方法

    <discriminator>

    一组实例值被用来决定结果映射的表

    现。属性:Column, javaType ,  jdbcType typeHandler,cases。

    cases属性就是实例的数组。

    @Case

    方法

    <case>

    单独实例的值和它对应的映射。属性:value  ,type ,results 。

    Results 属性是结果数组,因此这个注解和实际的ResultMap 很相似,由下面的  Results注解指定

    @Results

    方法

    <resultMap>

    结果映射的列表,包含了一个特别结果

    列如何被映射到属性或字段的详情。

    属性:value ,是Result注解的数组

    @Result

    方法

    <result>

    <id>

    在列和属性或字段之间的单独结果映

    射。属性:id ,column , property ,

    javaType ,jdbcType ,type Handler ,

    one,many。id 属性是一个布尔值,表

    示了应该被用于比较的属性。one 属性是单独的联系,和 <association> 相似,而many 属性是对集合而言的,和

    <collection>相似。

    @One

    方法

    <association>  

    复杂类型的单独属性值映射。属性:

    select,已映射语句(也就是映射器方

    法)的完全限定名,它可以加载合适类

    型的实例。注意:联合映射在注解 API

    中是不支持的。

    @Many

    方法

    <collection>

    复杂类型的集合属性映射。属性:

    select,是映射器方法的完全限定名,它可加载合适类型的一组实例。注意:联合映射在Java注解中是不支持的。

    @Options

    方法

    映射语句的属性

    这个注解提供访问交换和配置选项的宽广范围,它们通常在映射语句上作为属性出现。而不是将每条语句注解变复杂,Options 注解提供连贯清晰的方式来访问它们。属性:useCache=true,

    flushCache=false,

    resultSetType=FORWARD_ONLY,

    statementType=PREPARED,

    fetchSize= -1,timeout=-1 ,

    useGeneratedKeys=false ,

    keyProperty=”id“。

    理解Java 注解是很重要的,因为没有办法来指定“null ”作为值。因此,一旦你使用了Options注解,语句就受所有默认值的支配。要注意什么样的默认值来避免不期望的行为

    @Insert

    @Update

    @Delete

    方法

    <insert>

    <update>

    <delete>

    这些注解中的每一个代表了执行的真实 SQL。它们每一个都使用字符串数组(或单独的字符串)。如果传递的是字符串数组,它们由每个分隔它们的单独空间串联起来。属性:value,这是字符串数组用来组成单独的SQL语句

    @InsertProvider

    @UpdateProvider

    @DeleteProvider

    @SelectProvider

    方法

    <insert>

    <update>

    <delete>

    <select>

    允许创建动态

    SQL。

    这些可选的SQL注解允许你指定一个

    类名和一个方法在执行时来返回运行

    的SQL。基于执行的映射语句, MyBatis

    会实例化这个类,然后执行由 provider

    指定的方法. 这个方法可以选择性的接

    受参数对象作为它的唯一参数,但是必

    须只指定该参数或者没有参数。属性:

    type,method。type 属性是类的完全限定名。method  是该类中的那个方法名。

    @Param

    参数

    N/A

    当映射器方法需多个参数,这个注解可以被应用于映射器方法参数来给每个参数一个名字。否则,多参数将会以它们的顺序位置来被命名。比如

    #{1},#{2} 等,这是默认的。

    使用@Param(“person”),SQL中参数应该被命名为#{person}。

    这些注解都是运用到传统意义上映射器接口中的方法、类或者方法参数中的。

    今天主要介绍两种使用注解的方式。

    一种是直接在映射器接口中写SQL语句,一种是利用SqlBuilder来创建SQL再由映射器接口来调用

    准备前提:

    1,配置常规的MyBatis主配置文件,即各种数据源,别名等设置。在利用注解配置SQL的时候,一般不需要在主配置文件中配置Mapper,个别情况下需要配置。

    2,数据库表Blog:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    DROP TABLE IF EXISTS `blog`;
    CREATE TABLE `blog` (
      `id` int(10) NOT NULL auto_increment,
      `title` varchar(200) NOT NULL,
      `datevarchar(50) NOT NULL,
      `authername` varchar(15) NOT NULL,
      `content` varchar(500) NOT NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

     数据库表User:

    1
    2
    3
    4
    5
    6
    7
    8
    DROP TABLE IF EXISTS `user`;
    CREATE TABLE `user` (
      `id` int(11) NOT NULL auto_increment,
      `userName` varchar(50) default NULL,
      `userAge` int(11) default NULL,
      `userAddress` varchar(200) default NULL,
      PRIMARY KEY  (`id`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    3,分别写User和Blog对应的JavaBean即setter和getter实体类。

    第一种 映射器接口中写SQL语句

    映射器接口注解

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    package com.whut.inter;
    import java.util.List;
    import org.apache.ibatis.annotations.Delete;
    import org.apache.ibatis.annotations.Insert;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Select;
    import org.apache.ibatis.annotations.Update;
    import com.whut.model.User;
    //最基本的注解CRUD
    public interface IUserDAO {
        @Select("select *from User")
        public List<User> retrieveAllUsers();
                                                                                                                                                                                                                                       
        //注意这里只有一个参数,则#{}中的标识符可以任意取
        @Select("select *from User where id=#{idss}")
        public User retrieveUserById(int id);
                                                                                                                                                                                                                                       
        @Select("select *from User where id=#{id} and userName like #{name}")
        public User retrieveUserByIdAndName(@Param("id")int id,@Param("name")String names);
                                                                                                                                                                                                                                       
        @Insert("INSERT INTO user(userName,userAge,userAddress) VALUES(#{userName},"
                "#{userAge},#{userAddress})")
        public void addNewUser(User user);
                                                                                                                                                                                                                                       
        @Delete("delete from user where id=#{id}")
        public void deleteUser(int id);
                                                                                                                                                                                                                                       
        @Update("update user set userName=#{userName},userAddress=#{userAddress}"
                " where id=#{id}")
        public void updateUser(User user);
    }

    测试代码:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    package com.whut.test;
    import java.io.IOException;
    import java.io.Reader;
    import java.util.List;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import com.whut.inter.IUserDAO;
    import com.whut.model.User;
    public class TestUser {
        private static SqlSessionFactory sqlSessionFactory;
        private static Reader reader;
        static {
            try {
                Reader reader = Resources.getResourceAsReader("mybatic-config.xml");
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
                // 由于使用了注解,所以在主配置文件没有mapper,需要在代码里显示注册该mapper接口
                sqlSessionFactory.getConfiguration().addMapper(IUserDAO.class);
            catch (IOException e) {
                e.printStackTrace();
            }
        }
        public static void main(String[] args) {
            // testSelectAll();
            // testSelectByConditions();
            //testAddUser();
            //testDeleteUser();
                                                                                                                                                                                                                    
            testUpateUser();
        }
        public static void testSelectAll() {
            // sqlSessionFactory.getConfiguration().addMapper(IUserDAO.class);
            SqlSession session = sqlSessionFactory.openSession();
            try {
                IUserDAO userDAO = session.getMapper(IUserDAO.class);
                List<User> users = userDAO.retrieveAllUsers();
                System.out.println("用户编号 " "姓名 " "年龄 住址");
                for (User u : users) {
                    System.out.println(u.getId() + " " + u.getUserName() + " "
                            + u.getUserAge() + " " + u.getUserAddress());
                }
            finally {
                session.close();
            }
        }
        public static void testSelectByConditions() {
            SqlSession session = sqlSessionFactory.openSession();
            try {
                IUserDAO userDAO = session.getMapper(IUserDAO.class);
                User u = userDAO.retrieveUserByIdAndName(4"%spring%");
                if (u != null) {
                    System.out.println("用户编号 " "姓名 " "年龄 住址");
                    System.out.println(u.getId() + " " + u.getUserName() + " "
                            + u.getUserAge() + " " + u.getUserAddress());
                }
            finally {
                session.close();
            }
        }
        public static void testAddUser() {
            User u = new User();
            u.setUserName("dongtian");
            u.setUserAge(51);
            u.setUserAddress("hubeisheng");
            SqlSession session = sqlSessionFactory.openSession();
            try {
                IUserDAO userDAO = session.getMapper(IUserDAO.class);
                userDAO.addNewUser(u);
                session.commit();
            finally {
                session.close();
            }
        }
        public static void testDeleteUser() {
            SqlSession session = sqlSessionFactory.openSession();
            try {
                IUserDAO userDAO = session.getMapper(IUserDAO.class);
                userDAO.deleteUser(7);
                session.commit();
            finally {
                session.close();
            }
        }
                                                                                                                                                                                                                
        public static void testUpateUser() {
            User u = new User();
            u.setId(4);
            u.setUserName("dongtian");
            u.setUserAge(51);
            u.setUserAddress("hubeisheng");
            SqlSession session = sqlSessionFactory.openSession();
            try {
                IUserDAO userDAO = session.getMapper(IUserDAO.class);
                userDAO.updateUser(u);
                session.commit();
            finally {
                session.close();
            }
        }
    }

    第二种 映射器接口调用SqlBuilder生成的SQL进行执行

    映射器接口

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    package com.whut.inter;
    import java.util.List;
    import org.apache.ibatis.annotations.CacheNamespace;
    import org.apache.ibatis.annotations.DeleteProvider;
    import org.apache.ibatis.annotations.InsertProvider;
    import org.apache.ibatis.annotations.Options;
    import org.apache.ibatis.annotations.Param;
    import org.apache.ibatis.annotations.Result;
    import org.apache.ibatis.annotations.ResultMap;
    import org.apache.ibatis.annotations.Results;
    import org.apache.ibatis.annotations.SelectProvider;
    import org.apache.ibatis.annotations.UpdateProvider;
    import org.apache.ibatis.type.JdbcType;
    import com.whut.model.Blog;
    import com.whut.sqlTool.BlogSqlProvider;
    @CacheNamespace(size=100)
    public interface IBlogDAO {
        @SelectProvider(type = BlogSqlProvider.class, method = "getSql")
        @Results(value ={
                @Result(id=true, property="id",column="id",javaType=Integer.class,jdbcType=JdbcType.INTEGER),
                @Result(property="title",column="title",javaType=String.class,jdbcType=JdbcType.VARCHAR),
                @Result(property="date",column="date",javaType=String.class,jdbcType=JdbcType.VARCHAR),
                @Result(property="authername",column="authername",javaType=String.class,jdbcType=JdbcType.VARCHAR),
                @Result(property="content",column="content",javaType=String.class,jdbcType=JdbcType.VARCHAR),
                })
        public Blog getBlog(@Param("id"int id);
                                                                                                                                                                                           
        @SelectProvider(type = BlogSqlProvider.class, method = "getAllSql")
        @Results(value ={
                @Result(id=true, property="id",column="id",javaType=Integer.class,jdbcType=JdbcType.INTEGER),
                @Result(property="title",column="title",javaType=String.class,jdbcType=JdbcType.VARCHAR),
                @Result(property="date",column="date",javaType=String.class,jdbcType=JdbcType.VARCHAR),
                @Result(property="authername",column="authername",javaType=String.class,jdbcType=JdbcType.VARCHAR),
                @Result(property="content",column="content",javaType=String.class,jdbcType=JdbcType.VARCHAR),
                })
        public List<Blog> getAllBlog();
                                                                                                                                                                                           
        @SelectProvider(type = BlogSqlProvider.class, method = "getSqlByTitle")
        @ResultMap(value = "sqlBlogsMap")
        //这里调用resultMap,这个是SQL配置文件中的,必须该SQL配置文件与本接口有相同的全限定名
        //注意文件中的namespace路径必须是使用@resultMap的类路径
        public List<Blog> getBlogByTitle(@Param("title")String title);
                                                                                                                                                                                           
        @InsertProvider(type = BlogSqlProvider.class, method = "insertSql")
        public void insertBlog(Blog blog);
                                                                                                                                                                                           
        @UpdateProvider(type = BlogSqlProvider.class, method = "updateSql")
        public void updateBlog(Blog blog);
                                                                                                                                                                                           
        @DeleteProvider(type = BlogSqlProvider.class, method = "deleteSql")
        @Options(useCache = true, flushCache = false, timeout = 10000)
        public void deleteBlog(int ids);
                                                                                                                                                                                           
    }

    SQL生成器(利用SqlBuilder生成)

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    package com.whut.sqlTool;
    import java.util.Map;
    import static org.apache.ibatis.jdbc.SqlBuilder.*;
    public class BlogSqlProvider {
        private final static String TABLE_NAME = "blog";
        public String getSql(Map<Integer, Object> parameter) {
            BEGIN();
            //SELECT("id,title,authername,date,content");
            SELECT("*");
            FROM(TABLE_NAME);
            //注意这里这种传递参数方式,#{}与map中的key对应,而map中的key又是注解param设置的
            WHERE("id = #{id}");
            return SQL();
        }
        public String getAllSql() {
            BEGIN();
            SELECT("*");
            FROM(TABLE_NAME);
            return SQL();
        }
        public String getSqlByTitle(Map<String, Object> parameter) {
            String title = (String) parameter.get("title");
            BEGIN();
            SELECT("*");
            FROM(TABLE_NAME);
            if (title != null)
                WHERE(" title like #{title}");
            return SQL();
        }
        public String insertSql() {
            BEGIN();
            INSERT_INTO(TABLE_NAME);
            VALUES("title""#{title}");
            //  VALUES("title", "#{tt.title}");
            //这里是传递一个Blog对象的,如果是利用上面tt.方式,则必须利用Param来设置别名
            VALUES("date""#{date}");
            VALUES("authername""#{authername}");
            VALUES("content""#{content}");
            return SQL();
        }
        public String deleteSql() {
            BEGIN();
            DELETE_FROM(TABLE_NAME);
            WHERE("id = #{id}");
            return SQL();
        }
        public String updateSql() {
            BEGIN();
            UPDATE(TABLE_NAME);
            SET("content = #{content}");
            WHERE("id = #{id}");
            return SQL();
        }
    }

    注意由于在映射器接口中调用了@ResultMap,该注解内容是SQL配置文件ResultMap的ID,它是允许访问SQL配置文件中的ResultMap,则需要在相应的SQL配置相应ResultMap,然后再在主配置文件加上该SQL配置的Mapper路径。并且该SQL配置文件的namespace必须与使用@ResultMap的映射器接口的全限定相同。Blog.xml如下。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
    <mapper namespace="com.whut.inter.IBlogDAO">
       <resultMap type="Blog" id="sqlBlogsMap">
          <id property="id" column="id"/>
          <result property="title" column="title"/>
          <result property="authername" column="authername"/>
          <result property="date" column="date"/>
          <result property="content" column="content"/>
       </resultMap>
    </mapper>

    再在主配置文件mybatis-config.xml加入一句mapper。

    1
    2
    3
    <mappers>
            <mapper resource="com/whut/model/Blog.xml"/>
    </mappers>

    测试类

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    package com.whut.test;
    import java.io.IOException;
    import java.io.Reader;
    import java.util.List;
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import com.whut.inter.IBlogDAO;
    import com.whut.model.Blog;
    /**
     * 注意这里是一种利用SqlBuilder以及多种设置来注解使用
     * @author zxl
     *
     */
    public class TestBlog {
        private static SqlSessionFactory sqlSessionFactory;
        private static Reader reader;
        static {
            try {
                Reader reader = Resources.getResourceAsReader("mybatic-config.xml");
                sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
                // 由于使用了注解,所以在主配置文件没有mapper,需要在代码里显示注册该mapper接口
                //sqlSessionFactory.getConfiguration().addMapper(IBlogDAO.class);
            catch (IOException e) {
                e.printStackTrace();
            }
        }
                                                                                                                               
        public static void main(String[] args) {
            //testOneBlog();
            //testAllBlog();
            //testBlogByTitle();
            //testAddBlog();
            //testDeleteBlog();
                                                                                                                                   
            testUpdateBlog();
        }
                                                                                                                               
        public static void testOneBlog()
        {
            SqlSession session=sqlSessionFactory.openSession();
            try{
                IBlogDAO dao=session.getMapper(IBlogDAO.class);
                Blog  blog=dao.getBlog(2);
                System.out.println(blog.getId()+" "+blog.getAuthername()+" "+blog.getTitle());
            }finally{
                session.close();
            }
                                                                                                                                   
        }
        public static void testAllBlog()
        {
            SqlSession session=sqlSessionFactory.openSession();
            try{
                IBlogDAO dao=session.getMapper(IBlogDAO.class);
                List<Blog>  blogs=dao.getAllBlog();
                System.out.println("编号 作者 标题");
                for(Blog blog:blogs)
                System.out.println(blog.getId()+" "+blog.getAuthername()+" "+blog.getTitle());
            }finally{
                session.close();
            }
        }
        public static void testBlogByTitle()
        {
            SqlSession session=sqlSessionFactory.openSession();
            try{
                IBlogDAO dao=session.getMapper(IBlogDAO.class);
                List<Blog>  blogs=dao.getBlogByTitle("%word%");
                System.out.println("编号 作者 标题");
                for(Blog blog:blogs)
                System.out.println(blog.getId()+" "+blog.getAuthername()+" "+blog.getTitle());
            }finally{
                session.close();
            }
        }
                                                                                                                               
        public static void testAddBlog()
        {
            SqlSession session=sqlSessionFactory.openSession();
            Blog blog=new Blog();
            blog.setTitle("chuntian");
            blog.setAuthername("xiaohua");
            blog.setDate("2013/12/25");
            blog.setContent("bushuangyayya");
            try{
                IBlogDAO dao=session.getMapper(IBlogDAO.class);
                dao.insertBlog(blog);
                session.commit();
            }finally{
                session.close();
            }
        }
                                                                                                                               
        public static void testDeleteBlog()
        {
            SqlSession session=sqlSessionFactory.openSession();
            try{
                IBlogDAO dao=session.getMapper(IBlogDAO.class);
                dao.deleteBlog(5);
                session.commit();
            }finally{
                session.close();
            }
        }
                                                                                                                               
        public static void testUpdateBlog()
        {
            SqlSession session=sqlSessionFactory.openSession();
            Blog blog=new Blog();
            blog.setId(6);
            blog.setTitle("daxuexiaoyuan");
            blog.setAuthername("xiaohua");
            blog.setDate("2013/2/25");
            blog.setContent("冷死了");
            try{
                IBlogDAO dao=session.getMapper(IBlogDAO.class);
                dao.updateBlog(blog);
                session.commit();
            }finally{
                session.close();
            }
        }
    }

    注意事项:

    1) 在利用注解配置映射器接口的时候,必须要通过

    sqlSessionFactory.getConfiguration().addMapper(IBlogDAO.class);来对给映射器接口注册,如果映射器接口中使用了@ResultMap注解,则由于已经在mybatis-config.xml配置了Mapper,则就不需要再次在代码中添加mapper。

    2)当方法有多个参数的时候,为了与SQL语句中的#{}对应,一般可以使用@Param("")来为每个参数命别名,使得该别名与#{}对应。当参数只有一个的时候,不需要别名。

    3 在进行更新删除添加的时候,如果传递的是一个实体对象,则SQL可以直接使用实体的属性。

    4)映射器接口调用SqlBuilder中的方法,都是将参数转换为Map中的key,可以在SqlBuilder的方法中利用Map来获取传递的参数值,进而进行逻辑操作判断。

    5)注解中对于返回多条记录的查询可以直接利用@Results和@Result来配置映射,或者利用@ResultMap来调用SQL配置文件中的ResultMap。

    --------------------------------------------------------------------------------------------------------------------

    (1)官方开发文档:http://ibatis.apache.org/docs/dotnet/datamapper/ch03s09.html

    <isGreaterThan prepend="AND" property="bo.lastUpdatedBy" compareValue="0">

    <![CDATA[(

    LAST_UPDATED_BY=#bo.lastUpdatedBy:NUMERIC#

    )]]>

    </isGreaterThan>

    在ibatis中,该属性用于判断传入的值是否大于0

    <isNotNull prepend="AND" property="bo.lastUpdateDate" >

    <![CDATA[(

    LAST_UPDATE_DATE=#bo.lastUpdateDate:TIMESTAMP#

    )]]>

    </isNotNull>

    在ibatis中,该属性用于判断传入的值是否为空

    IBATIS动态查询语句

    <!-- 在ibatis中使用安全的拼接语句,动态查询 ibatis比JDBC的优势之一,安全高效说明文字在注释中 --> <select id="selectA

    <!--

    在ibatis中使用安全的拼接语句,动态查询

    ibatis比JDBC的优势之一,安全高效

    说明文字在注释中

    -->

    <select id="selectAllProducts" parameterClass="Product" resultMap="ProductResult">

    select id,note from Product

    <dynamic prepend="WHERE">

    <!-- isNotNull判断参数是否存在,Integer类型 -->

    <isNotNull property="id">

    <!-- isGreaterThan判断参数是否大于compareValue,isGreaterEquals是大于等于 -->

    <isGreaterThan prepend=" and " property="id" compareValue="0">

    id = #id#

    </isGreaterThan>

    </isNotNull>

    <!-- isNotEmpty判断字串不为空,isEmpty可以判断字串为空 -->

    <isNotEmpty prepend=" and " property="note">

    <!-- 模糊查询不能用#,#在是用prepareStatement的?插入参数,$是文本替换 -->

    note like '%$note$%'

    </isNotEmpty>

    </dynamic>

    </select>

    用Map传参数

    <select id="selectAllProducts" parameterClass="java.util.HashMap" resultMap="ProductResult">

    select id,note from Product

    <dynamic prepend="WHERE">

    <!-- isPropertyAvailable判断属性是否有效 -->

    <isPropertyAvailable property="id">

    <isNotNull property="id">

    <!-- isLessThan判断参数是否小于compareValue,isLessEquals是小于等于 -->

    <isLessThan prepend=" and " property="id" compareValue="10">

    id = #id#

    </isLessThan>

    </isNotNull>

    </isPropertyAvailable>

    </dynamic>

    </select>

    <!--------------------------------------------------------------------几个常用属性-->

    <isPropertyAvailable> 属性是存在

    <isNotPropertyAvailable> 属性不存在

    <isNull> 属性值是null

    <isEmpty> 判断Collection.size<1或String.length()<1

    <isEqual> 等于

    <isNotEqual> 不等于

    <isGreaterThan> 大于

    <isGreaterEqual> 大于等于

    <isLessThan> 小于

    <isLessEqual> 小于等于


    ibatis中使用安全的拼接语句,动态查询,大于、小于、等于

    2012-11-26 17:38:13| 分类: 默认分类 |举报|字号 订阅
    在ibatis中使用安全的拼接语句,动态查询
    ibatis比JDBC的优势之一,安全高效
    说明文字在注释中

    <select id="selectAllProducts" parameterClass="Product" resultMap="ProductResult">
    select id,note from Product
    <dynamic prepend="WHERE">
    <!-- isNotNull判断参数是否存在,Integer类型 -->
    <isNotNull property="id">
    <!-- isGreaterThan判断参数是否大于compareValue,isGreaterEquals是大于等于 -->
    <isGreaterThan prepend=" and " property="id" compareValue="0">
    id = #id#
    </isGreaterThan>
    </isNotNull>
    <!-- isNotEmpty判断字串不为空,isEmpty可以判断字串为空 -->
    <isNotEmpty prepend=" and " property="note">
    <!-- 模糊查询不能用#,#在是用prepareStatement的?插入参数,$是文本替换 -->
    note like '%$note$%'
    </isNotEmpty>
    </dynamic>
    </select>

    用Map传参数

    <select id="selectAllProducts" parameterClass="java.util.HashMap" resultMap="ProductResult">
    select id,note from Product
    <dynamic prepend="WHERE">
    <!-- isPropertyAvailable判断属性是否有效 -->
    <isPropertyAvailable property="id">
    <isNotNull property="id">
    <!-- isLessThan判断参数是否小于compareValue,isLessEquals是小于等于 -->
    <isLessThan prepend=" and " property="id" compareValue="10">
    id = #id#
    </isLessThan>
    </isNotNull>
    </isPropertyAvailable>
    </dynamic>
    </select>
    /*动态SQL的参数有

    属性关键字
    含义

    <isEqual>
    如果参数相等于值则查询条件有效。

    <isNotEqual>
    如果参数不等于值则查询条件有效。

    <isGreaterThan>
    如果参数大于值则查询条件有效。

    <isGreaterEqual>
    如果参数等于值则查询条件有效。

    <isLessEqual>
    如果参数小于值则查询条件有效。如下所示:

    <isLessEqual prepend = ”AND” property = ”age” compareValue = ”18” >

    ADOLESCENT = ‘TRUE’

    </isLessEqual>

    <isPropertyAvailable>
    如果参数有使用则查询条件有效。

    <isNotPropertyAvailable>
    如果参数没有使用则查询条件有效。

    <isNull>
    如果参数为NULL则查询条件有效。

    <isNotNull>
    如果参数不为NULL则查询条件有效。

    <isEmpty>
    如果参数为空则查询条件有效。

    <isNotEmpty>
    如果参数不为空则查询条件有效。参数的数据类型为Collection、String 时参数不为NULL或“”。如下所示:

    <isNotEmpty prepend=”AND” property=”firstName” >

    FIRST_NAME=#firstName#

    </isNotEmpty>

    <isParameterPresent>
    如果参数类不为NULL则查询条件有效。

    <isNotParameterPresent>
    Checks to see if the parameter object is not present (null). Example Usage:

    <isNotParameterPresent prepend=”AND”>

    EMPLOYEE_TYPE = ‘DEFAULT’

    </isNotParameterPresent>


    在复杂查询过程中,我们常常需要根据用户的选择决定查询条件,这里发生变化的并不只是SQL 中的参数,包括Select 语句中所包括的字段和限定条件,都可能发生变化。典型情况,如在一个复杂的组合查询页面,我们必须根据用户的选择和输入决定查询的条件组合。

    一个典型的页面如下:

    对于这个组合查询页面,根据用户选择填写的内容,我们应为其生成不同的查询语句。如用户没有填写任何信息即提交查询请求,我们应该返回所有记录:
    Select * from t_user;
    如用户只在页面上填写了姓名“Erica”,我们应该生成类似:
    Select * from t_user where name like ‘%Erica%’ ;的SQL查询语句。
    如用户只在页面上填写了地址“Beijing”,我们应该生成类似:
    Select * from t_user where address like ‘%Beijing%”;的SQL。
    而如果用户同时填写了姓名和地址(”Erica”&’Beijing’),则我们应生成类似:
    Select * from t_user where name like ‘%Erica%’ and address like ‘%Beijing%”的SQL查询语句。

    对于ibatis 这样需要预先指定SQL 语句的ORM 实现而言,传统的做法无非通过if-else 语句对输入参数加以判定,然后针对用户选择调用不同的statement 定义。对于上面这种简单的情况(两种查询条件的排列组合,共4 种情况)而言,statement 的重复定义工作已经让人不厌其烦,而对于动辄拥有七八个查询条件,乃至十几个查询条件
    的排列组合而言,琐碎反复的statement定义实在让人不堪承受。

    考虑到这个问题,ibatis引入了动态映射机制,即在statement定义中,根据不同的
    查询参数,设定对应的SQL语句。
    还是以上面的示例为例:
    <select id="getUsers"
    parameterClass="user"
    resultMap="get-user-result">
    select
    id,
    name,
    sex
    from t_user
    <dynamic prepend="WHERE">
    <isNotEmpty prepend="AND" property="name">
    (name like #name#)
    </isNotEmpty>
    <isNotEmpty prepend="AND" property="address">
    (address like #address#)
    </isNotEmpty>
    </dynamic>
    </select>
    通过dynamic 节点,我们定义了一个动态的WHERE 子句。此WHERE 子句中将
    可能包含两个针对name 和address 字段的判断条件。而这两个字段是否加入检索取决于用户所提供的查询条件(字段是否为空[isNotEmpty])。
    对于一个典型的Web程序而言,我们通过HttpServletRequest获得表单中的字段名并将其设入查询参数,如:
    user.setName(request.getParameter("name"));
    user.setAddress(request.getParameter("address"));
    sqlMap.queryForList("User.getUsers", user);
    在执行queryForList("User.getUsers", user)时,ibatis 即根据配置文
    件中设定的SQL动态生成规则,创建相应的SQL语句。
    上面的示例中,我们通过判定节点isNotEmpty,指定了关于name 和address 属
    性的动态规则:
    <isNotEmpty prepend="AND" property="name">
    (name like #name#)
    </isNotEmpty>
    这个节点对应的语义是,如果参数类的"name"属性非空(isNotEmpty,即非空
    字符串””),则在生成的SQL Where字句中包括判定条件(name like #name#),其
    中#name#将以参数类的name属性值填充。
    Address属性的判定生成与name属性完全相同,这里就不再赘述。
    这样,我们通过在statement 定义中引入dynamic 节点,很简单的实现了SQL 判定子句的动态生成,对于复杂的组合查询而言,这将带来极大的便利。判定节点的定义可以非常灵活,我们甚至可以使用嵌套的判定节点来实现复杂的动态映射,如:
    <isNotEmpty prepend="AND" property="name">
    ( name=#name#
    <isNotEmpty prepend="AND" property="address">
    address=#address#
    </isNotEmpty>
    )
    </isNotEmpty>
    这段定义规定,只有用户提供了姓名信息时,才能结合地址数据进行查询(如果只提供地址数据,而将姓名信息忽略,将依然被视为全检索)。Dynamic节点和判定节点中的prepend属性,指明了本节点中定义的SQL子句在
    主体SQL中出现时的前缀。如:

    <dynamic prepend="WHERE">
    <isNotEmpty prepend="AND" property="name">
    (name like #name#)
    </isNotEmpty>
    <isNotEmpty prepend="AND" property="address">
    (address like #address#)
    </isNotEmpty>
    </dynamic>

    假设"name"属性的值为“Erica”, "address"属性的值为“Beijing”,则会生成类似下面的SQL子句(实际运行期将生成带占位符的PreparedStatement,之后再为其填充数据):

    WHERE (name like ‘Beijing’) AND (address like ‘Beijing’)

    其中WHERE 之后的语句是在dynamic 节点中所定义,因此以dynamic 节点的prepend设置("WHERE")作为前缀,而其中的”AND”,实际上是address属性所对应的isNotEmpty节点的prepend设定,它引领了对应节点中定义的SQL子句。至于name属性对应的isNotEmpty节点,由于ibatis会自动判定是否需要追加prepend前缀,这里(name like #name#)是WHERE 子句中的第一个条件子句,无需AND 前缀,所以自动省略。

    判定节点并非仅限于isNotEmpty,ibatis中提供了丰富的判定定义功能。判定节点分两类:

    ? 一元判定
    一元判定是针对属性值本身的判定,如属性是否为NULL,是否为空值等。
    上面示例中isNotEmpty就是典型的一元判定。

    一元判定节点有:

    节点名 描述
    <isPropertyAvailable> 参数类中是否提供了此属性
    <isNotPropertyAvailable> 与<isPropertyAvailable>相反
    <isNull> 属性值是否为NULL
    <isNotNull> 与<isNull>相反
    <isEmpty> 如果属性为Collection或者String,其size是否<1,如果非以上两种类型,则通过String.valueOf(属性值)
    获得其String类型的值后,判断其size是否<1<isNotEmpty> 与<isEmpty>相反。

    ? 二元判定
    二元判定有两个判定参数,一是属性名,而是判定值,如
    <isGreaterThan prepend="AND" property="age"
    compareValue="18">
    (age=#age#)
    </isGreaterThan>
    其中,property="age"指定了属性名”age”,compareValue=”18”指明了判定值为”18”。上面判定节点isGreaterThan 对应的语义是:如果age 属性大于18(compareValue),则在SQL中加入(age=#age#)条件。
    二元判定节点有:
    节点名 属性值与compareValues的关系
    <isEqual> 相等。
    <isNotEqual> 不等。
    <isGreaterThan> 大于
    <isGreaterEqual> 大于等于
    <isLessThan> 小于
    <isLessEqual> 小于等于


    为了防止SQL注入,iBatis模糊查询时也要避免使用$$来进行传值。下面是三个不同数据库的ibatis的模糊查询传值。
    mysql: select * from stu where name like concat('%',#name #,'%')

    oracle: select * from stu where name like '%'||#name #||'%'

    SQL Server:select * from stu where name like '%'+#name #+'%
    如:
    <!-- 用途:小二后台查询活动的数目 -->
    <!-- 频率:1000/天 -->
    <!-- 维护:刘飞 -->
    <select id="countActivitySearch" resultClass="java.lang.Long" parameterClass="actDO">
    <![CDATA[
    select count(id) from activity
    ]]>

    <dynamic prepend="WHERE">
    <isNotNull prepend=" AND " property="name">
    name LIKE CONCAT('%', #name#, '%')
    </isNotNull>
    <isNotNull prepend=" AND " property="itemId">
    itemId = #itemId#
    </isNotNull>
    <isNotNull prepend=" AND " property="itemName">
    itemName LIKE CONCAT('%', #itemName#, '%')
    </isNotNull>
    <isNotNull prepend=" AND " property="status">
    status = #status#
    </isNotNull>
    <isNotNull prepend=" AND " property="actStatus">
    actStatus = #actStatus#
    </isNotNull>
    <isNotNull prepend=" AND " property="domain">
    domain LIKE CONCAT('%', #domain#, '%')
    </isNotNull>
    </dynamic>

    </select>

    <!-- 用途:小二后台查询活动的列表 -->
    <!-- 频率:1000/天 -->
    <!-- 维护:刘飞 -->
    <select id="searchActivityForList" resultMap="actResult" parameterClass="actDO">
    <![CDATA[
    select * from activity
    ]]>

    <dynamic prepend="WHERE">
    <isNotNull prepend=" AND " property="name">
    name LIKE CONCAT('%', #name#, '%')
    </isNotNull>
    <isNotNull prepend=" AND " property="itemId">
    itemId = #itemId#
    </isNotNull>
    <isNotNull prepend=" AND " property="itemName">
    itemName LIKE CONCAT('%', #itemName#, '%')
    </isNotNull>
    <isNotNull prepend=" AND " property="status">
    status = #status#
    </isNotNull>
    <isNotNull prepend=" AND " property="actStatus">
    actStatus = #actStatus#
    </isNotNull>
    <isNotNull prepend=" AND " property="domain">
    domain LIKE CONCAT('%', #domain#, '%')
    </isNotNull>
    </dynamic>

    <![CDATA[
    order by starttime desc, createtime desc
    limit
    #startRow#, #perPageSize#
    ]]>
    </select>


    IBatis模糊查詢

    <!--
    在ibatis中使用安全的拼接语句,动态查询
    ibatis比JDBC的优势之一,安全高效
    说明文字在注释中
    -->


    <select id="selectAllProducts" parameterClass="Product" resultMap="ProductResult">
    select id,note from Product
    <dynamic prepend="WHERE">
    <!-- isNotNull判断参数是否存在,Integer类型 -->
    <isNotNull property="id">
    <!-- isGreaterThan判断参数是否大于compareValue,isGreaterEquals是大于等于 -->
    <isGreaterThan prepend=" and " property="id" compareValue="0">
    id = #id#
    </isGreaterThan>
    </isNotNull>
    <!-- isNotEmpty判断字串不为空,isEmpty可以判断字串为空 -->
    <isNotEmpty prepend=" and " property="note">
    <!-- 模糊查询不能用#,#在是用prepareStatement的?插入参数,$是文本替换 -->
    note like '%$note$%'
    </isNotEmpty>
    </dynamic>
    </select>

    用Map传参数

    <select id="selectAllProducts" parameterClass="java.util.HashMap" resultMap="ProductResult">
    select id,note from Product
    <dynamic prepend="WHERE">
    <!-- isPropertyAvailable判断属性是否有效 -->
    <isPropertyAvailable property="id">
    <isNotNull property="id">
    <!-- isLessThan判断参数是否小于compareValue,isLessEquals是小于等于 -->
    <isLessThan prepend=" and " property="id" compareValue="10">
    id = #id#
    </isLessThan>
    </isNotNull>
    </isPropertyAvailable>
    </dynamic>
    </select>
    <!--------------------------------------------------------------------几个常用属性-->

    <isPropertyAvailable> 属性是存在
    <isNotPropertyAvailable> 属性不存在
    <isNull> 属性值是null
    <isEmpty> 判断Collection.size<1或String.length()<1
    <isEqual> 等于
    <isNotEqual> 不等于
    <isGreaterThan> 大于
    <isGreaterEqual> 大于等于
    <isLessThan> 小于
    <isLessEqual>

    ---------------------

    Ibatis的动态查询使得数据操作变得非常的灵活,下次举出了常用的动态查询的属性信息: 
    Ibatis配置信息 

    Xml代码  收藏代码
    1. <!-- Dynamic Sql -->  
    2.   <typeAlias alias="Student" type="com.ibatis.Student" />  
    3.     <typeAlias alias="StudentDTO" type="com.ibatis.StudentDTO" />  
    4.     <select id="dynamicGetStudent" parameterClass="StudentDTO"  
    5.         resultClass="Student">  
    6.         select *  
    7.         from student  
    8.         <dynamic prepend="WHERE">  
    9.             <isNotEqual prepend="AND" property="sid" compareValue="0">  
    10.                 sid = #sid#  
    11.             </isNotEqual>  
    12.               
    13.             <isNotNull prepend="AND" property="sname">  
    14.                 sname = #sname#  
    15.             </isNotNull>  
    16.         </dynamic>  
    17.         <dynamic prepend="order by">  
    18.             <isParameterPresent>  
    19.                 <isEqual prepend="order by" property="sort" compareValue="1">  
    20.                     sname desc,socre  
    21.                 </isEqual>  
    22.                   
    23.                 <isEqual prepend="order by" property="sort" compareValue="2">  
    24.                     sname asc,socre  
    25.                 </isEqual>  
    26.             </isParameterPresent>  
    27.         </dynamic>  
    28.     </select>  


    Student的信息 

    Java代码  收藏代码
    1. package com.ibatis;  
    2.   
    3. import java.util.Date;  
    4.   
    5. public class Student {  
    6.     private int sid;  
    7.     private String sname;  
    8.     private String major;  
    9.     private Date birth;  
    10.     private int socre;  
    11.     public int getSid() {  
    12.         return sid;  
    13.     }  
    14.     public void setSid(int sid) {  
    15.         this.sid = sid;  
    16.     }  
    17.     public String getSname() {  
    18.         return sname;  
    19.     }  
    20.     public void setSname(String sname) {  
    21.         this.sname = sname;  
    22.     }  
    23.     public String getMajor() {  
    24.         return major;  
    25.     }  
    26.     public void setMajor(String major) {  
    27.         this.major = major;  
    28.     }  
    29.     public Date getBirth() {  
    30.         return birth;  
    31.     }  
    32.     public void setBirth(Date birth) {  
    33.         this.birth = birth;  
    34.     }  
    35.     public int getSocre() {  
    36.         return socre;  
    37.     }  
    38.     public void setSocre(int socre) {  
    39.         this.socre = socre;  
    40.     }  
    41.       
    42.     @Override  
    43.     public String toString() {  
    44.         String content = "Sid="+this.sid+" "+"Sname="+this.sname+" "+this.birth.toLocaleString();  
    45.         return content;  
    46.     }  
    47.       
    48. }  


    StudentDTO的信息 

    Java代码  收藏代码
    1. package com.ibatis;  
    2.   
    3. import java.util.Date;  
    4.   
    5. public class StudentDTO {  
    6.     private int sid;  
    7.     private String sname;  
    8.     private String major;  
    9.     private Date birth;  
    10.     private int socre;  
    11.     private int sort;  
    12.     public int getSort() {  
    13.         return sort;  
    14.     }  
    15.     public void setSort(int sort) {  
    16.         this.sort = sort;  
    17.     }  
    18.     public int getSid() {  
    19.         return sid;  
    20.     }  
    21.     public void setSid(int sid) {  
    22.         this.sid = sid;  
    23.     }  
    24.     public String getSname() {  
    25.         return sname;  
    26.     }  
    27.     public void setSname(String sname) {  
    28.         this.sname = sname;  
    29.     }  
    30.     public String getMajor() {  
    31.         return major;  
    32.     }  
    33.     public void setMajor(String major) {  
    34.         this.major = major;  
    35.     }  
    36.     public Date getBirth() {  
    37.         return birth;  
    38.     }  
    39.     public void setBirth(Date birth) {  
    40.         this.birth = birth;  
    41.     }  
    42.     public int getSocre() {  
    43.         return socre;  
    44.     }  
    45.     public void setSocre(int socre) {  
    46.         this.socre = socre;  
    47.     }  
    48.       
    49.     @Override  
    50.     public String toString() {  
    51.         String content = "Sid="+this.sid+" "+"Sname="+this.sname+" "+this.birth.toLocaleString();  
    52.         return content;  
    53.     }  
    54.       
    55. }  


    Java中的调用信息 

    Java代码  收藏代码
    1. @SuppressWarnings("unchecked")  
    2.     public static void main(String[] args) {  
    3.         List<Student> list = dao.dynamicGetStudent(studentDTO);  
    4.         for(Student student : list){  
    5.             System.out.println("name:"+student.getSname());  
    6.         }  
    7.         System.out.println("size:"+list.size());  
    8.     }  
    9. @Override  
    10.     public List dynamicGetStudent(StudentDTO studentDTO) {  
    11.         List result = null;  
    12.         try {  
    13.             result = sqlMapClient.queryForList("dynamicGetStudent",studentDTO);  
    14.         } catch (SQLException e) {  
    15.             // TODO Auto-generated catch block  
    16.             e.printStackTrace();  
    17.         }  
    18.         return result;  
    19.     }  


    动态查询中的常用属性: 

    属性关键字 含义
    <isEqual> 如果参数相等于值则查询条件有效
    <isNotEqual> 如果参数不等于值则查询条件有效
    <isGreaterThan> 如果参数大于值则查询条件有效
    <isGreaterEqual> 如果参数等于值则查询条件有效
    <isLessEqual> 如果参数小于值则查询条件有效。如下所示:<isLessEqual prepend = ”AND” property = ”age” compareValue = ”18” >ADOLESCENT = ‘TRUE’</isLessEqual>
    <isPropertyAvailable> 如果参数有使用则查询条件有效。
    <isNotPropertyAvailable> 如果参数没有使用则查询条件有效
    <isNull> 如果参数为NULL则查询条件有效
    <isNotNull> 如果参数不为NULL则查询条件有效
    <isEmpty> 如果参数为空则查询条件有效
    <isNotEmpty> 如果参数不为空则查询条件有效
    <isParameterPresent> 如果参数类不为NULL则查询条件有效
    <isNotParameterPresent> Checks to see if the parameter object is not present (null). Example Usage
  • 相关阅读:
    素数路径Prime Path POJ3126 素数,BFS
    Fliptile POJ3279 DFS
    Find the Multiple POJ1426
    洗牌Shuffle'm Up POJ3087 模拟
    棋盘问题 POJ1321 DFS
    抓住那只牛!Catch That Cow POJ3278 BFS
    Dungeon Master POJ2251 三维BFS
    Splitting into digits CodeForce#1104A
    Ubuntu下手动安装Nvidia显卡驱动
    最大连续子序列和
  • 原文地址:https://www.cnblogs.com/fx2008/p/4039653.html
Copyright © 2011-2022 走看看