Mysql和Mybatis常用语句

0 高阶特性

c. mybatis的插件(链)(InterceptorChain)

org.apache.ibatis.plugin.InterceptorChain

Mybatis提供了可供拦截和定制化的钩子,一些三方插件,比如mybatis plus、pagehelper都是借此插件,借此插件,还可以打印sql执行时间、限制sql语句的长度,等等,可以玩出花来

b.如何在mybatis.xml中使用定制的动态sql语句

mybatis.xml的sql标签支持 OGNL语法,可 扩展原生的 = != and等简单操作符
<if test="@com.yourpackage.MyBatisUtils@matches(code, '.*aaaaaa.*')">

a. 如何从mysql table中读取到sql模板(动态sql)用来生成可执行sql

mybatis的sql provider 提供了扩展钩子可以实现
核心的代码片段:

@Mapper
public interface PersonMapper {
    @SelectProvider(type = SqlProvider.class, method = "selectPersonSql")
    List<Person> selectPerson(@Param("firstName") String firstName, @Param("lastName") String lastName, @Param("extraCondition") String extraCondition);

    class SqlProvider {
        private static SqlProviderService sqlProviderService;
        @Autowired
        public void setSqlProviderService(SqlProviderService sqlProviderService) {
            SqlProvider.sqlProviderService = sqlProviderService;
        }
        public static String selectPersonSql(@Param("firstName") String firstName, @Param("lastName") String lastName, @Param("extraCondition") String extraCondition) {
            // Fetch the SQL template from the service
            String sqlTemplate = sqlProviderService.getSql("selectPersonSql", extraCondition);
           // Return the modified SQL template
            return sqlTemplate;
        }
    }
}

1 MyBatisExceptionTranslator

可学习的方法命名,这个接口是用来 将mybatis 抛出的异常,统一封装成spring的DataAccessException

2 mybatis 的 aggressiveLazyLoading lazyLoadingEnabled

todo
TODO:细节

3 mysql字符集和校对规则

假如有这么一个建表语句:

`remark` varchar(256) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL COMMENT '备注'
  • CHARACTER SET utf8mb4 : 表示字符集是utf8mb4
  • COLLATE utf8mb4_bin :表示校对规则是 utf8mb4_bin (区分大小写),utf8mb4_general_ci (不区分大小写)

4 _parameter

mybatis 有 2个内置参数, 其中一个是 _databaseId,基本没啥用; 另一个 _parameter代表整个参数.

对于单个参数:_parameter就是这个参数
对于多个参数:参数会被封装为一个map, _parameter就是代表这个map

<!-- List<Employee> getEmployees(Employee employee); -->
      <select id="getEmployees" resultType="com.hand.mybatis.bean.Employee">
          SELECT * FROM emp
          <if test="_parameter!=null">      _parameter相当于传入的参数employee,判断employee是否为空,若不为空则执行where条件
           where ename=#{_parameter.eName}  
          </if>
      </select>

5 MySQL如何批量修改行?

CREATE TABLE employees (
    id INT PRIMARY KEY AUTO_INCREMENT,
    employee_id INT UNIQUE,
    name VARCHAR(100),
    department VARCHAR(100),
    salary DECIMAL(10, 2),
    version INT DEFAULT 1,
    UNIQUE KEY (employee_id)
);

INSERT INTO employees (employee_id, name, department, salary, version)
VALUES (101, 'John Doe', 'Engineering', 50000.00, 1)
ON DUPLICATE KEY UPDATE 
    name = VALUES(name),
    department = VALUES(department),
    salary = VALUES(salary),
    version = version + 1;

注意这里的版本号,最后一行,并不是`version = values(version) + 1;` ,而是
`version = version + 1;` 这是对当前行的`version`+ 1VALUES (101, 'John Doe', 'Engineering', 50000.00, 1)`version`=1 的只作为插入成功后`version`的初始值,可将其改为任意整数。
 
这有一个 副作用,如果某行已经存在,那么affected rows总是2;只有在新增成功时才是 1;这可能对需要根
据 affected rows做业务判断造成不便

