让MyBatis效率提升一百倍的写法,你还不知道?

10 种超好用的 MyBatis 写法,同事都说好用! 如果传递的是一个List,则mybatis会封装为一个list为key,list值为object的map,如果是array,则封装成一个array为key,array的值为object的map,如果自己封装呢,则colloection里放的是自己封装的map里的key值。此外,如果标签返回的内容是以AND 或OR 开头的,则它会剔除掉。使用时比较灵活, new一个这样的实体类,我们需要限制那个条件,只需要附上相应的值就会where这个条件,相反不去赋值就可以不在where中判断。 阅读详情

对一个 Java 后端程序员来说,MyBatis、Hibernate、Data Jdbc 等都是我们常用的 ORM 框架。它们有时候很好用,比如简单的 CRUD,事务的支持都非常棒。但有时候用起来也非常繁琐,比如接下来我们要聊到的一个常见的开发需求,而对这类需求,本文会给出一个比直接使用这些 ORM 开发效率至少会提高 100 倍的方法(绝无夸张)。

首先数据库有两张表

用户表(user):(简单起见,假设只有 4 个字段)

字段名类型含义
idbitint用户 ID
namevarchar(45)用户名
ageint年龄
role_idint角色 ID

角色表(role):(简单起见,假设只有 2 个字段)

字段名类型含义
idint角色 ID
namevarchar(45)角色名

接下来我们要实现一个用户查询的功能

这个查询有点复杂,它的要求如下:

  • 可按用户名字段查询,要求:
    • 可精确匹配(等于某个值)
    • 可全模糊匹配(包含给定的值)
    • 可后模糊查询(以...开头)
    • 可前模糊查询(以.. 结尾)
    • 可指定以上四种匹配是否可以忽略大小写
  • 可按年龄字段查询,要求:
    • 可精确匹配(等于某个年龄)
    • 可大于匹配(大于某个值)
    • 可小于匹配(小于某个值)
    • 可区间匹配(某个区间范围)
  • 可按角色ID查询,要求:精确匹配
  • 可按用户ID查询,要求:同年龄字段
  • 可指定只输出哪些列(例如,只查询 ID 与 用户名 列)
  • 支持分页(每次查询后,页面都要显示满足条件的用户总数)
  • 查询时可选择按 ID、用户名、年龄 等任意字段排序

后端接口该怎么写呢?

试想一下,对于这种要求的查询,后端接口里的代码如果用 MyBatis、Hibernate、Data Jdbc 直接来写的话,100 行代码 能实现吗?

反正我是没这个信心,算了,我还是直接坦白,面对这种需求后端如何 只用一行代码搞定 吧(有兴趣的同学可以 MyBatis 等写个试试,最后可以对比一下)

手把手:只一行代码实现以上需求

首先,重点人物出场啦:Bean Searcher, 它就是专门来对付这种列表检索的,无论简单的还是复杂的,统统一行代码搞定!而且它还非常轻量,Jar 包体积仅不到 100KB,无第三方依赖。

假设我们项目使用的框架是 Spring Boot(当然 Bean Searcher 对框架没有要求,但在 Spring Boot 中使用更加方便)

添加依赖

Maven :

<dependency>
    <groupId>com.ejlchina</groupId>
    <artifactId>bean-searcher-boot-starter</artifactId>
    <version>3.1.0</version>
</dependency>

Gradle :

implementation 'com.ejlchina:bean-searcher-boot-starter:3.1.0'

然后写个实体类来承载查询的结果

@SearchBean(tables="user u, role r", joinCond="u.role_id = r.id", autoMapTo="u") 
public class User {

    private Long id;        // 用户ID(u.id)
    private String name;    // 用户名(u.name)
    private int age;        // 年龄(u.age)
    private int roleId;     // 角色ID(u.role_id)
    @DbField("r.name")      // 指明这个属性来自 role 表的 name 字段
    private String role;        // 角色名(r.name)

    // Getter and Setter ...
}

接着就可以写用户查询接口了

接口路径就叫 /user/index 吧:

@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private MapSearcher mapSearcher;  // 注入检索器(由 bean-searcher-boot-starter 提供)

    @GetMapping("/index")
    public SearchResult<Map<String, Object>> index(HttpServletRequest request) {
        // 这里咱们只写一行代码
        return mapSearcher.search(User.class, MapUtils.flat(request.getParameterMap()));
    }

}

