芋道 Spring Boot MyBatis 入门

Innovus每日精要 | 用setScanReorderMode优化扫描链,效率翻倍! 在数字后端物理设计的世界里,扫描链优化就像修路一样,既要保证数据流的顺畅,又要尽量减少绕路和资源浪费。它的主要任务是优化扫描链的连接方式,确保数据能快速、安全地流动。无论是多电压域设计、分区设计,还是复杂的逻辑门,它都能帮你搞定。后,你会发现它不仅能帮你节省时间,还能让你的设计更优雅、更高效。下次遇到扫描链问题时,不妨试试这些技巧,说不定你的设计效率会翻倍!,它能帮你搞定扫描链优化的那些事儿,让你的设计更高效、更优雅。接下来,我们看看这个命令的几个关键选项,以及它们的实际用途。扫描链优化看似枯燥,但掌握。 阅读详情

点击上方“芋道源码”,选择“设为星标”

做积极的人,而不是积极废人!

源码精品专栏

 

摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源码」欢迎转载,保留摘要,谢谢!

  • 1. 概述

  • 2. MyBatis + XML

  • 3. MyBatis + 注解

  • 4. MyBatis-Plus

  • 5. tkmybatis

  • 666. 彩蛋


本文,我们基于 Spring Boot 2.X 版本。

1. 概述

在 DAL 数据访问层,目前会有三种方向的解决方案:

  • JDBC

  • MyBatis

  • JPA

艿艿自己在 知识星球 中,做过一个简单的调研,看看大家使用哪个为主。结果是 MyBatis > JPA > JDBC 。这个也符合在知乎上看到的两篇文章:

  • 《MyBatis 为什么在国内相当流行?》

  • 《为什么阿里巴巴的持久层采用 iBatis 框架,而不使用 hibernate 框架呢?感觉 hibernate 更厉害的样子?》

而每个团队使用 MyBatis 方式还有不同,主要是如下:

注意,几种方式可以组合使用。

  • MyBatis + XML

  • MyBatis + 注解

  • MyBatis-Plus

  • tkmybatis

艿艿的团队,最终我们使用 XML 的方式,因为 XML 便于可以看到每个表使用到的 SQL ,方便做优化和管理。 后来,考虑到提高开发效率,很多标准的数据库的 CRUD 操作,编写还是比较枯燥乏味浪费时间,所以使用 MyBatis-Plus 简化。当然,一些相对复杂的 SQL ,还是会考虑使用 XML 。

下面,我们上面列的四种方式,逐个来入门。

2. MyBatis + XML

示例代码对应仓库:mybatis-xml 。

本小节,我们会使用 mybatis-spring-boot-starter 自动化配置 MyBatis 主要配置。同时,在 XML 中编写相应的 SQL 操作。

2.1 引入依赖

在 pom.xml 文件中,引入相关依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lab-12-mybatis</artifactId>

    <dependencies>
        <!-- 实现对数据库连接池的自动化配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency> <!-- 本示例,我们使用 MySQL -->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <!-- 实现对 MyBatis 的自动化配置 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

        <!-- 方便等会写单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>

具体每个依赖的作用,胖友自己认真看下艿艿添加的所有注释噢。

2.2 Application

创建 Application.java 类,配置 @MapperScan 注解,扫描对应 Mapper 接口所在的包路径。代码如下:

// Application.java

@SpringBootApplication
@MapperScan(basePackages = "cn.iocoder.springboot.lab12.mybatis.mapper")
public class Application {
}
  • cn.iocoder.springboot.lab12.mybatis.mapper 包路径下,就是我们 Mapper 接口所在的包路径。

  • 建议 1 :因为这里是做示例。实际项目中,可以考虑创建一个 MyBatisConfig 配置类,将 @MapperScan 注解添加到其上。

2.3 应用配置文件

在 resources 目录下,创建 application.yaml 配置文件。配置如下:

spring:
  # datasource 数据源配置内容
  datasource:
    url: jdbc:mysql://47.112.193.81:3306/testb5f4?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.jdbc.Driver
    username: testb5f4
    password: F4df4db0ed86@11

# mybatis 配置内容
mybatis:
  config-location: classpath:mybatis-config.xml # 配置 MyBatis 配置文件路径
  mapper-locations: classpath:mapper/*.xml # 配置 Mapper XML 地址
  type-aliases-package: cn.iocoder.springboot.lab12.mybatis.dataobject # 配置数据库实体包路径

具体的每个配置项,胖友自己认真看下艿艿添加的所有注释噢。

2.4 MyBatis 配置文件

在 resources 目录下,创建 mybatis-config.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>

    <settings>
        <!-- 使用驼峰命名法转换字段。 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer"/>
        <typeAlias alias="Long" type="java.lang.Long"/>
        <typeAlias alias="HashMap" type="java.util.HashMap"/>
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
        <typeAlias alias="ArrayList" type="java.util.ArrayList"/>
        <typeAlias alias="LinkedList" type="java.util.LinkedList"/>
    </typeAliases>

</configuration>

因为在数据库中的表的字段,我们是使用下划线风格,而数据库实体的字段使用驼峰风格,所以通过 mapUnderscoreToCamelCase = true 来自动转换。

2.5 UserDO

在 cn.iocoder.springboot.lab12.mybatis.dataobject 包路径下,创建 UserDO.java 类,用户 DO 。代码如下:

// UserDO.java

public class UserDO {

    /**
     * 用户编号
     */
    private Integer id;
    /**
     * 账号
     */
    private String username;
    /**
     * 密码(明文)
     *
     * ps:生产环境下,千万不要明文噢
     */
    private String password;
    /**
     * 创建时间
     */
    private Date createTime;

    // ... 省略 setting/getting 方法

}