或者:

UPDATE table
SET column2 = (CASE column1 WHEN 1 THEN 'val1'
                 WHEN 2 THEN 'val2'
                 WHEN 3 THEN 'val3'
         END)
WHERE column1 IN(1, 2 ,3);

参考

6 How to INSERT If Row Does Not Exist (UPSERT) in MySQL

  • INSERT IGNORE
  • REPLACE INTO
  • INSERT… ON DUPLICATE KEY UPDATE

一定要注意: ‘REPLACE INTO’ 和 ‘INSERT… ON DUPLICATE KEY UPDATE’ 是不同的!!!
前者: 如果当前存在, 就删除它; 然后重新插入 , 所以 affect rows = 2
后者: 如果当前存在,就更新它, affect rows = 1

参考链接

7 如何 “存在就更新,不存在就插入”

CRUD代码有一个很常见的场景: 先查次数据库看数据是否存在, 存在则更新; 不存在就插入. 代码需要二次数据库交互, 不过使用下面语句其实可以一步到位

insert into my_table(id, content, create_time) 
        values (#{id,jdbcType=BIGINT},
        #{content,jdbcType=VARCHAR},
        #{createTime,jdbcType=TIMESTAMP}
        )
on duplicate key update content = VALUES(content)

8 如何一次性通统计多行数据

SELECT COUNT(1) AS total,
  SUM(CASE WHEN status = 1 THEN 1 ELSE 0 END) AS status,
  SUM(CASE WHEN state = 1 THEN 1 ELSE 0 END) AS state
FROM test_table
WHERE _id = #{id,jdbcType=BIGINT}

9 mapper-insert (snippet)

-- * 简单插入一条数据(使用自增)