上述代码中的 MapUtils 是 Bean Searcher 提供的一个工具类,MapUtils.flat(request.getParameterMap()) 只是为了把前端传来的请求参数统一收集起来,然后剩下的,就全部交给 MapSearcher 检索器了。

这样就完了?那我们来测一下这个接口,看看效果吧

(1)无参请求

  • GET /user/index
  • 返回结果:
{
    "dataList": [           // 用户列表,默认返回第 0 页,默认分页大小为 15 (可配置)
        { "id": 1, "name": "Jack", "age": 25, "roleId": 1, "role": "普通用户" },
        { "id": 2, "name": "Tom", "age": 26, "roleId": 1, "role": "普通用户" },
        ...
    ],
    "totalCount": 100       // 用户总数
}

(2)分页请求(page | size)

  • GET /user/index? page=2 & size=10
  • 返回结果:结构同 (1)(只是每页 10 条,返回第 2 页)

参数名 size 和 page 可自定义, page 默认从 0 开始,同样可自定义,并且可与其它参数组合使用

(3)数据排序(sort | order)

  • GET /user/index? sort=age & order=desc
  • 返回结果:结构同 (1)(只是 dataList 数据列表以 age 字段降序输出)

参数名 sort 和 order 可自定义,可与其它参数组合使用

(4)指定(排除)字段(onlySelect | selectExclude)

  • GET /user/index? onlySelect=id,name,role
  • GET /user/index? selectExclude=age,roleId
  • 返回结果:( 列表只含 id,name 与 role 三个字段)
{
    "dataList": [           // 用户列表,默认返回第 0 页(只包含 id,name,role 字段)
        { "id": 1, "name": "Jack", "role": "普通用户" },
        { "id": 2, "name": "Tom", "role": "普通用户" },
        ...
    ],
    "totalCount": 100       // 用户总数
}

参数名 onlySelect 和 selectExclude 可自定义,可与其它参数组合使用

(5)字段过滤(op = eq)

  • GET /user/index? age=20
  • GET /user/index? age=20 & age-op=eq
  • 返回结果:结构同 (1)(但只返回 age = 20 的数据)

参数 age-op = eq 表示 age 的 字段运算符 是 eq(Equal 的缩写),表示参数 age 与参数值 20 之间的关系是 Equal,由于 Equal 是一个默认的关系,所以 age-op = eq 也可以省略

参数名 age-op 的后缀 -op 可自定义,且可与其它字段参数 和 上文所列的参数(分页、排序、指定字段)组合使用,下文所列的字段参数也是一样,不再复述。

(6)字段过滤(op = ne)

  • GET /user/index? age=20 & age-op=ne
  • 返回结果:结构同 (1)(但只返回 age != 20 的数据,ne 是 NotEqual 的缩写)

(7)字段过滤(op = ge)

  • GET /user/index? age=20 & age-op=ge
  • 返回结果:结构同 (1)(但只返回 age >= 20 的数据,ge 是 GreateEqual 的缩写)

(8)字段过滤(op = le)

  • GET /user/index? age=20 & age-op=le
  • 返回结果:结构同 (1)(但只返回 age <= 20 的数据,le 是 LessEqual 的缩写)

(9)字段过滤(op = gt)

  • GET /user/index? age=20 & age-op=gt
  • 返回结果:结构同 (1)(但只返回 age > 20 的数据,gt 是 GreateThan 的缩写)

(10)字段过滤(op = lt)

  • GET /user/index? age=20 & age-op=lt
  • 返回结果:结构同 (1)(但只返回 age < 20 的数据,lt 是 LessThan 的缩写)

(11)字段过滤(op = bt)

  • GET /user/index? age-0=20 & age-1=30 & age-op=bt
  • 返回结果:结构同 (1)(但只返回 20 <= age <= 30 的数据,bt 是 Between 的缩写)

参数 age-0 = 20 表示 age 的第 0 个参数值是 20。上述提到的 age = 20 实际上是 age-0 = 20 的简写形式。另:参数名 age-0 与 age-1 中的连字符 - 可自定义。

(12)字段过滤(op = mv)

  • GET /user/index? age-0=20 & age-1=30 & age-2=40 & age-op=mv
  • 返回结果:结构同 (1)(但只返回 age in (20, 30, 40) 的数据,mv 是 MultiValue 的缩写,表示有多个值的意思)

(13)字段过滤(op = in)

  • GET /user/index? name=Jack & name-op=in
  • 返回结果:结构同 (1)(但只返回 name 包含 Jack 的数据,in 是 Include 的缩写)