对应的创建表的 SQL 如下:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
  `password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

2.6 UserMapper

在 cn.iocoder.springboot.lab12.mybatis.mapper 包路径下,创建 UserMapper 接口。代码如下:

// UserMapper.java

@Repository
public interface UserMapper {

    int insert(UserDO user);

    int updateById(UserDO user);

    int deleteById(@Param("id") Integer id); // 生产请使用标记删除,除非有点想不开,嘿嘿。

    UserDO selectById(@Param("id") Integer id);

    UserDO selectByUsername(@Param("username") String username);

    List<UserDO> selectByIds(@Param("ids")Collection<Integer> ids);

}
  • @Repository 注解,用于标记是数据访问 Bean 对象。在 MyBatis 的接口,实际非必须,只是为了避免在 Service 中,@Autowired 注入时无需报警。

  • @Param 注解,声明变量名。

    • 在方法为单参数时,非必须。

    • 在方法为多参数时,必须。艿艿自己的编程习惯,禁止使用 Map 作为查询参数,因为无法通过方法的定义,很直观的看懂具体的用途。

  • 细心的胖友,肯定会发现例如说 #selectByUsername(@Param("username") String username) 等方法,是使用 By 字段结尾,这是为什么呢?一般情况下,在 SQL 中的 WHERE 条件字段,我们建议能够带在方法名后。原因无它,简单明了。如果是多个字段,可以使用 AND 分隔。当然,如果查询字段比较多,可能方法名会比较长。

在 resources/mapper 路径下,创建 UserMapper.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">
<mapper namespace="cn.iocoder.springboot.lab12.mybatis.mapper.UserMapper">

    <sql id="FIELDS">
        id, username, password, create_time
    </sql>

    <insert id="insert" parameterType="UserDO" useGeneratedKeys="true" keyProperty="id">
        INSERT INTO users (
          username, password, create_time
        ) VALUES (
          #{username}, #{password}, #{createTime}
        )
    </insert>

    <update id="updateById" parameterType="UserDO">
        UPDATE users
        <set>
            <if test="username != null">
                , username = #{username}
            </if>
            <if test="password != null">
                , password = #{password}
            </if>
        </set>
        WHERE id = #{id}
    </update>

    <delete id="deleteById" parameterType="Integer">
        DELETE FROM users
        WHERE id = #{id}
    </delete>

    <select id="selectById" parameterType="Integer" resultType="UserDO">
        SELECT
            <include refid="FIELDS" />
        FROM users
        WHERE id = #{id}
    </select>

    <select id="selectByUsername" parameterType="String" resultType="UserDO">
        SELECT
            <include refid="FIELDS" />
        FROM users
        WHERE username = #{username}
        LIMIT 1
    </select>

    <select id="selectByIds" resultType="UserDO">
        SELECT
            <include refid="FIELDS" />
        FROM users
        WHERE id IN
            <foreach item="id" collection="ids" separator="," open="(" close=")" index="">
                #{id}
            </foreach>
    </select>

</mapper>
  • 建议 1 :对于绝大多数查询,我们是返回统一字段,所以可以使用 <sql /> 标签,定义 SQL 段。对于性能或者查询字段比较大的查询,按需要的字段查询。

  • 建议 2 :对于数据库的关键字,使用大写。例如说,SELECT、WHERE 等等。

  • 建议 3 :基本是每“块”数据库关键字占用一行,胖友可以看看艿艿写的每一行示例。一定要排版干净,毕竟我们是有代码洁癖的男孩子。

2.7 简单测试

创建 UserMapperTest 测试类,我们来测试一下简单的 UserMapper 的每个操作。代码如下:

// UserMapperTest.java

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        UserDO user = new UserDO().setUsername(UUID.randomUUID().toString())
                .setPassword("nicai").setCreateTime(new Date());
        userMapper.insert(user);
    }

    @Test
    public void testUpdateById() {
        UserDO updateUser = new UserDO().setId(1)
                .setPassword("wobucai");
        userMapper.updateById(updateUser);
    }

    @Test
    public void testDeleteById() {
        userMapper.deleteById(2);
    }

    @Test
    public void testSelectById() {
        userMapper.selectById(1);
    }

    @Test
    public void testSelectByUsername() {
        userMapper.selectByUsername("yunai");
    }

    @Test
    public void testSelectByIds() {
        List<UserDO> users = userMapper.selectByIds(Arrays.asList(1, 3));
        System.out.println("users:" + users.size());
    }

}

具体的,胖友可以自己跑跑,妥妥的。

如果胖友嫌弃手写 MyBatis XML 很麻烦,可以看看 IDEA MyBatisCodeHelper-Pro 插件。在没有使用 MyBatis-Plus 插件之前,使用过蛮长一段时间,我以前的老大也在用。

当然,也可以考虑使用 MyBatis Generator (MBG) 。

3. MyBatis + 注解

大多数情况下,艿艿并不推荐使用注解的方式编写 SQL 。一方面,SQL 无法很好的排版。另一方面,会导致 Mapper 接口很长很乱。

并且,在 MyBatis 的官方文档中,对注解的评价如下:

FROM https://mybatis.org/mybatis-3/zh/java-api.html

因为最初设计时,MyBatis 是一个 XML 驱动的框架。配置信息是基于 XML 的,而且映射语句也是定义在 XML 中的。而到了 MyBatis 3,就有新选择了。MyBatis 3 构建在全面且强大的基于 Java 语言的配置 API 之上。这个配置 API 是基于 XML 的 MyBatis 配置的基础,也是新的基于注解配置的基础。注解提供了一种简单的方式来实现简单映射语句,而不会引入大量的开销。

**不幸的是,Java 注解的的表达力和灵活性十分有限。**尽管很多时间都花在调查、设计和试验上,最强大的 MyBatis 映射并不能用注解来构建——并不是在开玩笑,的确是这样。比方说,C#属性就没有这些限制,因此 MyBatis.NET 将会比 XML 有更丰富的选择。也就是说,基于 Java 注解的配置离不开它的特性。

  • 间接表述不是很推荐使用 MyBatis 注解的方式。

同时,在艿艿的工作经历之间,和询问一些好朋友,没有发现使用注解的情况。

因此,真的不推荐使用 MyBatis + 注解。哈哈哈哈,不过这个章节,我还是想写一写。

示例代码对应仓库:lab-12-mybatis-annotation 。

3.1 差异部分

考虑到胖友已经看过 「2. MyBatis + XML」 小节的内容,我们在这个小节主要说下差异的地方。

1、application.yaml

在 application.yaml 配置文件中,我们可以删除 mapper-locations 配置项。

当然,如果胖友想 XML 和注解一起使用,可以保留该配置项。

2、UserMapper.xml

可以删除 UserMapper.xml 配置文件。不过需要在 UserMapper 接口上,通过注解声明 SQL 操作。具体见 「3.2 UserMapper」 。

3.2 UserMapper

在 cn.iocoder.springboot.lab12.mybatis.mapper 包路径下,创建 UserMapper 接口。代码如下:

// UserMapper.java

@Repository
public interface UserMapper {

    @Insert("INSERT INTO users(username, password, create_time) VALUES(#{username}, #{password}, #{createTime})")
    @Options(useGeneratedKeys = true, keyProperty = "id", keyColumn = "id")
    int insert(UserDO user);

    @Update(value = {
            "<script>",
            "UPDATE users",
            "<set>",
            "<if test='username != null'>, username = #{username}</if>",
            "<if test='password != null'>, password = #{password}</if>",
            "</set>",
            "</script>"
    })
    int updateById(UserDO user);

    @Insert("DELETE FROM users WHERE id = #{id}")
    int deleteById(@Param("id") Integer id); // 生产请使用标记删除,除非有点想不开,嘿嘿。

    @Select("SELECT username, password, create_time FROM users WHERE id = #{id}")
    UserDO selectById(@Param("id") Integer id);

    @Select("SELECT username, password, create_time FROM users WHERE username = #{username}")
    UserDO selectByUsername(@Param("username") String username);

    @Select(value = {
            "<script>",
            "SELECT username, password, create_time FROM users",
            "WHERE id IN",
            "<foreach item='id' collection='ids' separator=',' open='(' close=')' index=''>",
            "#{id}",
            "</foreach>",
            "</script>"
    })
    List<UserDO> selectByIds(@Param("ids") Collection<Integer> ids);

}
  • 是不是发现整个 Mapper 接口看起来乱乱的,并且 SQL 的排版也不尽如人意。

  • 对于使用 OGNL 编写动态 SQL ,也特别难受。具体怎么用,胖友可以看看 《MyBatis 在注解上使用动态 SQL》 文章。反正艿艿不是想写第二遍了。

3.3 简单测试

具体的测试,还是使用 UserMapperTest 测试类,直接运行每个测试方法即可。

4. MyBatis-Plus

关于 MyBatis-Plus 的介绍,直接到 https://mybatis.plus/ 官网,艿艿就不多哔哔,嘿嘿。

示例代码对应仓库:mybatis-plus 。

本小节,我们会使用 mybatis-plus-boot-starter 自动化配置 MyBatis-Plus 的配置。同时,演示如何使用 MyBatis-Plus 实现我们在 「2. MyBatis + XML」 演示的各种 CRUD 的操作。

4.1 引入依赖

在 pom.xml 文件中,引入相关依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lab-12-mybatis-plus</artifactId>

    <dependencies>
        <!-- 实现对数据库连接池的自动化配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency> <!-- 本示例,我们使用 MySQL -->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <!-- 实现对 MyBatis Plus 的自动化配置 -->
        <dependency>
            <groupId>com.baomidou</groupId>
            <artifactId>mybatis-plus-boot-starter</artifactId>
            <version>3.2.0</version>
        </dependency>

        <!-- 方便等会写单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>
  • 相比来说,将 mybatis-spring-boot-starter 替换成 mybatis-plus-boot-starter 。

4.2 Application

创建 Application.java 类,配置 @MapperScan 注解,扫描对应 Mapper 接口所在的包路径。代码如下:

// Application.java

@SpringBootApplication
@MapperScan(basePackages = "cn.iocoder.springboot.lab12.mybatis.mapper")
public class Application {
}
  • 和 「2.2 Application」 一致。

4.3 应用配置文件

在 resources 目录下,创建 application.yaml 配置文件。配置如下:

spring:
  # datasource 数据源配置内容
  datasource:
    url: jdbc:mysql://47.112.193.81:3306/testb5f4?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.jdbc.Driver
    username: testb5f4
    password: F4df4db0ed86@11

# mybatis-plus 配置内容
mybatis-plus:
  configuration:
    map-underscore-to-camel-case: true # 虽然默认为 true ,但是还是显示去指定下。
  global-config:
    db-config:
      id-type: auto # ID 主键自增
      logic-delete-value: 1 # 逻辑已删除值(默认为 1)
      logic-not-delete-value: 0 # 逻辑未删除值(默认为 0)
  mapper-locations: classpath*:mapper/*.xml
  type-aliases-package: cn.iocoder.springboot.lab12.mybatis.dataobject

# logging
logging:
  level:
    # dao 开启 debug 模式 mybatis 输入 sql
    cn:
      iocoder:
        springboot:
          lab12:
            mybatis:
              mapper: debug
  • 将 mybatis 替换成 mybatis-plus 配置项目。实际上,如果老项目在用 mybatis-spring-boot-starter 的话,直接将 mybatis 修改成 mybatis-plus 即可。

  • 相比 mybatis 配置项来说,mybatis-plus 增加了更多配置项,也因此我们无需在配置 mybatis-config.xml 配置文件。

  • 更多的 MyBatis-Plus 配置项,可以看看 MyBatis-Plus 使用配置 。

  • 配置 logging 的原因是,方便我们看到 MyBatis-Plus 自动生成的 SQL 。生产环境下,记得关闭噢。

4.4 UserDO

在 cn.iocoder.springboot.lab12.mybatis.dataobject 包路径下,创建 UserDO.java 类,用户 DO 。代码如下:

// UserDO.java
@TableName(value = "users")
public class UserDO {

    /**
     * 用户编号
     */
    private Integer id;
    /**
     * 账号
     */
    private String username;
    /**
     * 密码(明文)
     *
     * ps:生产环境下,千万不要明文噢
     */
    private String password;
    /**
     * 创建时间
     */
    private Date createTime;
    /**
     * 是否删除
     */
    @TableLogic
    private Integer deleted;

    // ... 省略 setting/getting 方法

}
  • 相比 「2.5 UserDO」 来说,主要有两点差别。

  • 增加了 @TableName 注解,设置了 UserDO 对应的表名是 users 。毕竟,我们要使用 MyBatis-Plus 给咱自动生成 CRUD 操作。

  • 增加了 deleted 字段,并添加了 @TableLogic 注解,设置该字段为逻辑删除的标记。

    • 在 application.yaml 配置文件中,我们配置了删除(logic-delete-value = 1)和未删除(logic-not-delete-value = 0)。当然,也可以通过注解的 value 和 delval 来定义未删除和删除。

    • 具体关于 MyBatis-Plus 的逻辑删除功能,看下 逻辑删除 部分的文档。

对应的创建表的 SQL 如下:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
  `password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  `deleted` bit(1) DEFAULT NULL COMMENT '是否删除。0-未删除;1-删除',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

