MyBatis中#{}占位符与${}拼接符的用法说明

1、关于#{}占位符

先来看以下的示例,该示例是MyBatis中的SQL映射配置文件(Mapper配置文件),在该配置中使用了#{}占位符。

<?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="test">
  <!-- 根据用户编号,查询单个用户实体 -->
  <select id="findUserById" parameterType="int" resultType="com.pjb.mybatis.po.User">
    SELECT * FROM tb_user WHERE id = #{id}
  </select>

  <!-- 新增用户 -->
  <insert id="insertUser" parameterType="com.pjb.mybatis.po.User">
    INSERT INTO tb_user(user_name,blog_url,remark)
    VALUES(#{userName},#{blogUrl},#{remark});
  </insert>
</mapper>

在SQL映射配置文章中,输入参数需要用占位符来标识对应的位置。

在传统的JDBC编程中,占位符用“?”来标识,然后在加载SQL之前按照“?”的位置设置参数。

而“#{}”在MyBatis中也代表一种占位符,该符号接受输入参数,在大括号中编写参数名称来接受对应参数。

“#{}”接受的输入参数的类型可以是简单类型、普通JavaBean或者HashMap。

当接受简单类型时,“#{}”中可以写“value”或者其他任意名称。

如果接受的是JavaBean,它会通过OGNL读取对象中的属性值。

2、关于${}拼接符

再来看以下的示例,该示例是MyBatis中的SQL映射配置文件(Mapper配置文件),在该配置中使用了${}拼接符。

<?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="test">
  <!-- 根据用户名称,模糊查询用户列表 -->
  <select id="findUserByUserName" parameterType="java.lang.String" resultType="com.pjb.mybatis.po.User">
    SELECT * FROM tb_user WHERE user_name LIKE '%${value}%'
  </select>
</mapper>

在SQL映射配置文件中,有时候需要拼接SQL语句。例如在模糊查询的时候,就需要在查询条件的两侧拼接两个“%”字符串,这个时候如果使用“#{}”占位符是不行的。在MyBatis中,“${}”在SQL配置文件中代表一个“拼接符号”,可以在原有SQL语句上拼接新的符合SQL语法的语句。

但是要注意的是,使用“${}”拼接的SQL语句,会引起SQL注入,所以一般不建议使用“${}”。

“${}”接受输入参数的类型可以是简单类型、普通JavaBean或者HashMap。

当接受简单类型时,“${}”中只能写“value”,而不能写其他任意名称。

如果接受的是JavaBean,它会通过OGNL读取对象中的属性值。

另外,在MyBatis 3.4.2之后,还可以在“${}”拼接符中设置一个默认值,格式如下:

${属性:默认值}

即在所需引入的属性名的后面添加“:”引号,然后紧跟着填写属性不存在或为空时的默认值。

【示例】设置“${}”拼接符的默认值。

(1)创建数据库连接的属性文件(db.properties)

在src目录下创建db.propertie属性文件,并使用“#”符号将属性项jdbc.username和jdbc.password注释掉,表示这两个属性项未进行配置。

jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/db_admin?useSSL=false&amp
#jdbc.username=root
#jdbc.password=123456

(2)启用拼接符默认值的配置

要使用“${}”拼接符中设置一个默认值,需要在properties标签中设置启用拼接符默认值的配置项。

在MyBatis配置文件(mybatis-config.xml)中,使用<properties>标签加载数据库连接属性文件(db.properties),并在该标签中设置启用拼接符默认值的配置项,该配置如下:

<!-- 加载用于数据库配置的属性文件 -->
<properties resource="db.properties">
  <!-- 启用默认值特性,这样${}拼接符才可以设置默认值 -->
  <property name="org.apache.ibatis.parsing.PropertyParser.enable-default-value" value="true"/>
</properties>

注意:在MyBatis配置文件(mybatis-config.xml)中,<properties>标签的配置必须写在<settings>标签的上面,因为MyBatis中的配置,不但有类型限制,还有顺序限制。

必须按照:<properties>、<settings>、<typeAliases>、<typeHandlers>、…顺序排放。

(3)编写数据库配置信息,并使用“${}”拼接符的默认值。

说明:

由于在db.propertie属性文件中,已经将jdbc.username和jdbc.password属性项注释掉了,然后在上面的配置信息中,给username和password配置项中的“${}”拼接符中设置默认值,这样程序在启动时,就会读取默认值。

补充:MyBatis映射——SQL占位符及传参

简介

本篇主要讲述Mybatis映射SQL通过#{}获取引入类型参数的属性值及通过@Param注解指定名称传参。

关于占位符与字符拼接:

占位符:占位符就是在某个地方占领一个位置,把它单独作为某个东西,比如这里就是把它作为 值。

#{}表示一个占位符号,通过#{}可以实现 preparedStatement 向占 位符中设置值, 自动进行 java

类型和 jdbc 类型转换。#{}可以有效防止 sql 注入。 #{}可以接 收简单类型值或 pojo 属性值。 如果 parameterType 传输单个简单类型值,#{} 括号中可以是 value 或其它名称。

字符拼接:字符拼接就是简单的对字符串拼接。没有特殊的其它含义。

表 示 拼 接 s q l 串 , 通 过 可 以 将 p a r a m e t e r T y p e 传 入 的 内 容 拼 接 在 s q l 中 且 不 进 行 j d b c 类 型 转 换 , 可 以 将 p a r a m e t e r T y p e 传 入 的 内 容 拼 接 在 s q l 中 且 不 进 行 j d b c 类 型 转 换 , 可 以 接 收 简 单 类 型 值 或 p o j o 属 性 值 , 如 果 p a r a m e t e r T y p e 传 输 单 个 简 单 类 型 值 , {}表示拼接 sql 串,通过可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,{}可以接收简单类型值或 pojo 属性值,如果 parameterType 传输单个简单类型值,表示拼接sql串,通过可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,可以将parameterType传入的内容拼接在sql中且不进行jdbc类型转换,可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,{}括号中只能是 value。

关于@Param:

在用注解来简化xml配置的时候(比如Mybatis的Mapper.xml映射文件中的sql参数引入);

@Param注解的作用是给参数命名,参数命名后就能根据名字得到参数值,正确的将参数传入sql语句中(一般通过#{}的方式,${}会有sql注入的问题)。

#{}: 解析为一个 JDBC 预编译语句(prepared statement)的参数标记符,一个 #{ } 被解析为一个参数占位符 。 ${}: 仅仅为一个纯碎的 string 替换,在动态 SQL 解析阶段将会进行变量替换。

MyBatis 的真正强大在于它的映射语句

Mapper.xml映射文件中定义了操作数据库的sql,每个sql是一个statement,映射文件是mybatis的核心。

映射文件中有很多属性,常用的就是parameterType(输入类型)、resultType(输出类型)、resultMap()、rparameterMap()。

实例步骤

先建好实体类Teacher和接口类

Teacher类

package com.lanou3g.mybaties.bean;
import lombok.Getter;
import lombok.Setter;
@Getter
@Setter
public class Teacher {
  private Integer id;
  private String tname;
  private Integer age;
  private Integer salary;
public Teacher(){}
  @Override
  public String toString() {
    return "Teacher{" +
        "id=" + id +
        ", tname='" + tname + '\'' +
        ", salary=" + salary +
        ", remark='" + remark + '\'' +
        ", age=" + age +
        '}';
  }
  private String remark;
  public Teacher(Integer id, String tname, Integer age, Integer salary, String remark) {
    this.id = id;
    this.tname = tname;
    this.age = age;
    this.salary = salary;
    this.remark = remark;
  }
  public Teacher(Integer id) {
    this.id = id;
  }
}

接口类

package com.lanou3g.mybaties.dao;
import com.lanou3g.mybaties.bean.Teacher;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface TeacherDao {
  List<Teacher> queryAll();
  Teacher queryById(int id);
  Teacher queryByIdAndAge(@Param("id") int id, @Param("age") int age);
  int insertTeacher(Teacher teacher);
  int insertTeacherByParam(@Param("tname") String tname, @Param("age") int age);
  int updateTeacherById(Teacher teacher);
  int deleteTeacherById(int id);
}

主要还是xml配置文件的配置,下面是 mybatis_conf.xml文件,它主要引入外部的properties文件(用于配置数据源)、定义类型别名(全局)、配置多套环境的数据库连接参数及引入哪些Mapper映射文件等

mybatis_conf.xml配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
    PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
    "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
  <properties resource="jdbc.properties" />
  <settings>
  <setting name="mapUnderscoreToCamelCase" value="false"/>
  </settings>
  <typeAliases>
    <!--这样我们就可以在mybatis的的上下文中使用Teacher来代替全路径名了,减少配置的复杂度。 -->
    <typeAlias type="com.lanou3g.mybaties.bean.Teacher" alias="Teacher" />
  <!--default属性,这个属性作用就是指定当前情况下使用哪个数据库配置,
  也就是使用哪个<environment>节点的配置,
  default的值就是配置的<environment>标签元素的id值。-->
  <environments default="test">
    <environment id="test">
      <!-- 事务管理器:
     MANAGED: 这个配置就是告诉mybatis不要干预事务,具体行为依赖于容器本身的事务处理逻辑。
     JDBC: 这个配置就是直接使用了 JDBC 的提交和回滚设置,它依赖于从数据源得到的连接来管理事务作用域。
    -->
      <!-- 使用jdbc事务管理 -->
      <transactionManager type="JDBC"/>
      <!-- 数据库连接池 -->
      <dataSource type="POOLED">
        <property name="driver" value="${jdbc.driver}"/>
        <property name="url" value="${jdbc.url}"/>
        <property name="username" value="${jdbc.user}"/>
        <property name="password" value="${jdbc.password}"/>
      </dataSource>
    </environment>
  </environments>
  <!--<mappers>用来在mybatis初始化的时候,告诉mybatis需要引入哪些Mapper映射文件。-->
  <mappers>
    <!--通过class属性指定mapper接口名称,此时对应的映射文件必须与接口位于同一路径下,
    并且名称相同-->

    <!--通过resource属性引入classpath路径的相对资源-->
    <mapper resource="mapper/TeacherMapper.xml" />

  </mappers>
</configuration>

TeacherMapper.xml映射文件

<?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">
<!-- namespace对应空Dao接口的全名 -->
<!--namespace属性
在MyBatis中,Mapper中的namespace用于绑定Dao接口的,即面向接口编程。
它的好处在于当使用了namespace之后就可以不用写接口实现类,
业务逻辑会直接通过这个绑定寻找到相对应的SQL语句进行对应的数据处理-->
<mapper namespace="com.lanou3g.mybaties.dao.TeacherDao">
  <!-- 此处的id是查询语句的名称,对应接口中的方法名 -->
  <!--指定 resultType 返回值类型时 Teacher 类型的,
    Teacher 在这里是一个别名,代表的是 com.lanou3g.mybaties.bean.Teacher
    对于引用数据类型,都是将大写字母转小写,比如 HashMap 对应的别名是 'hashmap'
    基本数据类型考虑到重复的问题,会在其前面加上 '_',比如 byte 对应的别名是 '_byte'
-->
  <select id="queryAll" resultType="Teacher">
    <!--
     通过 resultType 指定查询的结果是 Teacher 类型的数据
     只需要指定 resultType 的类型,MyBatis 会自动将查询的结果映射成 JavaBean 中的属性
      -->
  select * from teacher;
 </select>
  <!-- 带一个简单类型的参数, 这种情况下parameterType属性可以省略,
  mybatis可以自动推断出类型 -->
  <select id="queryById" resultType="Teacher">
        select * from teacher where id = #{id};
  </select>
  <!-- 带两个参数,需要在接口中通过@Param注解指定名称(因为编译时参数名不会保留) -->
  <select id="queryByIdAndAge" resultType="Teacher">
    select * from teacher where id = #{id} and age &lt;= #{age};
  </select>
  <!-- insert、update、delete的返回值都是int(影响行数) -->
  <!-- 自定义类型参数,通过#{属性名}可以直接获取引入类型参数的属性值 -->
  <insert id="insertTeacher" parameterType="Teacher">
    insert into teacher(tname) values (#{tname});
  </insert>
  <insert id="insertTeacherByParam">
    insert into teacher(tname, age) values (#{tname}, #{age});
  </insert>
  <update id="updateTeacherById" parameterType="Teacher">
    update teacher set tname = #{tname}, age = #{age} where id = #{id}
  </update>
  <delete id="deleteTeacherById">
    delete from teacher where id = #{id};
  </delete>
</mapper>

前面完成后,就要测试了。不过在测试时需要实例化创建对象,因要实现多个方法,在这先建MyBatisTools.java工具类,其主要进行封装Mybatis初始化操作,要求支持创建多env sqlSessionFactory,整个应用生命周期内相同env的sqlSessionFactory对象只有一个(这个类不要过于探究,会用即可)。

MyBatisTools.java

package com.lanou3g.mybaties;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.ExecutorType;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.util.concurrent.ConcurrentHashMap;
/**
 * 封装Mybatis初始化操作
 * 支持创建多env sqlSessionFactory
 * 整个应用生命周期内相同env的sqlSessionFactory对象只有一个
 */
@Slf4j
public class MyBatisTools {
  private static ConcurrentHashMap<String, SqlSessionFactory> factoryMap = new MyConcurrentHashMap();
  private static MyBatisTools myBatisTools;
  private MyBatisTools() {}
  public static MyBatisTools getInstance() {
    if(myBatisTools == null) {
      synchronized (MyBatisTools.class) {
        if(myBatisTools == null) {
          myBatisTools = new MyBatisTools();
        }
      }
    }
    log.debug("当前一共有: " + factoryMap.size() +"个SqlSessionFactory实例");
    log.debug("他们分别是: " + factoryMap);
    return myBatisTools;
  }
  public SqlSessionFactory getSessionFactory(String env) {
    try {
      // 1. 读入配置文件
      InputStream in = Resources.getResourceAsStream("mybatis_conf.xml");
      // 2. 构建SqlSessionFactory(用于获取sqlSession)
      SqlSessionFactory sessionFactory = null;
      synchronized (factoryMap) {
        if(factoryMap.containsKey(env)) {
          return factoryMap.get(env);
        } else {
          sessionFactory = new SqlSessionFactoryBuilder().build(in, env);
          factoryMap.put(env, sessionFactory);
        }
      }
      return sessionFactory;
    } catch (Exception e) {
      log.error("初始化SqlSessionFactory失败", e);
      return null;
    }
  }
  public SqlSession openSession() {
    return getSessionFactory(null).openSession();
  }
  public SqlSession openSession(boolean autoCommit) {
    return getSessionFactory(null).openSession(autoCommit);
  }
  public SqlSession openSession(ExecutorType executorType, boolean autoCommit) {
    return getSessionFactory(null).openSession(executorType, autoCommit);
  }
}
/**
 * 继承原生ConcurrentHashMap,处理null key问题
 */
class MyConcurrentHashMap extends ConcurrentHashMap {
  @Override
  public Object put(Object key, Object value) {
    if(key == null) {
      key = "null";
    }
    return super.put(key, value);
  }
  @Override
  public boolean containsKey(Object key) {
    if(key == null) {
      key = "null";
    }
    return super.containsKey(key);
  }
  @Override
  public Object get(Object key) {
    if(key == null) {
      key = "null";
    }
    return super.get(key);
  }
}

最后就是测试,在AppTest类测试

AppTest

@Slf4j
public class AppTest
{
  /**
   * Rigorous Test :-)
   */
  TeacherDao teacherDao = null;
  @Before
  public void setUp() {
    teacherDao = MyBatisTools.getInstance().openSession(true).getMapper(TeacherDao.class);
  }
  /**
   * 练习查询多个库(用到了多环境配置)
   */
  @Test
  public void textqueryById(){
    Teacher teacher=teacherDao.queryById(1);
    System.out.println(teacher);
  }
  @Test
  public void text(){
    List<Teacher> teachers=teacherDao.queryAll();
    System.out.println(teachers);
  }
  /**
   * 多个参数查询语句
   */
  @Test
  public void testQueryByIdAndAge() {
    Teacher teacherList = teacherDao.queryByIdAndAge(1, 65);
    log.info("查询结果:" + teacherList);
  }
  @Test
  public void testInsert() {
    // 新增Teacher表
    System.out.println("--------------插入前:");
    List<Teacher> teacherList = teacherDao.queryAll();
    System.out.println(teacherList);
    int ret = teacherDao.insertTeacher(new Teacher("好人"));
    log.info("影响的行数: " + ret);
    // 比较low的写法(不推荐)
    //int ret = teacherDao.insertTeacherByParam("哈哈哥", 99);
    //log.info("影响的行数: " + ret);
    System.out.println("--------------插入后:");
    teacherList = teacherDao.queryAll();
    System.out.println(teacherList);
  }
  @Test
  public void testUpdate() {
    Teacher teacher = new Teacher();
    teacher.setId(6);
    teacher.setAge(99);
    teacher.setTname("乔巴老师");
    int rows = teacherDao.updateTeacherById(teacher);
    log.info("更新行数:" + rows);
  }
  @Test
  public void testDelete() {
    int rows = teacherDao.deleteTeacherById(13);
    log.info("删除行数:" + rows);
  }
  @Test
  public void testinsertTeacherByParam(){
int row=teacherDao.insertTeacherByParam("hh",22);
    System.out.println(row);
  }
}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持我们。如有错误或未考虑完全的地方,望不吝赐教。

(0)

相关推荐

  • Mybatis打印替换占位符后的完整Sql教程

    利用mybtis插件打印完整的sql,将占位符?替换成实际值 import org.apache.ibatis.cache.CacheKey; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.mapping.BoundSql; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.mapping.Paramete

  • Spring及Mybatis整合占位符解析失败问题解决

    问题:写了一个新的dao接口,进行单元测试时提示: Initialization of bean failed; nested exception is org.springframework.beans.TypeMismatchException: Failed to convert property value of type 'java.lang.String' to required type 'int' for property 'maxActive'; nested exceptio

  • 在MyBatis中使用 # 和 $ 书写占位符的区别说明

    #将传入的数据都当成一个字符串,会对传入的数据自动加上引号: $将传入的数据直接显示生成在SQL中 注意:使用 $ 占位符可能会导致SQL注入攻击,能用#的地方就不要使用 $ 写order by 子句的时候应该用 $ 而不是# 补充知识:mybatis 中生成的字段不带引号 #{}和${} 最近在用mybatis,之前用过ibatis,总体来说差不多,不过还是遇到了不少问题,再次记录下, 比如说用#{},和 ${}传参的区别, 使用#传入参数是,sql语句解析是会加上"",比如 sel

  • java字符串中${}或者{}等的占位符替换工具类

    正如标题所述,这是一个替换java字符串中${}或者{}等占位符的工具类,其处理性能比较令人满意.该类主要通过简单的改写myatis框架中的GenericTokenParser类得到.在日常开发过程中,可以将该类进行简单的改进或封装,就可以用在需要打印日志的场景中,现在张贴出来给有需要的人,使用方式参考main方法,不再赘述! public class Parser { /** * 将字符串text中由openToken和closeToken组成的占位符依次替换为args数组中的值 * @par

  • Mybatis日志参数快速替换占位符工具的详细步骤

    Mybatis log printf工具网页地址: http://www.feedme.ltd/log.html Mybatis执行的sql的打印格式为: 2020-08-04 09:16:44 -DEBUG - [io-8888-exec-5] .mapper.operation.OperationMapper.insert.        debug 145 : ==>  Preparing: INSERT INTO tulu.t_log_operation (id, module, mod

  • 解决myBatis中删除条件的拼接问题

    今天刚刚学习了mybatis,做了简单的对数据库的增删改查.在进行删除操作时,单条删除时很简单,但是批量删除的时候拼接删除条件却有些麻烦,现记录一下做法. Sql语句中,当删除条件并不唯一的时候,我们有两种删除的sql语句,一种使用or拼接where中的条件,例如delete from 表名where 条件1 or 条件2,另一种是使用in 例如delete from 表名where 元素in( ) 利用第一种删除语句在mybatis中的mapping.xml中进行拼接: 利用第二种删除语句在m

  • MyBatis中#{}占位符与${}拼接符的用法说明

    1.关于#{}占位符 先来看以下的示例,该示例是MyBatis中的SQL映射配置文件(Mapper配置文件),在该配置中使用了#{}占位符. <?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mappe

  • MyBatis中正则使用foreach拼接字符串

    目录 正则使用foreach拼接字符串 foreach标签拼接多字段in ,和union 正则使用foreach拼接字符串 业务需求:使用代理名字查询该代理的所有下级代理 数据库: pid存储的是该字段的上级集合 实现步骤: 1.先用名字在用户表中查询出用户id集合 2.在数据库中判断字段pids中是否出现这些id,再去重 -------上重点-------: 在mybatis中写拼接这个sql碰到了很多坑,记录下这个教训: 1.foreach拼接字符串,开头和结尾用单引号,否则报错 2.中括号

  • 深入理解结构体中占位符的用法

    复制代码 代码如下: typedef union{    struct x{    char a1 : 2;    char b1 : 3;    char c1 : 3;    }x1;    char c;}my_un;int main(){    my_un a;    a.c = 100;    printf("%d/n",a.x1.c1);    printf("%d/n",sizeof(my_un)); return 0;} 输出结果:31即第一个是3,

  • java开发MyBatis中常用plus实体类注解符详解

    目录 mybatis-plus常用注解符 1. 表名注解(@TableName) 2. 主键注解(@TableId) 3. 属性注解(@TableField) mybatis-plus常用注解符 1. 表名注解(@TableName) 作用:实体类和数据库中表建立对应关系:如 @TableName("thotset") public class HotsetEntity implements Serializable { private static final long serial

  • java泛型中占位符T和?有什么区别

    泛型中占位符T和?有什么区别?这是一个好问题,有的人可能弄不清楚,所以我们这里简单的演示一下,相信大家一定能弄清楚的! 先上两段代码: public static <T> void show1(List<T> list){ for (Object object : list) { System.out.println(object.toString()); } } public static void show2(List<?> list) { for (Object

  • 深入了解Golang中占位符的使用

    目录 基本常见常用的占位符 较少使用的占位符 进制和浮点使用占位符 指针占位符 基本常见常用的占位符 %s %d %v , %v+ , %+v %T , %q 写一个 demo 来看看上面占位符的效果,具体都是啥样的 type Animal struct { hobby string } func main() { name := "xiaomotong" age := 19 hh := Animal{"basketball"} fmt.Printf("n

  • SQL中使用ESCAPE定义转义符详解

    使用ESCAPE定义转义符 在使用LIKE关键字进行模糊查询时,"%"."_"和"[]"单独出现时,会被认为是通配符.为了在字符数据类型的列中查询是否存在百分号 (%).下划线(_)或者方括号([])字符,就需要有一种方法告诉DBMS,将LIKE判式中的这些字符看作是实际值,而不是通配符.关键字 ESCAPE允许确定一个转义字符,告诉DBMS紧跟在转义字符之后的字符看作是实际值.如下面的表达式: LIKE '%M%' ESCAPE 'M' 使用E

  • C#中const 和 readonly 修饰符的用法详解

    1. 只有C#内置类型(int,double,long等)可以声明为const;结果.类和数组不能声明为const. 2. readonly 是在字段上使用的修饰符,直接以类名.字段访问. 3. const 必须在申明中初始化.之后不能再修改. 4. readonly可以在申明中初始化,也可以在构造函数中初始化,其它情况不能修改. namespace const_and_readonly { class Program { static void Main(string[] args) { Co

随机推荐