(14)字段过滤(op = sw)

  • GET /user/index? name=Jack & name-op=sw
  • 返回结果:结构同 (1)(但只返回 name 以 Jack 开头的数据,sw 是 StartWith 的缩写)

(15)字段过滤(op = ew)

  • GET /user/index? name=Jack & name-op=ew
  • 返回结果:结构同 (1)(但只返回 name 以 Jack 结尾的数据,sw 是 EndWith 的缩写)

(16)字段过滤(op = ey)

  • GET /user/index? name-op=ey
  • 返回结果:结构同 (1)(但只返回 name 为空 或为 null 的数据,ey 是 Empty 的缩写)

(17)字段过滤(op = ny)

  • GET /user/index? name-op=ny
  • 返回结果:结构同 (1)(但只返回 name 非空 的数据,ny 是 NotEmpty 的缩写)

(18)忽略大小写(ic = true)

  • GET /user/index? name=Jack & name-ic=true
  • 返回结果:结构同 (1)(但只返回 name 等于 Jack (忽略大小写) 的数据,ic 是 IgnoreCase 的缩写)

参数名 name-ic 中的后缀 -ic 可自定义,该参数可与其它的参数组合使用,比如这里检索的是 name 等于 Jack 时忽略大小写,但同样适用于检索 name 以 Jack 开头或结尾时忽略大小写。

当然,以上各种条件都可以组合,例如

查询 name 以 Jack (忽略大小写) 开头,且 roleId = 1,结果以 id 字段排序,每页加载 10 条,查询第 2 页:

  • GET /user/index? name=Jack & name-op=sw & name-ic=true & roleId=1 & sort=id & size=10 & page=2
  • 返回结果:结构同 (1)

OK,效果看完了,/user/index 接口里我们确实只写了一行代码,它便可以支持这么多种的检索方式,有没有觉得现在 你写的一行代码 就可以 干过别人的一百行 呢?

Bean Searcher

本例中,我们只使用了 Bean Searcher 提供的 MapSearcher 检索器的一个检索方法,其实,它还有很多检索方法。

检索方法

  • searchCount(Class<T> beanClass, Map<String, Object> params) 查询指定条件下的数据 总条数
  • searchSum(Class<T> beanClass, Map<String, Object> params, String field) 查询指定条件下的 某字段 的 统计值
  • searchSum(Class<T> beanClass, Map<String, Object> params, String[] fields) 查询指定条件下的 多字段 的 统计值
  • search(Class<T> beanClass, Map<String, Object> params) 分页 查询指定条件下数据 列表 与 总条数
  • search(Class<T> beanClass, Map<String, Object> params, String[] summaryFields) 同上 + 多字段 统计
  • searchFirst(Class<T> beanClass, Map<String, Object> params) 查询指定条件下的 第一条 数据
  • searchList(Class<T> beanClass, Map<String, Object> params) 分页 查询指定条件下数据 列表
  • searchAll(Class<T> beanClass, Map<String, Object> params) 查询指定条件下 所有 数据 列表

MapSearcher 与 BeanSearcher

另外,Bean Searcher 除了提供了 MapSearcher 检索器外,还提供了 BeanSearcher 检索器,它同样拥有 MapSearcher 所有的方法,只是它返回的单条数据不是 Map,而是一个 泛型 对象。

参数构建工具

另外,如果你是在 Service 里使用 Bean Searcher,那么直接使用 Map<String, Object> 类型的参数可能不太优雅,为此, Bean Searcher 特意提供了一个参数构建工具。

例如,同样查询 name 以 Jack (忽略大小写) 开头,且 roleId = 1,结果以 id 字段排序,每页加载 10 条,加载第 2 页,使用参数构建器,代码可以这么写:

Map<String, Object> params = MapUtils.builder()
        .field(User::getName, "Jack").op(Operator.StartWith).ic()
        .field(User::getRoleId, 1)
        .orderBy(User::getId, "asc")
        .page(2, 10)
        .build()
List<User> users = beanSearcher.searchList(User.class, params);

这里使用的是 BeanSearcher 检索器,以及它的 searchList(Class<T> beanClass, Map<String, Object> params) 方法。

运算符约束

上文我们看到,Bean Searcher 对实体类中的每一个字段,都直接支持了很多的检索方式。

