mybatis学习笔记

啥是Mybatis

  • MyBatis本是apache的一个开源项目iBatis,

  • 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis。

  • 2013年11月迁移到Github

  • iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。

  • iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。

  • 当前,最新版本是MyBatis 3.5.9,其发布时间是2021年12月26日。

如何获取

  • Maven:

    <!-- https://mvnrepository.com/artifact/org.mybatis/mybatis --> <dependency>    <groupId>org.mybatis</groupId>    <artifactId>mybatis</artifactId>    <version>3.5.9</version> </dependency>
  • GitHub: https:/lgithub.com/mybatis/mybatis-3/releases

  • 中文文档: https://mybatis.org/mybatis-3/zh/index.html

持久层框架

数据持久化

  • 持久化就是将数据在持久状态和瞬时状态转化的过程

  • 内存:断电即失

  • 数据库(jdbc),io文件持久化

  • 生活中的例子:冷藏,罐头;

为什么需要持久化

  • 有些对象,不能把它丢了

  • 内存太贵

持久层

(dao,server,Controller层)

  • 完成持久化工作的代码块

  • 层界限十分明显

为什么需要Mybatis

  • 帮助程序员将数据存放到数据库中

  • 方便

  • 传统的JDBC代码太复杂,而mybatis简化.框架.自动化

  • 使用的人多重点)spring,springMVC,springboot

  • 优点:

  • 简单易学:最简单安装只要两个jar文件+配置几个sql映射文件。易于学习,易于使用。通过文档和源代码,可以比较完全的掌握它的设计思路和实现。

  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。 sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。

  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。

  • 提供映射标签,支持对象与数据库的orm字段关系映射。

  • 提供对象关系映射标签,支持对象关系组建维护。

  • 提供xml标签,支持编写动态sql

2、第一个Mybatis 程序

思路:插入环境-->导入Mybatis-->编写代码-->测试!

2.1、搭建环境

创建数据库

drop database if exists ssm_test; create database ssm_test character set utf8; use ssm_test; DROP TABLE IF EXISTS `user`; CREATE TABLE `user` (  `id` int(0) UNSIGNED NOT NULL AUTO_INCREMENT,  `name` varchar(10) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,  `sex` char(6) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,  `pwd` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,  `email` varchar(20) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL,  PRIMARY KEY (`id`) USING BTREE ) ENGINE = InnoDB AUTO_INCREMENT = 7 CHARACTER SET = utf8 COLLATE = utf8_bin ROW_FORMAT = Dynamic; INSERT INTO `user` VALUES (2, 'java', '✔', 'aaaa', 'teat@163.com'); INSERT INTO `user` VALUES (3, '张三', '男', 'a', '67676@qq.com'); INSERT INTO `user` VALUES (4, '李四', '男', 'a', '7676776@qq.com'); INSERT INTO `user` VALUES (5, '王五', '女', 'a', '7575@qq.com'); INSERT INTO `user` VALUES (6, '赵六', '女', 'a', '123@qq.com'); INSERT INTO `user` VALUES (7, '测试', '男', 'aaaaa', '1234@qq.com');

新建项目

  1. 创建一个普通的 Maven项目

  2. 删除是src目录

  3. 导入maven依赖

<dependencies>        <!--mysql 依赖-->        <dependency>            <groupId>mysql</groupId>            <artifactId>mysql-connector-java</artifactId>            <version>5.1.47</version>        </dependency>        <!--mybatis 依赖-->        <dependency>            <groupId>org.mybatis</groupId>            <artifactId>mybatis</artifactId>            <version>3.5.3</version>        </dependency>        <!--junit 依赖-->        <dependency>            <groupId>junit</groupId>            <artifactId>junit</artifactId>            <version>4.12</version>            <scope>test</scope>        </dependency>    </dependencies>

2.2、创建一个子模块

编写一个Mybatis 工具类