4.5 UserMapper

在 cn.iocoder.springboot.lab12.mybatis.mapper 包路径下,创建 UserMapper 接口。代码如下:

// UserMapper.java

@Repository
public interface UserMapper extends BaseMapper<UserDO> {

    default UserDO selectByUsername(@Param("username") String username) {
        return selectOne(new QueryWrapper<UserDO>().eq("username", username));
    }

    List<UserDO> selectByIds(@Param("ids") Collection<Integer> ids);

    default IPage<UserDO> selectPageByCreateTime(IPage<UserDO> page, @Param("createTime") Date createTime) {
        return selectPage(page,
                new QueryWrapper<UserDO>().gt("create_time", createTime));
    }

}
  • 还是老样子,我们来比较下 「2.6 UserMapper」 接口。

  • 继承了 com.baomidou.mybatisplus.core.mapper.BaseMapper<T> 接口,这样常规的 CRUD 操作,MyBatis-Plus 就可以替我们自动生成。一般来说,开发 CRUD 业务的时候,最枯燥的就是要写 CRUD 的常用 SQL ,完全跟不上艿艿的思绪哈。

    • 因为继承了 BaseMapper 接口,所以我们删除了 #insert(UserDO user)、#updateById(UserDO user)、#deleteById(@Param("id") Integer id)、#selectById(@Param("id") Integer id) 四个 CRUD 方法。

    • 更多 BaseMapper 已经提供好的接口方法,可以看看 《MyBatis-Plus 文档 —— CRUD 接口》 。

  • 对于 #selectByUsername(@Param("username") String username) 方法,我们使用了 com.baomidou.mybatisplus.core.conditions.query.QueryWrapper<T> 构造相对灵活的条件,这样一些动态 SQL 我们就无需在 XML 中编写。

    • 更多 QueryWrapper 已经提供好的拼接方法,可以看看 《MyBatis-Plus 文档 —— 条件构造器》 。

    • 建议 1 :不要在 Service 中,使用 QueryWrapper 拼接动态条件。因为 BaseMapper 提供了 #selectList(Wrapper<T> queryWrapper) 等方法,促使我们能够在 Service 层的逻辑中,使用 QueryWrapper 拼接动态条件,这样会导致逻辑里遍布了各种查询,使我们无法对实际有哪些查询条件做统一的管理。碰到这种情况,建议封装到对应的 Mapper 中,这样会更加简洁干净可管理。

    • 建议 2 :因为 QueryWrapper 暂时不支持一些类似 <if /> 等 MyBatis 的 OGNL 表达式,所以艿艿在 onemall 中,通过继承 QueryWrapper 类,封装了 QueryWrapperX 类。

  • 对于 #selectByIds(@Param("ids") 方法,实际也可以使用 MyBatis-Plus 的 QueryWrapper 很方便的实现,这里仅仅是为了演示在 MyBatis-Plus 混合使用 XML 。

  • 对于 #selectPageByCreateTime(IPage<UserDO> page, @Param("createTime") Date createTime) 方法,是我们额外添加的,用于演示 MyBatis-Plus 提供的分页插件。

    • 更多 IPage 的内容,可以看看 《MyBatis-Plus 文档 —— 分页插件》 。