但某同学:哎呀!检索方式太多了,我根本不需要这么多,我的数据量几十亿,用户名字段的前模糊查询方式利用不到索引,万一把我的数据库查崩了怎么办呀?

好办,Bean Searcher 支持运算符的约束,实体类的用户名 name 字段只需要注解一下即可:

@SearchBean(tables="user u, role r", joinCond="u.role_id = r.id", autoMapTo="u") 
public class User {

    @DbField(onlyOn = {Operator.Equal, Operator.StartWith})
    private String name;

    // 为减少篇幅,省略其它字段...
}

如上,通过 @DbField 注解的 onlyOn 属性,指定这个用户名 name 只能适用与 精确匹配 和 后模糊查询,其它检索方式它将直接忽略。

上面的代码是限制了 name 只能有两种检索方式,如果再严格一点,只允许 精确匹配,那其实有两种写法。

(1)还是使用运算符约束:

@SearchBean(tables="user u, role r", joinCond="u.role_id = r.id", autoMapTo="u") 
public class User {

    @DbField(onlyOn = Operator.Equal)
    private String name;

    // 为减少篇幅,省略其它字段...
}

(2)在 Controller 的接口方法里把运算符参数覆盖:

@GetMapping("/index")
public SearchResult<Map<String, Object>> index(HttpServletRequest request) {
    Map<String, Object> params = MapUtils.flatBuilder(request.getParameterMap())
        .field(User::getName).op(Operator.Equal)   // 把 name 字段的运算符直接覆盖为 Equal
        .build()
    return mapSearcher.search(User.class, params);
}

条件约束

该同学又:哎呀!我的数据量还是很大,age 字段没有索引,我不想让它参与 where 条件,不然很可能就出现慢 SQL 啊!

不急,Bean Searcher 还支持条件的约束,让这个字段直接不能作为条件:

@SearchBean(tables="user u, role r", joinCond="u.role_id = r.id", autoMapTo="u") 
public class User {

    @DbField(conditional = false)
    private int age;

    // 为减少篇幅,省略其它字段...
}

如上,通过 @DbField 注解的 conditional 属性, 就直接不允许 age 字段参与条件了,无论前端怎么传参,Bean Searcher 都不搭理。

参数过滤器

该同学仍:哎呀!哎呀 ...

别怕! Bean Searcher 还支持配置全局参数过滤器,可自定义任何参数过滤规则,在 Spring Boot 项目中,只需要配置一个 Bean:

@Bean
public ParamFilter myParamFilter() {
    return new ParamFilter() {
        @Override
        public <T> Map<String, Object> doFilter(BeanMeta<T> beanMeta, Map<String, Object> paraMap) {
            // beanMeta 是正在检索的实体类的元信息, paraMap 是当前的检索参数
            // TODO: 这里可以写一些自定义的参数过滤规则
            return paraMap;      // 返回过滤后的检索参数
        }
    };
}

某同学问

参数咋这么怪,这么多呢,和前端有仇么

  1. 参数名是否奇怪,这其实看个人喜好,如果你不喜欢中划线 -,不喜欢 op、ic 后缀,完全可以自定义,参考这篇文档:

searcher.ejlchina.com/guide/lates…

  1. 参数个数的多少,其实是和需求的复杂程度相关的。如果需求很简单,那么很多参数没必要让前端传,后端直接塞进去就好。比如:name 只要求后模糊匹配,age 只要求区间匹配,则可以:
@GetMapping("/index")
public SearchResult<Map<String, Object>> index(HttpServletRequest request) {
    Map<String, Object> params = MapUtils.flatBuilder(request.getParameterMap())
        .field(User::getName).op(Operator.StartWith)
        .field(User::getAge).op(Operator.Between)
        .build()
    return mapSearcher.search(User.class, params);
}
复制代码

这样前端就不用传 name-op 与 age-op 这两个参数了。

其实还有一种更简单的方法,那就是 运算符约束(当约束存在时,运算符默认就是 onlyOn 属性中指定的第一个值,前端可以省略不传):

@SearchBean(tables="user u, role r", joinCond="u.role_id = r.id", autoMapTo="u") 
public class User {

    @DbField(onlyOn = Operator.StartWith)
    private String name;
    @DbField(onlyOn = Operator.Between)
    private String age;

    // 为减少篇幅,省略其它字段...
}

入参是 request,我 swagger 文档不好渲染了呀