<insert id="insertAuthor" useGeneratedKeys="true"
    keyProperty="id">
  insert into Author (username,password,email,bio)
  values (#{username},#{password},#{email},#{bio})
</insert>

-- * 批量插入数据(使用自增)
<insert id="batchInsert" useGeneratedKeys="true"
        keyProperty="id">
    insert into  (column1, column2, column3, column4) values
    <foreach item="item" collection="list" separator=",">
        (#{item.}, #{item.}, #{item.}, #{item.})
    </foreach>
</insert>

-- * 插入(若DB不支持自增 或 自定义随机主键的)

-- 多数情况下, order="AFTER"更合适
<insert id="insertAuthor">
  <selectKey keyProperty="id" resultType="int" order="BEFORE">
    select CAST(RANDOM()*1000000 as INTEGER) a from SYSIBM.SYSDUMMY1
  </selectKey>
  insert into Author
    (id, username, password, email,bio, favourite_section)
  values
    (#{id}, #{username}, #{password}, #{email}, #{bio}, #{favouriteSection,jdbcType=VARCHAR})
</insert>

10 mapper-select(snippet)

select
<include refid="Base_Column_List"/>
from XXXXX
where env_id = #{envId,jdbcType=BIGINT} and is_deleted = 0
and XXXX in
<foreach collection="XXXXX" index="index" item="item"
         separator="," open="(" close=")">
   #{item}
</foreach>


<if test="xxxx != null and xxxx.size()>0 ">
    and xxxxxx in
    <foreach collection="xxxx" index="index" item="item"
             separator="," open="(" close=")">
        #{item}
    </foreach>
</if>

11 foreach(snippet)

<if test="query.idSet != null and query.idSet.size()>0">
	<foreach collection="query.idSet" item="item" open=" and xxxxx.id not in (" separator="," close=")">
		#{item}
	</foreach>
</if>
<think>嗯,用户问的是MySQLMyBatis之间的区别以及它们的应用场景。首先,我需要明确这两个技术各自的定位,避免混淆。MySQL数据库管理系统,而MyBatis是持久层框架,所以它们属于不同的技术层级。用户可能因为都是处理数据的关系而容易混淆,需要明确区分。 接下来,我需要从功能、作用、使用场景等方面展开比较。首先,MySQL作为关系型数据库,负责数据的存储、查询管理,支持SQL语言,事务处理,索引优化等。而MyBatis则是帮助Java应用程序与数据库交互的框架,简化了JDBC操作,通过映射文件或注解将SQL与Java对象关联,提供更灵活的SQL控制。 用户可能想知道两者的主要区别,所以需要分点说明。比如,定位不同、功能差异、使用方式、适用场景等。同时,应用场景部分需要结合两者的特点,例如MySQL适用于需要结构化数据存储的场景,而MyBatis适合需要高度定制SQL的项目。 还要参考提供的引用内容,尤其是关于MyBatisHibernate的区别,虽然用户的问题是MySQLMyBatis,但引用的内容中提到了MyBatis的特点,比如直接编写SQL、灵活控制、学习曲线平缓等,这些都可以用来解释MyBatis的应用场景。同时,引用中提到MyBatis适合需要精确控制SQL的情况,而MySQL作为数据库,更侧重于数据存储管理。 另外,需要注意用户可能的混淆点,比如误以为MyBatis数据库,或者MySQL是框架。因此,在回答中需要明确两者的角色,MySQL数据库系统,而MyBatis是中间层的框架,帮助应用程序与数据库交互。 可能还需要提到它们如何协同工作,比如在Java项目中,使用MyBatis作为持久层框架来操作MySQL数据库,这样结合各自的优势。同时,指出它们不是替代关系,而是互补的关系。 最后,生成的相关问题需要围绕两者的区别、应用场景以及如何选择等方面,帮助用户进一步理解。例如,询问何时选择MyBatis而不是其他框架,或者MySQL与其他数据库的区别等。</think>### MySQLMyBatis的主要区别及应用场景 #### 一、技术定位差异 1. **MySQL** - 是**关系型数据库管理系统(RDBMS)**,核心功能为数据存储、管理查询,支持标准SQL语法。 - 提供事务管理、索引优化、用户权限控制等数据库核心功能[^1]。 - 典型应用场景:结构化数据存储(如用户信息、订单记录)、复杂查询(如统计报表)[^3]。 2. **MyBatis** - 是**Java持久层框架**,用于简化应用程序与数据库的交互,核心功能为SQL与Java对象的映射。 - 通过XML或注解配置SQL语句,提供动态SQL生成能力,开发者可精确控制SQL逻辑[^2][^4]。 - 典型应用场景:需要高度定制SQL的Java项目(如金融系统、电商平台)[^3]。 #### 二、核心功能对比 | **维度** | **MySQL** | **MyBatis** | |----------------|------------------------------------|----------------------------------| | 核心职责 | 数据存储与查询 | 数据库操作抽象与SQL映射 | | 技术层级 | 数据库系统 | ORM框架(半自动化) | | 开发控制粒度 | 提供标准SQL执行能力 | 允许开发者直接编写/优化SQL | | 性能优化方向 | 索引设计、查询优化、事务隔离级别 | SQL语句优化、缓存机制 | #### 三、协同工作关系 在实际Java项目中,二者通常配合使用: $$ \text{应用程序} \xrightarrow{\text{MyBatis API}} \text{MySQL数据库} $$ 例如通过MyBatis调用MySQL存储过程: ```xml <select id="callProcedure" statementType="CALLABLE"> {call calculate_statistics(#{param1, mode=IN})} </select> ``` #### 四、应用场景选择指南 1. **优先选择MySQL的场景** - 需要持久化存储结构化数据(如用户档案) - 要求ACID事务保证(如银行转账系统) - 涉及复杂联表查询统计分析(如数据仓库)[^1] 2. **优先选择MyBatis的场景** - 需要精细控制SQL语句(如分库分表优化) - 涉及多数据库兼容需求(需配合不同方言配置) - 遗留系统改造需保留原有SQL逻辑[^4] 3. **组合使用典型案例** ```java // MyBatis操作MySQL示例 public interface UserMapper { @Select("SELECT * FROM users WHERE id = #{id}") User getUserById(@Param("id") int id); } ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值