在 resources/mapper 路径下,创建 UserMapper.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">
<mapper namespace="cn.iocoder.springboot.lab12.mybatis.mapper.UserMapper">

    <sql id="FIELDS">
        id, username, password, create_time
    </sql>

    <select id="selectByIds" resultType="UserDO">
        SELECT
            <include refid="FIELDS" />
        FROM users
        WHERE id IN
            <foreach item="id" collection="ids" separator="," open="(" close=")" index="">
                #{id}
            </foreach>
    </select>

</mapper>
  • 是不是一下子,瘦了!

4.6 简单测试

创建 UserMapperTest 测试类,我们来测试一下简单的 UserMapper 的每个操作。代码如下:

// UserMapperTest.java

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        UserDO user = new UserDO().setUsername(UUID.randomUUID().toString())
                .setPassword("nicai").setCreateTime(new Date())
                .setDeleted(0); // 一般情况下,是否删除,可以全局枚举下。
        userMapper.insert(user);
    }

    @Test
    public void testUpdateById() {
        UserDO updateUser = new UserDO().setId(1)
                .setPassword("wobucai");
        userMapper.updateById(updateUser);
    }

    @Test
    public void testDeleteById() {
        userMapper.deleteById(2);
    }

    @Test
    public void testSelectById() {
        userMapper.selectById(1);
    }

    @Test
    public void testSelectByUsername() {
        userMapper.selectByUsername("yunai");
    }

    @Test
    public void testSelectByIds() {
        List<UserDO> users = userMapper.selectByIds(Arrays.asList(1, 3));
        System.out.println("users:" + users.size());
    }

    @Test
    public void testSelectPageByCreateTime() {
        IPage<UserDO> page = new Page<>(1, 10);
        Date createTime = new Date(2018 - 1990, Calendar.FEBRUARY, 24); // 临时 Demo ,实际不建议这么写
        page = userMapper.selectPageByCreateTime(page, createTime);
        System.out.println("users:" + page.getRecords().size());
    }

}
  • 和 「2.7 简单测试」 差不多,只是多了一个分页的单元测试方法。

总的来说,MyBatis-Plus 给我们日常开发,还是提供了蛮多便利性的,胖友不烦尝试下。

5. tkmybatis

关于 tkmybatis 的介绍,直接到 http://www.mybatis.tk/ 官网,艿艿就不多哔哔,嘿嘿。

需要注意的是,tkmybatis 对自己的定位是 mybatis 的工具的意思,那么 tk 猜测是 toolkit 的缩写。也因此,tkmybatis 是多个开源项目组合起来的:

  • Mapper :提供通用的 MyBatis Mapper 。

  • Mybatis-PageHelper :提供 MyBatis 分页插件。

本小节,我们会使用 tkmybatis 实现我们在 「3. MyBatis-Plus」 的各种 CRUD 操作。

艿艿:说实在的,还是喜欢 MyBatis-Plus 。一站式,文档也更加齐全和易懂。

5.1 引入依赖

在 pom.xml 文件中,引入相关依赖。

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.3.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>lab-12-mybatis-tk</artifactId>

    <dependencies>
        <!-- 实现对数据库连接池的自动化配置 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jdbc</artifactId>
        </dependency>
        <dependency> <!-- 本示例,我们使用 MySQL -->
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>5.1.48</version>
        </dependency>

        <!-- 实现对 MyBatis 的自动化配置 -->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.1.1</version>
        </dependency>

        <!-- 实现对 Mapper 的自动化配置-->
        <dependency>
            <groupId>tk.mybatis</groupId>
            <artifactId>mapper-spring-boot-starter</artifactId>
            <version>2.1.5</version>
        </dependency>
        <!-- 实现对 PageHelper 的自动化配置-->
        <dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper-spring-boot-starter</artifactId>
            <version>1.2.5</version>
            <exclusions>
                <exclusion>
                    <groupId>org.mybatis.spring.boot</groupId>
                    <artifactId>mybatis-spring-boot-starter</artifactId>
                </exclusion>
            </exclusions>
        </dependency>

        <!-- 方便等会写单元测试 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>

    </dependencies>