其实,Bean Searcher 的检索器只是需要一个 Map<String, Object> 类型的参数,至于这个参数是怎么来的,和 Bean Searcher 并没有直接关系。前文之所以从 request 里取,只是因为这样代码看起来简洁,如果你喜欢声明参数,完全可以把代码写成这样:

@GetMapping("/index")
public SearchResult<Map<String, Object>> index(Integer page, Integer size, 
            String sort, String order, String name, Integer roleId,
            @RequestParam(value = "name-op", required = false) String name_op,
            @RequestParam(value = "name-ic", required = false) Boolean name_ic,
            @RequestParam(value = "age-0", required = false) Integer age_0,
            @RequestParam(value = "age-1", required = false) Integer age_1,
            @RequestParam(value = "age-op", required = false) String age_op) {
    Map<String, Object> params = MapUtils.builder()
        .field(Employee::getName, name).op(name_op).ic(name_ic)
        .field(Employee::getAge, age_0, age_1).op(age_op)
        .field(Employee::getRoleId, roleId)
        .orderBy(sort, order)
        .page(page, size)
        .build();
    return mapSearcher.search(User.class, params);
}

字段参数之间的关系都是 “且” 呀,那 “或” 呢? “且” “或” 任意组合呢?

上文所述的字段参数之间确是都是 "且" 的关系,至于 “或”,虽然这种使用场景不太多,但 Bean Searcher 也是支持的,详细可以参考这篇文章:

github.com/ejlchina/be…

这里就不再复述了。

结语

本文介绍了 Bean Searcher 在复杂列表检索领域的超强能力。它之所以可以极大提高这类需求的研发效率,根本上归功于它 独创 的 动态字段运算符 与 多表映射机制,这是传统 ORM 框架所没有的。但由于篇幅所限,它的特性本文不能尽述,比如它还:

  • 支持 聚合查询
  • 支持 Select|Where|From子查询
  • 支持 实体类嵌入参数
  • 支持 字段转换器
  • 支持 Sql 拦截器
  • 支持 多数据源
  • 支持 自定义注解
  • 等等

要了解更多,先来点个 Star 吧 : Github 、Gitee。

Bean Searcher 是我在工作中总结封装出来的一个小工具,公司内部使用了 4 年,经历大小项目三四十个,只是最近才着手完善文档分享给大家,如果你喜欢,一定去点个 Star 哦 _。

再奉上 Bean Searcher 的详细文档:searcher.ejlchina.com/

最后,再来个 Demo 地址:

大哥,别忘 Star 啊(破音。。 泪目。。。)

别再只看图了!代谢组学OPLS-DA分析,R2Y和Q2Y到底怎么看才不踩坑? 本文深入解析代谢组学OPLS-DA分析中的关键指标R2Y和Q2Y,揭示如何避免过拟合陷阱。通过详细解读模型解释能力(R2Y)和预测能力(Q2Y),结合置换检验方法,提供完整的模型评估流程与实战建议,帮助研究者获得可靠的分析结果。 阅读详情

相关推荐

5分钟搞定!用Keil MDK将STM32F103C8T6工程无缝迁移到ZET6开发板

本文详细介绍了如何在Keil MDK环境下快速将STM32F103C8T6工程迁移到ZET6开发板,涵盖硬件差异对比、工程配置调整、外设适配及编译排错等关键步骤,帮助开发者5分钟内完成工程移植,大幅提升开发效率。

weixin_30879169的博客 409

这样写代码,比直接使用 MyBatis 效率提高了 100 倍

对一个 Java 后端程序员来说,mybatis、hibernate、data-jdbc 等都是我们常用的 ORM 框架。它们有时候很好用,比如简单的 CRUD,事务的支持都非常棒。但有时候用起来也非常繁琐,比如接下来我们要聊到的一个常见的开发需求,而对这类需求,本文会给出一个比直接使用这些 ORM 开发效率至少会提高100倍的方法(绝无夸张)。 首先数据库有两张表 用户表(user):(简单起见,假设只有 4 个字段) 字段名 类型 含..

qq_64513388的博客 321

PyTorch、Torchvision、Torchaudio历史版本whl文件下载地址、版本对应关系与离线安装全攻略

本文详细解析了PyTorch、Torchvision和Torchaudio历史版本whl文件的下载地址、版本对应关系及离线安装全攻略。针对无网络环境下的安装挑战,提供了官方whl文件获取路径、版本匹配技巧和完整安装流程,帮助开发者高效解决兼容性问题,确保深度学习环境的稳定部署。

weixin_31960565的博客 379