package lv.utils; 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 java.io.IOException; import java.io.InputStream; public class MybatisUtil {    private static SqlSessionFactory sqlSessionFactory;    static {        try {            //使用Mybatis 获取SqlSessionFactory对象            String resource = "mybatis-config.xml";            InputStream inputStream = Resources.getResourceAsStream(resource);            sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);       } catch (IOException e) {            e.printStackTrace();       }   }    //既然有了 SqlSessionFactory,顾名思义,我们可以从中获得 SqlSession 的实例。    // SqlSession 提供了在数据库执行 SQL 命令所需的所有方法。    //你可以通过 SqlSession 实例来直接执行已映射的 SQL 语句。    public static SqlSession getSqlSession(){        return sqlSessionFactory.openSession();   } }

 

2.2、编写代码

pojo层

package lv.pojo; import lombok.AllArgsConstructor; import lombok.Data; import lombok.NoArgsConstructor; @Data @AllArgsConstructor @NoArgsConstructor public class User {    private int id;    private String name;    private String sex;    private String pwd;    private String email; }

mapper层

package lv.mapper; import lv.pojo.User; import java.util.List; public interface UserMapper {    List<User> getUserList(); }

(接口映射)接口实现类XXXmapper.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 = 绑定一个对应的mapper接口--> <mapper namespace="lv.mapper.UserMapper ">    <select id="getUserList" resultType="lv.pojo.User">       select * from ssm_test.user    </select> </mapper>

2.3、测试

注意点:

报错: org.apache.ibatis.binding.BindingException: Type interface lv.mapper.UserMapper is not known to the MapperRegistry.

org.apache.ibatis.binding.BindingException: Type interface lv.mapper.UserMapper is not known to the MapperRegistry. at org.apache.ibatis.binding.MapperRegistry.getMapper(MapperRegistry.java:47) at org.apache.ibatis.session.Configuration.getMapper(Configuration.java:779) at org.apache.ibatis.session.defaults.DefaultSqlSession.getMapper(DefaultSqlSession.java:291) at UserTest.test(UserTest.java:16) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

 

MapperRegistry是什么?

junit测试

 @Test    public void test(){        //1.获取Session 对象        SqlSession sqlSession = MybatisUtil.getSqlSession();        //2、执行sql        UserMapper mapper = sqlSession.getMapper(UserMapper.class);        List<User> list = mapper.getUserList();        for (User user : list) {            System.out.println(user);       }   }

再次报错

"C:\Program Files\Java\jdk1.8.0_221\bin\java.exe" -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar=58633:E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\bin" -Dfile.encoding=UTF-8 -classpath "E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\lib\idea_rt.jar;E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\plugins\junit\lib\junit5-rt.jar;E:\java\idea21.2.2\IntelliJ IDEA 2021.2.2\plugins\junit\lib\junit-rt.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_221\jre\lib\rt.jar;D:\learn\mybatis\mybatis-01\target\test-classes;D:\learn\mybatis\mybatis-01\target\classes;D:\maven\apache-maven-3.8.2\resource\mysql\mysql-connector-java\5.1.47\mysql-connector-java-5.1.47.jar;D:\maven\apache-maven-3.8.2\resource\org\mybatis\mybatis\3.5.3\mybatis-3.5.3.jar;D:\maven\apache-maven-3.8.2\resource\junit\junit\4.12\junit-4.12.jar;D:\maven\apache-maven-3.8.2\resource\org\hamcrest\hamcrest-core\1.3\hamcrest-core-1.3.jar;D:\maven\apache-maven-3.8.2\resource\org\projectlombok\lombok\1.18.8\lombok-1.18.8.jar" com.intellij.rt.junit.JUnitStarter -ideVersion5 -junit4 UserTest,test java.lang.ExceptionInInitializerError at UserTest.test(UserTest.java:14) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:498) at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runner.JUnitCore.run(JUnitCore.java:137) at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69) at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33) at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235) at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54) Caused by: org.apache.ibatis.exceptions.PersistenceException: ### Error building SqlSession. ### The error may exist in lv.mapper.UserMapper.xml ### Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource lv.mapper.UserMapper.xml at org.apache.ibatis.exceptions.ExceptionFactory.wrapException(ExceptionFactory.java:30) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:80) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:64) at lv.utils.MybatisUtil.<clinit>(MybatisUtil.java:18) ... 23 more Caused by: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: java.io.IOException: Could not find resource lv.mapper.UserMapper.xml at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:121) at org.apache.ibatis.builder.xml.XMLConfigBuilder.parse(XMLConfigBuilder.java:98) at org.apache.ibatis.session.SqlSessionFactoryBuilder.build(SqlSessionFactoryBuilder.java:78) ... 25 more Caused by: java.io.IOException: Could not find resource lv.mapper.UserMapper.xml at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:114) at org.apache.ibatis.io.Resources.getResourceAsStream(Resources.java:100) at org.apache.ibatis.builder.xml.XMLConfigBuilder.mapperElement(XMLConfigBuilder.java:372) at org.apache.ibatis.builder.xml.XMLConfigBuilder.parseConfiguration(XMLConfigBuilder.java:119) ... 27 more Process finished with exit code -1

 

解决方法(在pom.xml依赖中放入)

<!--在build中配置resources,来防止我们的资源导出失败-->    <build>        <resources>            <resource>                <directory>src/main/resources</directory>                <includes>                    <include>**/*.properties</include>                    <include>**/*.xml</include>                </includes>            </resource>            <resource>                <directory>src/main/java</directory>                <includes>                    <include>**/*.properties</include>                    <include>**/*.xml</include>                </includes>                <filtering>true</filtering>            </resource>        </resources>    </build>

2 .3CUID

2.1、namespace

namespace-->命名空间 中的包名 要和mapper 接口的包名一致!

2.2、select

select -->选择,查询语句;

属性

  • id-->与mapper 实现类中的方法名一致

  • resultType: 返回的数据类型,自动进行封装操作

  • parameterType: 给SQL语句传递参数的数据类型

  • resultMap: 查询结果返回的数据类型,根据结果集映射文件中的<resultMap>来完成数据封装

  • parameterMap: 给SQL语句传递参数的数据类型,需要和<parameterMap>标签连用

UserMapper

  //查询所有数据    List<User> getUserList();    //根据条件查询数据    User getUserById(int id);

UserMapper.xml

<!--查询所有用户信息-->    <select id="getUserList" resultType="com.lv.pojo.User">       select * from ssm_test.user    </select>    <!--根据用户id查询用户信息-->    <select id="getUserById" parameterType="int" resultType="com.lv.pojo.User">       select * from ssm_test.user where id = #{id}    </select>

Test

/* * 测试查询所有数据    * */    @Test    public void test(){        //1.获取Session 对象        SqlSession sqlSession = MybatisUtil.getSqlSession();        //2、执行sql        UserMapper mapper = sqlSession.getMapper(UserMapper.class);        List<User> list = mapper.getUserList();        for (User user : list) {            System.out.println(user);       }        sqlSession.close();   }    /*    * 测试根据条件 id 查询数据    * */    @Test    public void getUserById(){        //获取Session 对象        SqlSession session = MybatisUtil.getSqlSession();        UserMapper mapper = session.getMapper(UserMapper.class);        User user =mapper.getUserById(4);        System.out.println(user);        session.close();   }

 

2.3、insert

insert-->插入;

属性

  • parameterType: 入参的权限限定类名或类型别名;

  • keyColumn: 用于设置数据表自动生成的主键名

  • keyProperty(用来设置主键): 默认值unset ,用于设置getGeneratedKeys方法或selectKet子元素返回值将赋值到领域模型中的那个属性中

  • useGeneratedKeys ,取值范围true|false(默认值),设置是否使用JDBC的getGenereatedKeys方法获取主键并赋值到keyProperty设置的领域模型属性中。MySQL和SQLServer执行auto-generated key field,

    [因此当数据库设置好自增长主键后]: ,可通过JDBC的getGeneratedKeys方法获取。但像Oralce等不支持auto-generated key field的数据库就不能用这种方法获取主键了

  • statementType ,取值范围STATEMENT,PREPARED(默认值),CALLABLE

    flushCache ,取值范围true(默认值)|false,设置执行该操作后是否会清空二级缓存和本地缓存

    timeout ,默认为unset(依赖jdbc驱动器的设置),设置执行该操作的最大时限,超时将抛异常

    databaseId ,取值范围oracle|mysql等,表示数据库厂家,元素内部可通过<if test="_databaseId = 'oracle'">来为特定数据库指定不同的sql语句

UserMapper

int addUser(User user);

UserMapper.xml

<!--添加用户-->    <insert id="addUser" parameterType="com.lv.pojo.User" useGeneratedKeys="true" keyProperty="id">       insert into ssm_test.user(name,sex,pwd,email) values(#{name},#{sex},#{pwd},#{email})    </insert>

Test

/**     * 增删改需要提交事务     * */    /*    * 测试添加数据    * */    @Test    public void addUser(){        SqlSession sqlSession = MybatisUtil.getSqlSession();        UserMapper mapper = sqlSession.getMapper(UserMapper.class);        int res = mapper.addUser(new User(1,"MQQ","女","mmmmmm","mqq@.168"));        if (res>0) {            System.out.println("添加成功");       }        //提交事务        sqlSession.commit();        //关闭sqlSession        sqlSession.close();   }

2.4、update

UserMapper

  //修改用户信息    int updateUser(User user);

UserMapper.xml

   <!--更新用户信息-->    <update id="updateUser" parameterType="com.lv.pojo.User">       update ssm_test.user set name=#{name},sex=#{sex},pwd=#{pwd},email=#{email} where id=#{id}    </update>

Test

/*    *跟新用户数据    * */    @Test    public void updateTest(){        SqlSession sqlSession = MybatisUtil.getSqlSession();        UserMapper mapper = sqlSession.getMapper(UserMapper.class);        mapper.updateUser(new User(9,"mqq","女","ttttt","mqq@.168"));        //提交事务        sqlSession.commit();        //关闭sqlSession        sqlSession.close();   }

2.5、delete

UserMapper

 //删除用户信息    int deleteUser(int id);

UserMapper.xml

  <!--删除用户信息-->    <delete id="deleteUser" parameterType="int">       delete       from ssm_test.user       where id=#{id};    </delete>

Test

/*     *删除用户数据     * */    @Test    public void deleteTest(){        SqlSession sqlSession = MybatisUtil.getSqlSession();        UserMapper mapper = sqlSession.getMapper(UserMapper.class);        mapper.deleteUser(8);        //提交事务        sqlSession.commit();        //关闭sqlSession        sqlSession.close();   }

2.6、提示:增删改需要提交事务

 

3、分析错误

  • 标签的对应匹配!

  • resource 绑定mapper,需要使用路径!

  • 程序配置文件必须符合规范!

  • NullPointerException , 没有注册到资源!

  • 输出的XML文件中存在中文乱码问题!

  • maven 资源没有导出的问题!

4万能的Map

假如我们的实体类,或者数据库中的表,字段或者参数过多,我们应当考虑使用Map

UserMapper

User getUserByIdMap(Map<String,Object> map); /*使用Map集合添加一个用户*/ int addUserByMap(Map<String,Object> map);

UserMapper.xml

 <select id="getUserByIdMap" parameterType="map" resultType="com.lv.pojo.User">       select *       from ssm_test.user where id = #{userId} and name = #{userName};    </select>    <!--添加用户-->    <insert id="addUserByMap" parameterType="map" >       insert into ssm_test.user (id,name,sex,pwd,email)       values (#{userId},#{userName},#{suerSex},#{password},#{email});    </insert>

注:使用Map 时参数可以不与实体类的参数一致

但是参数与你map.put的键需要相同

Test

@Test    public void getUserByIdMap(){        SqlSession session = MybatisUtil.getSqlSession();        UserMapper mapper = session.getMapper(UserMapper.class);        Map<String, Object> map = new HashMap<>();        map.put("userId",4);        map.put("userName","李四");        final User user = mapper.getUserByIdMap(map);        System.out.println(user);        //关闭链接        session.close();   }

__EOF__

本文作者夜雨闻铃
本文链接https://www.cnblogs.com/sugeek/articles/16629675.html
关于博主:编程菜鸟一只,希望每个今天胜过昨天,一步步走向技术的高峰!
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   sugeek  阅读(19)  评论(0编辑  收藏  举报
(评论功能已被禁用)
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· winform 绘制太阳,地球,月球 运作规律
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 上周热点回顾(3.3-3.9)
· AI 智能体引爆开源社区「GitHub 热点速览」
· 写一个简单的SQL生成工具
点击右上角即可分享
微信分享提示