</project>
  • 引入 mybatis-spring-boot-starter 依赖,自动化配置 MyBatis 。

  • 引入 mapper-spring-boot-starter 依赖,自动化配置 Mapper 。

  • 引入 pagehelper-spring-boot-starter 依赖,自动化配置 PageHelper 。

5.2 Application

创建 Application.java 类,配置 @MapperScan 注解,扫描对应 Mapper 接口所在的包路径。代码如下:

// Application.java

@SpringBootApplication
@MapperScan(basePackages = "cn.iocoder.springboot.lab12.mybatis.mapper") // 注意,要换成 tk 提供的 @MapperScan 注解
public class Application {
}
  • 注意,整列使用的是 tkmybatis 提供的 tk.mybatis.spring.annotation.@MapperScan 注解。

5.3 应用配置文件

在 resources 目录下,创建 application.yaml 配置文件。配置如下:

spring:
  # datasource 数据源配置内容
  datasource:
    url: jdbc:mysql://47.112.193.81:3306/testb5f4?useSSL=false&useUnicode=true&characterEncoding=UTF-8
    driver-class-name: com.mysql.jdbc.Driver
    username: testb5f4
    password: F4df4db0ed86@11

# mybatis 配置内容
mybatis:
  config-location: classpath:mybatis-config.xml # 配置 MyBatis 配置文件路径
  mapper-locations: classpath:mapper/*.xml # 配置 Mapper XML 地址
  type-aliases-package: cn.iocoder.springboot.lab12.mybatis.dataobject # 配置数据库实体包路径

# mapper 配置内容
mapper:
  mappers: cn.iocoder.springboot.lab12.mybatis.util.BaseMapper # 设置基础 Mapper 接口
  not-empty: true # 在 INSERT 和 UPDATE 操作时,是否会判断字段是否为空。即 <if test='xxx != null' />
  identity: MYSQL

# PageHelper 配置内容
# 具体的参数作用,看 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
pagehelper:
  helperDialect: mysql # 分页插件会自动检测当前的数据库链接,自动选择合适的分页方式。 你可以配置helperDialect属性来指定分页插件使用哪种方言。
  reasonable: true # 分页合理化参数,默认值为false。当该参数设置为 true 时,pageNum<=0 时会查询第一页, pageNum>pages(超过总数时),会查询最后一页。默认false 时,直接根据参数进行查询。
  supportMethodsArguments: true # 支持通过 Mapper 接口参数来传递分页参数,默认值false,分页插件会从查询方法的参数值中,自动根据上面 params 配置的字段中取值,查找到合适的值时就会自动分页。 使用方法可以参考测试代码中的 com.github.pagehelper.test.basic 包下的 ArgumentsMapTest 和 ArgumentsObjTest。

# logging
logging:
  level:
    # dao 开启 debug 模式 mybatis 输入 sql
    cn:
      iocoder:
        springboot:
          lab12:
            mybatis:
              mapper: debug
  • 一共有 mybatis、mapper、pagehelper 三大块配置项。相比 MyBatis-Plus 略微复杂一些。具体每个配置项的作用,胖友看下注释。

  • 有一点要注意,cn.iocoder.springboot.lab12.mybatis.util.BaseMapper  接口,需要我们自己定义,去继承 tk.mybatis.mapper.common.Mapper 和 tk.mybatis.mapper.common.MySqlMapper 接口。

5.4 MyBatis 配置文件

在 resources 目录下,创建 mybatis-config.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>

    <settings>
        <!-- 使用驼峰命名法转换字段。 -->
        <setting name="mapUnderscoreToCamelCase" value="true"/>
    </settings>

    <typeAliases>
        <typeAlias alias="Integer" type="java.lang.Integer"/>
        <typeAlias alias="Long" type="java.lang.Long"/>
        <typeAlias alias="HashMap" type="java.util.HashMap"/>
        <typeAlias alias="LinkedHashMap" type="java.util.LinkedHashMap"/>
        <typeAlias alias="ArrayList" type="java.util.ArrayList"/>
        <typeAlias alias="LinkedList" type="java.util.LinkedList"/>
    </typeAliases>

</configuration>
  • 和 「2.3 MyBatis 配置文件」 一致。

5.5 UserDO

在 cn.iocoder.springboot.lab12.mybatis.dataobject 包路径下,创建 UserDO.java 类,用户 DO 。代码如下:

// UserDO.java

/**
 * 用户 DO
 */
@Table(name = "users")
public class UserDO {

    /**
     * 用户编号
     */
    @Id // 表示该字段为主键 ID
    @GeneratedValue(strategy = GenerationType.IDENTITY, generator = "JDBC") // strategy 设置使用数据库主键自增策略;generator 设置插入完成后,查询最后生成的 ID 填充到该属性中。
    private Integer id;
    /**
     * 账号
     */
    private String username;
    /**
     * 密码(明文)
     *
     * ps:生产环境下,千万不要明文噢
     */
    private String password;
    /**
     * 创建时间
     */
    private Date createTime;

    public Integer getId() {
        return id;
    }

    public UserDO setId(Integer id) {
        this.id = id;
        return this;
    }

    public String getUsername() {
        return username;
    }

    public UserDO setUsername(String username) {
        this.username = username;
        return this;
    }

    public String getPassword() {
        return password;
    }

    public UserDO setPassword(String password) {
        this.password = password;
        return this;
    }

    public Date getCreateTime() {
        return createTime;
    }

    public UserDO setCreateTime(Date createTime) {
        this.createTime = createTime;
        return this;
    }

}
  • 因为 Mapper 暂时不支持逻辑删除功能,所以这里我们去除了 deleted 属性。Mapper 的开发者,倾向使用者,自己在业务逻辑中实现逻辑删除。

  • @Table、@Id、@GeneratedValue 注解,使用的是 JPA 提供的注解。如果不知道怎么引入这三个注解,胖友可以看看 UserDO.java 类。

对应的创建表的 SQL 如下:

CREATE TABLE `users` (
  `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '用户编号',
  `username` varchar(64) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '账号',
  `password` varchar(32) COLLATE utf8mb4_bin DEFAULT NULL COMMENT '密码',
  `create_time` datetime DEFAULT NULL COMMENT '创建时间',
  PRIMARY KEY (`id`),
  UNIQUE KEY `idx_username` (`username`)
) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;

5.6 UserMapper

在 cn.iocoder.springboot.lab12.mybatis.mapper 包路径下,创建 UserMapper 接口。代码如下:

// UserMapper.java

@Repository
public interface UserMapper extends BaseMapper<UserDO> { // 继承的是,我们定义的 BaseMapper 接口

    default UserDO selectByUsername(@Param("username") String username) {
        Example example = new Example(UserDO.class);
        // 创建 Criteria 对象,设置 username 查询条件
        example.createCriteria().andEqualTo("username", username);
        // 执行查询
        return selectOneByExample(example);
    }

    List<UserDO> selectByIds(@Param("ids") Collection<Integer> ids);

    default List<UserDO> selectListByCreateTime(@Param("createTime") Date createTime) {
        Example example = new Example(UserDO.class);
        // 创建 Criteria 对象,设置 create_time 查询条件
        example.createCriteria().andGreaterThan("createTime", createTime);
        return selectByExample(example);
    }

}
  • 继承的接口,是我们自己定义的 cn.iocoder.springboot.lab12.mybatis.util.BaseMapper 接口。

  • 在 MyBatis-Plus 中,我们使用 QueryWrapper 拼装动态 SQL 。而在 tkmybatis 中,通过使用它提供的 Example 和 Criteria 类。

  • 关于分页,PageHelper 的使用方式,有点神奇,我们在 「5.6 简单测试」 来看。

在 resources/mapper 路径下,创建 UserMapper.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">
<mapper namespace="cn.iocoder.springboot.lab12.mybatis.mapper.UserMapper">

    <sql id="FIELDS">
        id, username, password, create_time
    </sql>

    <select id="selectByIds" resultType="UserDO">
        SELECT
            <include refid="FIELDS" />
        FROM users
        WHERE id IN
            <foreach item="id" collection="ids" separator="," open="(" close=")" index="">
                #{id}
            </foreach>
    </select>

</mapper>
  • 这个没有差别哈。

5.7 简单测试

创建 UserMapperTest 测试类,我们来测试一下简单的 UserMapper 的每个操作。代码如下:

// UserMapperTest.java

@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
public class UserMapperTest {

    @Autowired
    private UserMapper userMapper;

    @Test
    public void testInsert() {
        UserDO user = new UserDO().setUsername(UUID.randomUUID().toString())
                .setPassword("nicai").setCreateTime(new Date());
        userMapper.insert(user);
        System.out.println(user.getId());
    }

    @Test
    public void testUpdateById() {
        UserDO updateUser = new UserDO().setId(1)
                .setPassword("wobucai");
        userMapper.updateByPrimaryKey(updateUser);
    }

    @Test
    public void testDeleteById() {
        userMapper.deleteByPrimaryKey(2);
    }

    @Test
    public void testSelectById() {
        userMapper.selectByPrimaryKey(1);
    }

    @Test
    public void testSelectByUsername() {
        userMapper.selectByUsername("yunai");
    }

    @Test
    public void testSelectByIds() {
        List<UserDO> users = userMapper.selectByIds(Arrays.asList(1, 3));
        System.out.println("users:" + users.size());
    }

    @Test // 更多使用,可以参考 https://github.com/pagehelper/Mybatis-PageHelper/blob/master/wikis/zh/HowToUse.md
    public void testSelectPageByCreateTime() {
        // 设置分页
        PageHelper.startPage(1, 10);
        Date createTime = new Date(2018 - 1990, Calendar.FEBRUARY, 24); // 临时 Demo ,实际不建议这么写
        // 执行列表查询
        // PageHelper 会自动发起分页的数量查询,设置到 PageHelper 中
        List<UserDO> users = userMapper.selectListByCreateTime(createTime); // 实际返回的是 com.github.pagehelper.Page 代理对象
        // 转换成 PageInfo 对象,并输出分页
        PageInfo<UserDO> page = new PageInfo<>(users);
        System.out.println(page.getTotal());
    }

}
  • 分页逻辑,在 #testSelectPageByCreateTime() 方法中,我们已经进行实现。相比来说,个人不是很喜欢 PageHelper 这种方式。也和朋友聊了下,他们也倾向类似 MyBatis-Plus 提供的分页方式。

666. 彩蛋

总的来说,个人还是比较推荐在项目中使用 MyBatis-Plus 。也问了好些朋友,目前都处于要么在使用 MyBatis-Plus ,要么新项目考虑使用 MyBatis-Plus 。

在之前使用 Spring Data JPA 的过程中,还是比较喜欢可以通过方法名,自动生成对应的 CRUD 操作。所以,就琢磨有没可能 Spring Data JPA 底层实现,除了使用 Hibernate ,是否有可能使用 MyBatis 呢?于是乎,在 Github 上竟然搜到了 spring-data-jpa-mybatis 项目。有点神奇,感兴趣的胖友可以试试。当然,生产上不是很建议哈。

推荐阅读:

  • 《性能测试 —— MySQL 基准测试》

  • 《芋道 Spring Boot 多数据源(读写分离)入门》 对应 lab-17 。

  • 《芋道 Spring Boot 分库分表入门》 对应 lab-18 。



欢迎加入我的知识星球,一起探讨架构,交流源码。加入方式,长按下方二维码噢:

已在知识星球更新源码解析如下:


最近更新《芋道 SpringBoot 2.X 入门》系列,已经 20 余篇,覆盖了 MyBatis、Redis、MongoDB、ES、分库分表、读写分离、SpringMVC、Webflux、权限、WebSocket、Dubbo、RabbitMQ、RocketMQ、Kafka、性能测试等等内容。

提供近 3W 行代码的 SpringBoot 示例,以及超 4W 行代码的电商微服务项目。

获取方式:点“在看”,关注公众号并回复 666 领取,更多内容陆续奉上。

如果你喜欢这篇文章,喜欢,转发。

生活很美好,明天见(。・ω・。)ノ♡

2.实体机安装TrueNAS 方法 访问不了可以使用以下连接:提取码:0927。 阅读详情

相关推荐

SV fork join_none & for循环结合使用

fork join_none与循环联用常见问题解决方案

ZhangShuHuai11的博客 880

springboot+Mybatis依赖+各种报错

springboot+mybatis依赖: 1.pom.xml文件中添加如下代码: &lt;dependency&gt; &lt;groupId&gt;org.mybatis.spring.boot&lt;/groupId&gt; &lt;artifactId&gt;mybatis-spring-boot-starter&lt;/artifactId&gt; &lt;version&gt;1...

qq_43616689的博客 1719

计算机考研复试面试常问问题 数据结构篇(下)

计算机考研复试面试常问问题 数据结构篇(下) 使用前需知(拒绝白嫖,如果对你有帮助,你只需点个赞就行): 注意:有人在闲鱼上盗卖我的资料,而且还有很多同学买了,请各位擦亮双眼,我是整理出来免费分享给大家的! 大家请多点赞和评论,这样后面的同学更容易百度到,不至于被人盗卖,我就不加水印影响大家使用了! 第一次整理,度不好控制,有不好的地方希望大家理解,后面可能会改进,造福今年之后的同学们! ...

程序员宝藏的博客 1万+

芋道 Spring Boot MyBatis 入门(四)之 tkmybatis

点击上方“芋道源码做积极的人,而不是积极废人!源码精品专栏摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源码」欢迎转载,保留摘要,谢谢!1. 概述2. MyBatis + XML2.1 引入依赖2.2 Application2.3 应用配置文件2.4 MyBatis 配置文件2.5 UserDO2.6 UserMapper2.7 简...

芋艿V 519

【SPSS操作】Non-parametric ANCOVA (Quade‘s) in SPSS

在SPSS中执行Quade的非参数ANCOVA需要手动计算步骤,因为SPSS没有内置的菜单选项。以下是详细的操作指南。

weixin_43689393的博客 1278

华为AR3260路由器NAT回流配置实战:从WEB界面到命令行的完整避坑指南

本文详细解析了华为AR3260路由器NAT回流(Hairpin NAT)的配置原理与实战方法。针对内网用户无法通过公网地址访问内部服务器的常见问题,文章不仅剖析了WEB界面配置的常见报错原因,更提供了清晰、可靠且一劳永逸的命令行(CLI)配置方案与排错指南,帮助企业网络工程师彻底解决内外网访问不一致的难题。

u6v7w8x的博客 872

芋道 Spring Boot MyBatis 入门(一)之 MyBatis + XML

点击上方“芋道源码”,选择“设为星标”做积极的人,而不是积极废人!源码精品专栏原创 | Java 2019 超神之路,很肝~中文详细注释的开源项目RPC 框架 Dubbo 源码解析网络...

芋艿V 536

PCB设计中的规则优先级陷阱:为什么你的过孔总是十字连接?

本文深入解析PCB设计中Altium Designer规则优先级机制,解决过孔总是十字连接而非全连接的问题。通过分析铺铜连接原理和规则匹配逻辑,提供精确控制连接方式的技术实践,包括Custom Query使用和优先级最佳设置,帮助设计师避免常见陷阱,优化高速电路板的电气性能和制造可靠性。

banana的博客 467

Spring Boot MyBatis 入门

1. 概述 在 DAL 数据访问层,目前会有三种方向的解决方案: JDBC MyBatis JPA 艿艿自己在知识星球中,做过一个简单的调研,看看大家使用哪个为主。结果是 MyBatis > JPA > JDBC 。这个也符合在知乎上看到的两篇文章: 《MyBatis 为什么在国内相当流行?》 《为什么阿里巴巴的持久层采用 iBatis 框架,而不使用 hibernat...

weixin_42073629的博客 477

第8章 Stata主成分分析与因子分析

在进行数据统计分析时,还往往会遇见变量特别多的情况,而且很多时候这些变量之间还存在着很强的相关关系或者说变量之间存在着很强的信息重叠,如果我们直接对数据进行分析,一方面会带来工作量的无畏的加大,另一方面还会出现一些模型应用的错误,于是主成分分析与因子分析应运而生。这两种分析方法的基本思想都是在不损失大量信息的前提下,利用较少的独立变量来替代原来的变量进行进一步的分析。 8.1主成分分析 基本思想是将众多的初始变量整合成少数几个互相无关的主成分变量,而这些新变量尽可能地包含...

qq_45112156的博客 5万+

从零构建机械臂规划栈:Pinocchio、OMPL与Ruckig的工程化融合实践

本文详细介绍了如何从零构建机械臂规划栈,通过融合Pinocchio、OMPL和Ruckig三大核心组件,实现高性能的机械臂运动规划与轨迹生成。文章深入探讨了技术选型、工程架构设计及实战优化技巧,特别针对逆解、路径规划和轨迹平滑等关键环节提供了实用解决方案,适用于工业场景中的高实时性需求。

weixin_29072299的博客 433

Spring Boot整合MyBatis(xml相关)步骤及问题排查

1.pom.xml加入依赖: <!--mysql driver--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--jpa--> &...

成长笔记 268

使用DrissionPage和自动化技术实现得物鞋子信息爬取

本文介绍了一个基于DrissionPage技术的得物鞋子信息采集系统,能自动化采集商品图片、价格等数据并保存为Excel。系统采用浏览器模拟技术处理动态加载内容,通过XPath定位元素,实现智能交互和完整数据采集。关键技术包括:图片URL提取与下载、Excel数据集成与图片嵌入、文件名安全处理等。项目适用于市场分析和学术研究,强调必须遵守法律法规和平台规则,仅用于非商业用途。与API爬虫相比,浏览器自动化能更好处理现代Web应用,但需注意知识产权保护。

那些看似不起波澜的日复一日,会在某天让你看到坚持的意义 1665

芋道 Spring Boot MyBatis 入门(三)之 MyBatis-Plus

点击上方“芋道源码做积极的人,而不是积极废人!源码精品专栏摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源码」欢迎转载,保留摘要,谢谢!1. 概述2. MyBatis + XML2.1 引入依赖2.2 Application2.3 应用配置文件2.4 MyBatis 配置文件2.5 UserDO2.6 UserMapper2.7 简...

芋艿V 588

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

芋道 Spring Boot MyBatis 入门(二)之 MyBatis + 注解

点击上方“芋道源码做积极的人,而不是积极废人!源码精品专栏摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源码」欢迎转载,保留摘要,谢谢!1. 概述2. MyBatis + XML2.1 引入依赖2.2 Application2.3 应用配置文件2.4 MyBatis 配置文件2.5 UserDO2.6 UserMapper2.7 简...

芋艿V 186

假人有限元模型

假人模型,车辆碰撞假人有限元模型,适合做乘员安全的研究者利用

mybatis 注解_芋道 Spring Boot MyBatis 入门(二)之 MyBatis + 注解

摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源码」欢迎转载,保留摘要,谢谢!1. 概述2. MyBatis + XML2.1 引入依赖2.2 Application2.3 应用配置文件2.4 MyBatis 配置文件2.5 UserDO2.6 UserMapper2.7 简单测试3. MyBatis + 注解3.1 差异部分3.2 ...

weixin_39711441的博客 95

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

tkmybatis 连接查询_芋道 Spring Boot MyBatis 入门(四)之 tkmybatis

摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源码」欢迎转载,保留摘要,谢谢!1. 概述2. MyBatis + XML2.1 引入依赖2.2 Application2.3 应用配置文件2.4 MyBatis 配置文件2.5 UserDO2.6 UserMapper2.7 简单测试3. MyBatis + 注解3.1 差异部分3.2 ...

weixin_39585761的博客 600

spring boot 转xml格式报错解决方法_芋道 Spring Boot MyBatis 入门(一)之 MyBatis + XML...

摘要: 原创出处 http://www.iocoder.cn/Spring-Boot/MyBatis/ 「芋道源码」欢迎转载,保留摘要,谢谢!1. 概述2. MyBatis + XML2.1 引入依赖2.2 Application2.3 应用配置文件2.4 MyBatis 配置文件2.5 UserDO2.6 UserMapper2.7 简单测试3. MyBatis + 注解3.1 差异部分3.2 ...

weixin_39747807的博客 435

新人一看就懂:Spring Boot+Spring mvc+Mybatis的基础框架demo

Spring Boot的设计目的是来简化新Spring应用的初始搭建以及开发过程,大大减少了代码量,通过这篇文章你可以清楚的看到。这是一个基于Spring Boot的简单demo,希望读者可以通过这篇文章大概能看懂这一个简单的框架搭建。后续我会陆续更新,微服务架构(Spring Boot、Spring Cloud)、分布式架构(Dobbo+Zookeeper)、大数据架构以及源码解析等相关的文章,感兴趣的话可以关注一下。

程序员云帆哥的博客 2万+

企业级Spring Boot框架开发效率提升解决方案:芋道源码全解析

芋道源码作为一款企业级Spring Boot应用框架,通过模块化开发实现业务逻辑与技术架构的解耦,为企业级应用提供从数据权限控制到工作流引擎的完整解决方案。本文将从价值定位、核心能力、实战指南和扩展进阶四个维度,全面解析芋道源码框架如何帮助开发者提升开发效率,构建稳定可靠的企业级应用。 ## 一、价值定位:3大核心优势解决企业级开发痛点 在企业级应用开发过程中,开发者常常面临系统架构复杂、模块

gitblog_00398的博客 812

芋道源码企业级框架从入门到精通完整指南

芋道源码作为一款基于Spring Boot深度优化的企业级应用框架,为开发者提供了开箱即用的完整解决方案。无论你是刚接触企业级开发的新手,还是希望提升开发效率的资深工程师,本指南都将带你全面掌握这个强大工具。 ## 项目快速上手 ### 环境准备与源码获取 通过以下命令快速获取项目源码: ```bash git clone https://gitcode.com/gh_mirrors/ru/

gitblog_00314的博客 956

芋道源码终极指南:Spring Boot企业级开发框架实战教程

芋道源码是一个基于Spring Boot的企业级开发框架,为开发者提供了一套完整的企业应用解决方案。这个开源项目涵盖了从基础架构到业务模块的全方位功能,是快速构建企业级应用的理想选择。 ## 🚀 什么是芋道源码? 芋道源码是一个功能丰富的Spring Boot企业级开发框架,它整合了现代企业应用所需的各种核心组件和技术栈。无论是中小型企业还是大型互联网公司,都能从这个框架中找到适合自己业务场

gitblog_00830的博客 942

芋道源码:企业级Spring Boot应用框架的终极指南

芋道源码是一个功能强大的企业级Spring Boot应用框架,专为Java开发者提供完整的后端解决方案。这个开源框架集成了现代化企业应用所需的各种功能模块,让开发者能够快速构建高质量的业务系统。😊 ## 🚀 框架核心架构与设计理念 芋道源码采用**模块化架构设计**,将不同的业务功能拆分成独立的模块,每个模块都包含API接口和业务实现两部分。这种设计让系统更加灵活,便于维护和扩展。 ##

gitblog_00109的博客 801

芋道源码新手入门:5分钟搭建第一个应用

不需要配置复杂的环境,打开网页就能直接运行代码,还能一键部署查看效果。对于想快速入门Java开发的同学来说,这种即开即用的体验真的很友好。我试了几个示例项目,从代码编辑到部署上线整个过程非常流畅,省去了很多环境配置的麻烦。作为新手,第一次接触这种企业级框架确实有点懵,不过跟着官方文档和社区教程走了一遍,发现其实入门没那么难。今天就把我的学习过程整理成笔记,分享给同样想入门的小伙伴们。首先需要安装JDK 1.8或以上版本,建议直接下载OpenJDK,安装后记得配置JAVA_HOME环境变量。

NightshadeRaven21的博客 812

10分钟实现全文检索:芋道云平台Elasticsearch快速集成实战指南

你是否还在为系统中的搜索功能发愁?用户抱怨找不到想要的内容,简单的数据库模糊查询效率低下且体验糟糕?本文将带你一文解决这些痛点,通过芋道云(yudao-cloud)平台的Elasticsearch集成方案,快速实现高效、精准的全文检索功能。 芋道云平台(yudao-cloud)是一个基于Spring Cloud Alibaba + MyBatis Plus + Vue & Element实现的后

gitblog_00533的博客 1198

芋道源码:企业级Spring Boot框架的价值定位与实践指南

企业级框架如何解决中小团队技术选型困境?芋道源码作为一款模块化Spring Boot应用开发框架,通过"框架+业务模块"的解耦设计,帮助团队实现快速开发解决方案,本文将从价值定位、核心功能、实践指南和扩展进阶四个维度,全面解析这一架构解耦实践的实施路径。 ## 一、价值定位:为什么选择芋道源码框架 ### 学习目标 - 理解企业级框架的核心价值主张 - 掌握芋道源码解决的关键技术痛点 - 评估

gitblog_00815的博客 744
上一篇: 2019 年最受欢迎的 JVM 配置参数是怎样的?
下一篇: 狠人 Spring Cloud 20000 字总结!
公众号-芋道源码
博客等级 码龄10年 1625粉丝 377原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值