Mybatis如何书写

mybatis书写

weixin_45632897的博客 573

OpenCV实战:高效检测与识别多类型条码与二维码

本文详细介绍了如何利用OpenCV的BarcodeDetector和QRCodeDetector模块,高效实现EAN-13条形码与常见二维码的检测与识别。内容涵盖从环境搭建、单码识别到处理多二维码的完整流程,并分享了提升识别率的图像预处理与性能优化等实战技巧,帮助开发者一站式解决视觉项目中的条码识别需求。

weixin_29094539的博客 495

在统信UOS Server 20上踩坑记:手把手教你搞定openGauss 5.0.0企业版安装(附常见报错解决方案)

本文详细记录了在统信UOS Server 20上安装openGauss 5.0企业版的实战经验,包括环境准备、依赖库问题、目录权限、内存参数调优等常见问题的解决方案。通过伪装系统标识、建立软链接、调整内存参数等方法,成功克服国产操作系统与企业级数据库的兼容性挑战,为开发者提供了一份深度排雷指南。

weixin_28698059的博客 265

学会了MybatisPlus,代码开发效率提高了10倍

我们知道 MyBatis 是一个基于 java 的持久层框架,它内部封装了 jdbc,极大提高了我们的开发效率。但是使用 Mybatis 开发也有很多痛点: 2.每个 Mapper 文件都需要写一堆基本的增删改查语句。3.如果查询的列表需要分页,我们还需要给查询方法封装成分页对象。你可能会说:Mybatis 还能有痛点?用着多方便!对于小项目而言,用着确实还行。但是遇到大项目,光 Dao 接口都有几百个,如果还要手动定义一堆增删改查方法和 sql 语句,那也很浪费时间。那有没有这样一个框架:1.封装了

l688899886的博客 455

Labview及NI-USRP驱动安装教程

软件下载 安装使用的LabVIEW2018及NI-USRP驱动程序已上传,下载地址: 天翼云盘链接 (访问码:oc33) 百度网盘链接 (提取码:88mi) (注:天翼云盘下载不限速) LabVIEW2018安装步骤 右键软件压缩包选择解压至LabVIEW2018 选中文件,鼠标右击选择以管理员身份打开2018LV-WinChn.exe文件。 点击确定。 点击Unzip解压。 点击确定。 点击下一步。 填写任意信息后,点击下一步。 点击下一步。 点击浏览更改安装路径建议安装到除C盘以

dadapongi6的博客 2万+

mybatis和mybatisPlus中解决实体类字段与数据库关键字冲突问题

由于数据库表字段名称设计不合理,导致与MySQL数据库关键字或者预留关键字一致,在这种情况下,将会导致数据插入不成功。直接在实体类上添加 @TableField 注解,给上别名加上反单引号即可。( 反单引号在 键盘Esc键下面的那个,注意切换英文输入法 ) 引起来。1、针对XML文件,可以在冲突的字段名添加。

weixin_46483006的博客 9685

Android12 适配 usb 触屏

在 Android 系统中,输入设备 IDC(Input Device Configuration)设备描述文件(.idc)是用于配置和定义输入设备行为和属性的文本文件。 该文件通常在`/system/usr/idc/` 或 `/vendor/usr/idc/`,具体位置因芯片厂商SDK而异。一般情况此类文件是预置到系统,开发者 root 权限才能修改这些文件。输入设备 IDC 设备描述文件在 Android 系统中起到了识别、配置、映射和定制输入设备的作用,使得系统能够准确解析和处理各种输入设备的事件,提

weixin_35723192的博客 1234

全面指南:PyTorch与ROCm版本兼容性及多版本环境管理

本文详细介绍了在AMD GPU上配置PyTorch开发环境的完整流程,重点解决版本兼容性和多版本ROCm环境管理问题。主要内容包括:1) PyTorch与ROCm版本对应关系查询;2) 四种查看ROCm版本的方法;3) 使用update-alternatives管理多版本ROCm;4) 环境变量配置与冲突解决方案;5) 完整的验证流程和性能测试方法。文章提供了最佳实践建议和故障排除清单,帮助开发者快速搭建稳定高效的深度学习开发环境,充分发挥AMD GPU硬件性能。通过系统化的验证流程确保各组件协同工作,解决

数字人生 607

Trae 用户转向 Cursor?或许你听说过它吗:专为 Java 生态打造的深度集成方案

如果你正在 Trae 和 Cursor 之间纠结,或者对通用 AI 工具的 Java 适配不满意,不妨试试这款 Java 专属的 IDE 插件,毕竟,只有专注于单一领域的工具,才能把体验做到极致,让 Java 开发更高效、更舒心。它跟 Trae、Cursor 这类啥语言都敢接的 “全能选手” 不一样,一门心思扎在 Java 生态里,连 IDE 集成都做到了 “贴身适配”,就像给 Java 开发量身定做的 “定制西装”,比通用工具的 “均码外套” 合身一百倍,用了才知道啥叫 “专业的事交给专业的工具”。

CalEx_Tech的博客 655

大模型系列——Ollama简明教程

在这篇文章中,我们将了解如何使用 Ollama、如何在 Ollama 中创建自己的模型 以及如何使用 Ollama 构建聊天机器人。这是深入研究 Ollama 的第一部分,以及我所学到的有关本地 LLM 的知识以及如何将它们用于基于推理的应用程序。在这篇文章中,你将了解——

2401_84052244的博客 1万+

别又给我生成一堆 TODO:我们如何让 AI 告别 “留白式” 编程?

AI “留白式” 编程,本质上是通用 AI 不懂 Java 开发场景的 “后遗症”—— 它们想覆盖多语言,却对 Java 的语法规范、生态组件、业务逻辑一知半解,自然会用 TODO “甩锅”,生成 “半成品” 代码。它跟那些啥语言都敢写、一到复杂逻辑就甩 TODO 的通用 AI 不一样,一门心思扎在 Java 领域,连代码生成的 “完整性” 都做到了极致,就像给项目装了个 “TODO 橡皮擦”,能落地的逻辑直接写全,比通用 AI 的 “半成品代码” 靠谱一百倍,专治各种 “留白式” 编程。

CalEx_Tech的博客 770

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

告别“留白式”AI编程,Java开发者有救啦!

比如你复制了一段格式混乱的代码,用它一键整理后,缩进、换行、命名全规范了,提交代码时再也不用被格式检查打回,省了不少。最后还得开发者用代码整洁工具重新格式化,不然提交代码时,光格式检查就能被打回三次,简直让人崩溃。,结果生成的代码连库存扣减、日志记录都包含在内,直接复制到项目里就能用,省了两小时开发时间。括号位置不统一,有的换行,有的不换行;变量命名更是混乱,一会儿驼峰式,一会儿下划线式,上线前没注意,差点造成资金安全隐患,被领导狠狠批评了一顿,整个人都怀疑人生了。缩进忽多忽少,有的用空格,有的用。

CalEx_Tech的博客 435

文档:亲测可用解决vnc灰屏,黑屏,鼠标大黑叉情况

主要解决vnc-viewer灰屏,黑屏,鼠标大黑叉等现象,详细见文档。

MyBatis实践:提高持久层数据处理效率

编写SQL语句的文件的一般命名方式:......Mapper.xml(前缀名一般用数据库表名);工厂模式:如果创建一个对象,使用的过程基本固定,那么我们就可以把创建这个对象的相关代码封装到一个“工厂类”中,以后都使用这个工厂类来“生产”我们需要的对象。SqlSession:代表Java程序和数据库之间的会话(HttpSession是Java程序和浏览器之间的会话)MyBatis框架下,SQL语句编写位置发生改变,从原来的Java类,改成了xml或者注解定义。接口的全类名和映射配置文件的名称空间一致。

qq_26367907的博客 136

怀旧版电脑GBC模拟器

再现原版GBC掌机的界面,电脑运行连游戏界面都一样大小,很怀旧,很真实,(英文版)强烈推荐,很小的文件,很难才找到的。

MyBatis中 collection 的两种使用方法,及效率比较

方案一 &lt;resultMap type="Student" id="StudentMap"&gt; &lt;id column="id" property="id" /&gt; &lt;result column="name" property="name" /&gt;

hlz5857475的博客 2万+

同事问我飞速代码背后的秘密,我望着他笑着拿出了MybatisPlus~

1. Mybatis 存在的痛点 我们知道 MyBatis 是一个基于 java 的持久层框架,它内部封装了 jdbc,极大提高了我们的开发效率。 但是使用 Mybatis 开发也有很多痛点: 每个 Dao 接口都需要自己定义一堆增删改查方法。 /** * @Desc: UserDao 接口 * @Author: 公众号:知否技术 * @date: 下午7:43 2022/5/7 */ public interface UserDao { // 获取所有用户信息 List..

wdj_yyds的博客 2067

java mybatis 效率_提升开发效率的一款mybatis开发神器

文末附有完整案例的代码内容!!以前在开发的时候,使用mybatis的时候,经常都需要先配置xml映射文件,然后每条sql操作都需要自己进行手动编写,对于一些复杂的sql这么来操作确实有必要,但是如果只是一些非常简单的insert,update,delete,select这类型的语句而言,也需要开发人员花费额外的时间进行手动编写的话,确实费时又费力。能否为mybatis特别定制一套能够自动为我们生成...

weixin_39743064的博客 325

mybatis plus 查询优化及扩展

mybatis plus 中的查询优化 传统查询弊端 对于常规的mybatis单表查询,我们既可以采用LambdaQueryWrapper查询,也可以使用QueryWrapper查询。 LambdaQueryWrapper具有防误写、规范代码等好处,但是缺点是无法在复杂的多表查询中使用。 相比较来说,使用QueryWrapper编写查询更加灵活,可以适应更复杂的查询场景。 我们首先看一个QueryWrapper查询的例子 public List list (UserForm userForm) { Quer

liuerchong的博客 3029

Mybatis使用详情

ⅩⅣ.Mybatis ORM(Object Relational Mapping) 编写程序的时候,以面向对象的方式处理数据 保存数据的时候,却以关系型数据库的方式存储 ORM解决方案包含下面四个部分 在持久化对象上执行基本的增、删、改、查操作 对持久化对象提供一种查询语言或者API 对象关系映射工具 提供与事务对象交互、执行检查、延迟加载以及其他优化功能 Mybatis配置 1.jar包 导入mybatis-3.4.1.jar包 2.编写主配置文件 在src下创建 MyBatis 主配置文件 mybati

weixin_44194661的博客 2557

Spring Boot 集成 BeanSearcher:从配置到查询的完整步骤

BeanSearcher 是一款轻量级的 Java ORM 工具,专为简化数据库查询操作而设计。通过 Spring Boot 集成 BeanSearcher,开发者可以快速实现复杂条件的数据库查询,无需编写繁琐的 SQL 语句。本文将详细介绍从环境配置到实际查询的完整流程,帮助新手轻松掌握这一高效工具。 ## 一、快速入门:10分钟完成集成配置 ### 1.1 添加依赖坐标 在 Spring

gitblog_00182的博客 520

MyBatis系列(六):MyBatis动态Sql之if标签的用法

MyBatis动态Sql之if标签的用法

申城异乡人 2512

Mybatis系列第12篇:掌握缓存为查询提速!

Mybatis系列目标:从入门开始开始掌握一个高级开发所需要的Mybatis技能。 这是mybatis系列第12篇,源码位于文章尾部! 什么是缓存? 缓存就是存储数据的一个地方(称作:Cache),当程序要读取数据时,会首先从缓存中获取,有则直接返回,否则从其他存储设备中...

优快云_KONGlX的博客 358

mysql mybatis分页查询 大数据量 非常慢

然后自定义一个查询count的方法,在接口上面添加上@cacheable注解(具体实现自行百度),如果下一次查询的条件和上次的条件一致,则直接返回结果,就不需要跟数据库进行交互。为什么说这个方法对于连表查询有用呢,是因为连表查询,sql比较复杂,通过自带的count肯定查询条件一致,但是自定义的话就只查询主表数量就足够了,不需要连表进行count。看了很多帖子,要么就是数据库记录数据、或者来一条数据更新一下总数、或者多线程一个查询列表一个程序总数等等,这些方法都不适用于正常的待条件分页查询,可以忽略。

qq_36178165的博客 5865

mysql mybatis 查询数据特别慢

场景 mysql数据库中有50万条数据,采用的是mybatis+spring开发。当查询数据的时候不知道什么原因。查询执行需要10s才能查询出50条数据。这个执行速度让人不能接受 最后采用jdbc进项查询数据。2s就返回数据了。可能是mybatis设置的原因,也可能是其他原因。但是最终采用jdbc访问就ok了

wangliutao1的专栏 1万+
上一篇: 蚂蚁中间件五面:一致性Hash+分布式协议+RabbitMQ+亿级数据解决方案
下一篇: 头条抖音3面题:网络编程Socket+GC Roots+数据同步+事务+Redis
Java技术那些事儿
博客等级 码龄5年 2306粉丝 2584原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值