当前位置: 首页 > news >正文

手写Mybatis框架源码(简写)

pom文件:

springboot版本:2.6.5

jdk:8

<?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"><modelVersion>4.0.0</modelVersion><groupId>org.example</groupId><artifactId>mybatis-boot</artifactId><version>1.0-SNAPSHOT</version><parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>2.6.5</version></parent><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!--web依赖--><dependency><!----><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!--测试--><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId></dependency><!--测试--><dependency><groupId>junit</groupId><artifactId>junit</artifactId><version>4.12</version><scope>test</scope></dependency><!--lombok依赖--><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><version>1.18.24</version></dependency><!--fastjson--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</artifactId><version>1.2.83</version></dependency><!--MySQL驱动--><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency><!--Dom4j依赖,比较流行的解析XML工具--><dependency><groupId>dom4j</groupId><artifactId>dom4j</artifactId><version>1.6.1</version></dependency><!--XPath(XML Path Language)的解析和查询库--><!--使用XPath表达式来查询和操作XML文档中的节点,从而实现对XML数据的处理和分析--><dependency><groupId>jaxen</groupId><artifactId>jaxen</artifactId><version>1.2.0</version></dependency><!--数据库连接池--><dependency><groupId>com.mchange</groupId><artifactId>c3p0</artifactId><version>0.9.5.5</version></dependency><!--在引入import注解的时候需要--><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.7</version> <!-- 确保使用兼容的版本 --></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.7</version> <!-- 确保使用兼容的版本 --></dependency><!--reflections--><dependency><groupId>org.reflections</groupId><artifactId>reflections</artifactId><version>0.9.12</version> <!-- 确保使用兼容的版本 --></dependency></dependencies></project>
  1. mybatis执行原理(自己理解的)通过mapper注解或者是mapperscan注解去读取相应的mapper接口,通过这些接口文件的类对象去实现动态代理,通过动态代理实现了一个动态对象,将这个动态对象加入到bean对象当中。在启动的时候顺便将mapper的xml的各种数据进行一个保存,通过这些数据可以拿到操作sql的sql语句和入参类型和返回类型。

代码的实现:

  1. 启动类:
    package org.example;import org.example.anno.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;@SpringBootApplication
    @MapperScan(value = "org.example.mapper") //自己实现的Mapper注解
    public class MybatisApplication {public static void main(String[] args) {SpringApplication.run(MybatisApplication.class,args);}
    }

2、MapperScan注解:

package org.example.anno;import org.example.handler.RegisterBeanMapperHandler;
import org.springframework.context.annotation.Import;import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Target(ElementType.TYPE) //注解的位置
@Retention(RetentionPolicy.RUNTIME) //运行时
@Import(RegisterBeanMapperHandler.class)   //注解的注册器
public @interface MapperScan {String value() default "";
}

3、MapperScan的注册器:

package org.example.handler;import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.DocumentException;
import org.example.anno.MapperScan;
import org.example.config.Configurations;
import org.example.dto.SqlData;
import org.example.executor.Executor;
import org.example.executor.impl.ExecutorImpl;
import org.example.session.Session;
import org.example.session.SessionInit;
import org.reflections.Reflections;
import org.reflections.scanners.SubTypesScanner;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.annotation.ImportBeanDefinitionRegistrar;
import org.springframework.core.type.AnnotationMetadata;import java.beans.PropertyVetoException;
import java.lang.reflect.*;
import java.util.*;/*** 实现了bean的注册器,同时还实现了session接口,这个接口是自己实现的*/
@Slf4j
public class RegisterBeanMapperHandler implements ImportBeanDefinitionRegistrar, Session {private Configurations configurations; //xml的数据记录/*** * @param importingClassMetadata  添加了import注解的处理器对象* @param registry  注册器*/@SneakyThrows   //lombok的异常处理@Overridepublic void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {//判断是否含有MapperScan注解if (!importingClassMetadata.isAnnotated(MapperScan.class.getName())) {return;}//获取mapperscan注解的属性Map<String, Object> annotationAttributes = importingClassMetadata.getAnnotationAttributes(MapperScan.class.getName());//获取这个mapper包的值String value = (String) annotationAttributes.get("value");//处理mapper.xml和数据库configurations = SessionInit.init();log.info("value: {}",value);//生成mapper接口的动态代理Map<String, Object> map = readMapperPackageData(value);if (registry instanceof DefaultListableBeanFactory){DefaultListableBeanFactory factory = (DefaultListableBeanFactory) registry;for (Map.Entry<String, Object> entry : map.entrySet()) {//将mapper生成的动态代理添加到bean容器当中,通过名字添加factory.registerSingleton(entry.getKey(),entry.getValue());}}}/*** * @param path 包名* @return* @throws ClassNotFoundException* @throws PropertyVetoException* @throws DocumentException*/public Map<String,Object> readMapperPackageData(String path) throws ClassNotFoundException, PropertyVetoException, DocumentException {Map<String,Object> map = new HashMap<>();//reflections的坑:是否excludeObjectClass排除这个包下的,默认为true。Reflections reflections = new Reflections(path,new SubTypesScanner(false));//如果默认为true,就会报SubType为null,就是说找不到Object相应的数据Set<Class<?>> allMapper = reflections.getSubTypesOf(Object.class);for (Class<?> aClass : allMapper) {//获取动态代理对象map.put(aClass.getSimpleName(),getMapper(aClass));}return map;}@Overridepublic <E> List<E> selectList(SqlData sqlData, Object... params) throws Exception {Executor executor = new ExecutorImpl();List<Object> query = executor.query(configurations, sqlData, params);return (List<E>) query;}@Overridepublic <E> E select(SqlData sqlData, Object... params) throws Exception {List<Object> objects = selectList(sqlData, params);if (objects == null || objects.size() ==0){return null;}if (objects.size()>1){throw new RuntimeException("查到不止一个");}return (E) objects.get(0);}@Overridepublic <E> E insert(SqlData sqlData, Object... params) throws Exception {Executor executor = new ExecutorImpl();List<Object> query = executor.query(configurations, sqlData, params);return (E) query.get(0);}@Overridepublic <E> E update(SqlData sqlData, Object... params) throws Exception {Executor executor = new ExecutorImpl();List<Object> query = executor.query(configurations, sqlData, params);return (E) query.get(0);}@Overridepublic <E> E delete(SqlData sqlData, Object... params) throws Exception {Executor executor = new ExecutorImpl();List<Object> query = executor.query(configurations, sqlData, params);return (E) query.get(0);}/*** * @param mapperType 要生成动态代理的类对象* @return* @param <T>* @throws PropertyVetoException* @throws DocumentException*/@Overridepublic <T> T getMapper(Class<?> mapperType) throws PropertyVetoException, DocumentException {//生成代理,通过代理处理你想要的结果Object instance =Proxy.newProxyInstance(mapperType.getClassLoader(), new Class[]{mapperType}, new InvocationHandler() {/*** method是动态代理对象的某个方法,args是这个方法的参数*/@Overridepublic Object invoke(Object proxy, Method method, Object[] args) throws Throwable {//获得method的名字和类,拼接之后得到sql的数据,拿到sql的数据去执行相应的逻辑String methodName = method.getName();String className = method.getDeclaringClass().getName();//返回类型Type genericReturnType = method.getGenericReturnType();//通过这个去configurations拿值String key = className+"."+methodName;SqlData sqlData = configurations.getMap().get(key);//相应方法的sql数据String sqlType = sqlData.getType();if ("insert".equals(sqlType)){return insert(sqlData,args);}else if ("update".equals(sqlType)){return update(sqlData,args);} else if ("delete".equals(sqlType)) {return delete(sqlData,args);}//是否是参数化类型if (genericReturnType instanceof ParameterizedType){return selectList(sqlData,args);}else{return select(sqlData,args);}}});//返回动态代理对象return (T) instance;}
}

4、configurations:

package org.example.config;import lombok.Data;
import org.example.dto.SqlData;
import org.springframework.stereotype.Component;import javax.sql.DataSource;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;@Component
@Data
public class Configurations {private DataSource dataSource;Map<String, SqlData> map = new ConcurrentHashMap<>();
}

5、session:

package org.example.session;import org.dom4j.DocumentException;
import org.example.dto.SqlData;import java.beans.PropertyVetoException;
import java.util.List;public interface Session {<E>List<E> selectList(SqlData sqlData,Object ...params) throws Exception;<E> E select(SqlData sqlData,Object ...params) throws Exception;<E> E insert(SqlData sqlData,Object ...params) throws Exception;<E> E update(SqlData sqlData,Object ...params) throws Exception;<E> E delete(SqlData sqlData,Object ...params) throws Exception;<T> T getMapper(Class<?> mapperType) throws PropertyVetoException, DocumentException;
}

6、SessionInit:

package org.example.session;import lombok.Data;
import org.dom4j.DocumentException;
import org.example.config.Configurations;
import org.example.service.DatasourceXml;
import org.example.service.XmlBuilderService;
import org.springframework.stereotype.Component;import javax.annotation.PostConstruct;
import java.beans.PropertyVetoException;@Data
public class SessionInit {public static Configurations init() throws DocumentException, PropertyVetoException {Configurations configuration = new Configurations();//解析xml mapperXmlBuilderService xmlBuilderService = new XmlBuilderService(configuration);xmlBuilderService.parse();//数据库配置DatasourceXml datasourceXml = new DatasourceXml(configuration);datasourceXml.parse();//配置完之后,开始容器的创建,将所有的mapper进行封装,生成代理//通过返回bean对象将代理对象都交给bean容器管理return configuration;}
}

7、XmlBuilderMapper:

package org.example.service;import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;
import org.example.config.Configurations;
import org.example.dto.SqlData;import javax.annotation.PostConstruct;
import java.io.File;
import java.util.List;public class XmlBuilderService {private Configurations configuration;public XmlBuilderService(Configurations configuration) {this.configuration = configuration;}/*** 我在这里把地址写死了,当然可以在配置文件当中设置* @throws DocumentException*/public void parse() throws DocumentException {File folder = new File("src/main/resources/mapper");File[] files = folder.listFiles((dir,name)->{return name.endsWith(".xml");});for (File file : files) {SAXReader saxReader = new SAXReader();Document read = saxReader.read(file);Element readElements = read.getRootElement();//主标签上的属性String namespace = readElements.attributeValue("namespace");//主标签下的所有标签List<Element> elements = readElements.elements();//按照对应的namespace去找这个mapper对应的方法for (Element element : elements) {String name = element.getName();String id = element.attributeValue("id");String resultType = element.attributeValue("resultType");String parameterType = element.attributeValue("parameterType");String textTrim = element.getTextTrim();//解析为相应的数据,保存到configurations当中SqlData sqlData = new SqlData();sqlData.setId(id);sqlData.setSql(textTrim);sqlData.setParameterType(parameterType);sqlData.setResultType(resultType);sqlData.setType(name);String key = namespace+"."+id;System.out.println(key);configuration.getMap().put(namespace+"."+id,sqlData);}}}
}
<!--resource mapper包下的一个xml-->
<?xml version="1.0" encoding="UTF-8" ?><mapper namespace="org.example.mapper.OrderMapper"><select id="getList" resultType="org.example.entity.Order">select*from orders</select><update id ="update" resultType="java.lang.Integer" parameterType="org.example.entity.Order">update ordersset orders = #{orders},date=#{date}where id = #{id}</update><delete id="delete" resultType="java.lang.Integer" parameterType="org.example.entity.Order">delete from orderswhere id = #{id}</delete><insert id="insert" resultType="java.lang.Integer" parameterType="org.example.entity.Order">insert into orders values (#{id},#{orders},#{date})</insert>
</mapper>

8、DatasourceXmlBuilder:我在这里写死了,当然可以通过解析或者配置yml文件去读取

package org.example.service;import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.example.config.Configurations;import java.beans.PropertyVetoException;public class DatasourceXml {private Configurations configuration;public DatasourceXml(Configurations configuration) {this.configuration = configuration;}public void parse() throws PropertyVetoException {ComboPooledDataSource dataSource= new ComboPooledDataSource();dataSource.setDriverClass("com.mysql.cj.jdbc.Driver");dataSource.setJdbcUrl("jdbc:mysql://localhost:3306/ds0");dataSource.setUser("root");dataSource.setPassword("root");configuration.setDataSource(dataSource);}
}

SqlData:

package org.example.dto;import lombok.Data;@Data
public class SqlData {//方法名private String id;//返回类型private String resultType;//参数类型private String parameterType;//sql语句private String sql;//sql类型,select、update等等private String type;
}

BoundSql:

package org.example.dto;import lombok.Data;import java.util.ArrayList;
import java.util.List;@Data
public class BoundSql {//sql语句private String sql;//解析出来的sql当中的参数private List<String> paramsList =new ArrayList<>();
}

ExectuorImpl: 这段代码就不加注释了,自己理解了就好理解整个过程。

package org.example.executor.impl;import com.sun.deploy.ui.AboutDialog;
import org.example.config.Configurations;
import org.example.dto.BoundSql;
import org.example.dto.SqlData;
import org.example.executor.Executor;import javax.print.DocFlavor;
import javax.sql.DataSource;
import java.beans.IntrospectionException;
import java.beans.PropertyDescriptor;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.sql.*;
import java.util.*;public class ExecutorImpl implements Executor {@Overridepublic <T> List<T> query(Configurations configurations, SqlData sqlData, Object... args) throws SQLException, ClassNotFoundException, NoSuchFieldException, IllegalAccessException, InstantiationException, IntrospectionException, InvocationTargetException {DataSource dataSource = configurations.getDataSource();Connection connection = dataSource.getConnection();BoundSql boundSql = handleSql(sqlData.getSql());//String parameterType = sqlData.getParameterType();String sql = boundSql.getSql();List<String> paramsList = boundSql.getParamsList();PreparedStatement preparedStatement = connection.prepareStatement(sql);for (int i = 0; i < paramsList.size(); i++) {//参数替换,通过Method方法获取某个对象中某个对应的值String param = paramLists.get(i);Object arg = args[0];Class<?> type = getType(parameterType);//获取字段的对象,通过字段对象去匹配赋值Field declaredField = type.getDeclaredField(param);declaredField.setAccessible(true);Object filedValue = declaredField.get(arg);preparedStatement.setObject(i + 1, filedValue);}ResultSet resultSet;if ("select".equals(sqlData.getType())) {resultSet = preparedStatement.executeQuery();} else {int i = preparedStatement.executeUpdate();List<Integer> list = new ArrayList<>();list.add(i);return (List<T>) list;}if (resultSet == null){return null;}List<Object> resultList = new ArrayList<>(resultSet.getRow());String resultType = sqlData.getResultType();while (resultSet.next()){ResultSetMetaData metaData = resultSet.getMetaData();//获取列数int columnCount = metaData.getColumnCount();//创建一个返回类型的类对象Class<?> returnType = getType(resultType);//通过类对象创建一个返回对象Object instance = returnType.newInstance();for (int i = 1; i <= columnCount; i++) {//获取列的名字String columnName = metaData.getColumnName(i);System.out.println(columnName);//通过列的名字取值,并将列返回Object result = resultSet.getObject(columnName);System.out.println(result);//将列名与返回的类对象进行匹配PropertyDescriptor propertyDescriptor = new PropertyDescriptor(columnName,returnType);//得到一个写入方法Method writeMethod = propertyDescriptor.getWriteMethod();//将值写入到这个对象当中writeMethod.invoke(instance,result);}resultList.add(instance);}return (List<T>) resultList;}private Map<Integer,Integer> mapIndex = new LinkedHashMap<>();private List<String> paramLists = new ArrayList<>();private int fromIndex = 0;private BoundSql handleSql(String sql){submitSql(sql);for (Map.Entry<Integer, Integer> entry : mapIndex.entrySet()) {Integer begin = entry.getKey();Integer end = entry.getValue();String substring = sql.substring(begin + 2, end);paramLists.add(substring);}BoundSql boundSql = new BoundSql();for (String paramList : paramLists) {sql = sql.replace("#{" + paramList + "}", "?");boundSql.getParamsList().add(paramList);}boundSql.setSql(sql);//boundSql.setParamsList(paramLists);return boundSql;}private void submitSql(String sql) {int beginIndex = sql.indexOf("#{", fromIndex);if (beginIndex != -1){int endIndex = sql.indexOf("}", fromIndex + 1);if (endIndex != -1){fromIndex = endIndex+1;mapIndex.put(beginIndex,endIndex);submitSql(sql);}}}private Class<?> getType(String type) throws ClassNotFoundException {if (null == type || type.equals("")){return null;}return Class.forName(type);}}

总结:

总得来说,通过Proxy生成代理对象,通过代理对象调用相应的方法,相应的方法从configurations拿到相应的方法需要执行的sql语句。通过这个sql语句去执行JDBC基础的语句,也就是通过Connections去执行语句。

代码地址:lr-cc/fff

相关文章:

手写Mybatis框架源码(简写)

pom文件&#xff1a; springboot版本&#xff1a;2.6.5 jdk&#xff1a;8 <?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&q…...

Flask返回中文Unicode编码(乱码)解决方案

大家好,我是爱编程的喵喵。双985硕士毕业,现担任全栈工程师一职,热衷于将数据思维应用到工作与生活中。从事机器学习以及相关的前后端开发工作。曾在阿里云、科大讯飞、CCF等比赛获得多次Top名次。现为CSDN博客专家、人工智能领域优质创作者。喜欢通过博客创作的方式对所学的…...

最大值和最小值的差

最大值和最小值的差 C语言代码C 语言代码Java语言代码Python语言代码 &#x1f490;The Begin&#x1f490;点点关注&#xff0c;收藏不迷路&#x1f490; 输出一个整数序列中最大的数和最小的数的差。 输入 第一行为M&#xff0c;表示整数个数&#xff0c;整数个数不会大于1…...

如何在 IntelliJ IDEA 中为 Spring Boot 应用实现热部署

文章目录 1. 引言2. 准备工作3. 添加必要的依赖4. 配置 IntelliJ IDEA4.1 启用自动编译4.2 开启热部署策略 5. 测试热部署6. 高级技巧7. 注意事项8. 总结 随着现代开发工具的进步&#xff0c;开发者们越来越重视提高生产力的特性。对于 Java 开发者来说&#xff0c;能够在不重启…...

探索 Java 中的 Bug 世界

在 Java 编程的旅程中&#xff0c;我们不可避免地会遇到各种 Bug。这些 Bug 可能会导致程序出现意外的行为、崩溃或者性能问题。了解 Java Bug 的类型、产生原因以及解决方法&#xff0c;对于提高我们的编程技能和开发出稳定可靠的应用程序至关重要。 一、Java Bug 的定义与分类…...

SQL面试题——百度SQL面试题 连续签到领金币

百度SQL面试题 连续签到领金币 今天的这个题目来自百度,而且这个题目很常见,是一个大家日常经常遇到的一个场景,几乎无处不在,就是签到送积分,只不过这里是签到领金币 有用户签到记录表,sign,记录用户当天是否完成签到,请计算出每个用户的每个月获得的金币数量; 签到…...

easyExcel单一下拉框和级联下拉框

文章目录&#xff1a; 单一下拉框级联下拉框 具体实现&#xff1a; 单一下拉框 public class BoolWriteHandler implements SheetWriteHandler {private List<String> dropDown;private List<Integer> indexList;public BoolWriteHandler(List<Integer> i…...

linux-安全-iptables防火墙基础笔记

目录 一、 iptables链结构 五链 二、 iptables表结构 四表 三、 匹配流程 四、 语法 五、 匹配 1. 通用匹配 2. 隐含匹配 3. 显示匹配 六、 SNAT 七、 DNAT 八、 规则备份及还原 1. 备份 2. 还原 这篇将讲解iptables防火墙的基础知识 一、 iptables链结构 规则…...

力扣刷题TOP101: 25.BM32合并二叉树

目录&#xff1a; 目的 思路 复杂度 记忆秘诀 python代码 目的&#xff1a; 已知两颗二叉树&#xff0c;将它们合并成一颗二叉树。合并规则是&#xff1a;都存在的结点&#xff0c;就将结点值加起来&#xff0c;否则空的位置就由另一个树的结点来代替。 思路 我们有两棵二…...

R的中文文本处理包--tmcn

文章目录 介绍tmcn 和 jieba 的关系函数&#xff1a;catUTF8toUTF8实例 介绍 tmcn 包是 R 语言中的一个用于处理和分析中文文本的包&#xff0c;特别适用于中文文本的分词、词频统计和文本挖掘等任务。以下是 tmcn 包的基本用法&#xff0c;包括安装、常用函数和示例。 一个用…...

差异基因富集分析(R语言——GOKEGGGSEA)

接着上次的内容&#xff0c;上篇内容给大家分享了基因表达量怎么做分组差异分析&#xff0c;从而获得差异基因集&#xff0c;想了解的可以去看一下&#xff0c;这篇主要给大家分享一下得到显著差异基因集后怎么做一下通路富集。 1.准备差异基因集 我就直接把上次分享的拿到这…...

scrapy对接rabbitmq的时候使用post请求

之前做分布式爬虫的时候,都是从push url来拿到爬虫消费的链接,这里提出一个问题,假如这个请求是post请求的呢,我观察了scrapy-redis的源码,其中spider.py的代码是这样写的 1.scrapy-redis源码分析 def make_request_from_data(self, data):"""Returns a Reques…...

vue+elementUI+transition实现鼠标滑过div展开内容,鼠标划出收起内容,加防抖功能

文章目录 一、场景二、实现代码1.子组件代码结构2.父组件 一、场景 这两天做项目&#xff0c;此产品提出需求 要求详情页的顶部区域要在鼠标划入后展开里面的内容&#xff0c;鼠标划出要收起部分内容&#xff0c;详情底部的内容高度要自适应&#xff0c;我这里运用了鼠标事件t…...

大模型语料库的构建过程 包括知识图谱构建 垂直知识图谱构建 输入到sql构建 输入到cypher构建 通过智能体管理数据生产组件

以下是大模型语料库的构建过程&#xff1a; 一、文档切分语料库构建 数据来源确定&#xff1a; 首先&#xff0c;需要确定语料库的数据来源。这些来源可以是多种多样的&#xff0c;包括但不限于&#xff1a; 网络资源&#xff1a;利用网络爬虫技术从各种网站&#xff08;如新闻…...

阿里云ECS服务器域名解析

阿里云ECS服务器域名解析&#xff0c;以前添加两条A记录类型&#xff0c;主机记录分别为www和&#xff0c;这2条记录都解析到服务器IP地址。 1.进入阿里云域名控制台&#xff0c;找到域名 ->“解析设置”->“添加记录” 2.添加一条记录类型为A,主机记录为www&#xff0c…...

牛客周赛71:A:JAVA

链接&#xff1a;登录—专业IT笔试面试备考平台_牛客网 来源&#xff1a;牛客网 题目描述 \hspace{15pt}对于给定的两个正整数 nnn 和 kkk &#xff0c;是否能构造出 kkk 对不同的正整数 (x,y)(x,y)(x,y) &#xff0c;使得 xynxynxyn 。 \hspace{15pt}我们认为两对正整数 (…...

查询产品所涉及的表有(product、product_admin_mapping)

文章目录 1、ProductController2、AdminCommonService3、ProductApiService4、ProductCommonService5、ProductSqlService1. 完整SQL分析可选部分&#xff08;条件筛选&#xff09;&#xff1a; 2. 涉及的表3. 总结4. 功能概述 查询指定管理员下所有产品所涉及的表&#xff1f;…...

算法基础学习Day5(双指针、动态窗口)

文章目录 1.题目2.题目解答1.四数之和题目及题目解析算法学习代码提交 2.长度最小的子数组题目及题目解析滑动窗口的算法学习方法一&#xff1a;单向双指针(暴力解法)方法二&#xff1a;同向双指针(滑动窗口) 代码提交 1.题目 18. 四数之和 - 力扣&#xff08;LeetCode&#x…...

docker 部署 mysql 9.0.1

docker 如何部署 mysql 9 &#xff0c;请看下面步骤&#xff1a; 1. 先看 mysql 官网 先点进去 8 版本的 Reference Manual 。 选择 9.0 版本的。 点到这里来看&#xff0c; 这里有一些基础的安装步骤&#xff0c;可以看一下。 - Basic Steps for MySQL Server Deployment wit…...

关于小标join大表,操作不当会导致笛卡尔积,数据倾斜

以前总是说笛卡尔积&#xff0c;笛卡尔积&#xff0c;没碰到过&#xff0c;今天在跑流程调度时&#xff0c;就碰到笛卡尔积了&#xff0c;本来&#xff0c;就是查询几个编码的信息&#xff0c;然后由于使用的是with tmp as&#xff0c;没使用where in ,所以跑的很慢 现象&#…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

第19节 Node.js Express 框架

Express 是一个为Node.js设计的web开发框架&#xff0c;它基于nodejs平台。 Express 简介 Express是一个简洁而灵活的node.js Web应用框架, 提供了一系列强大特性帮助你创建各种Web应用&#xff0c;和丰富的HTTP工具。 使用Express可以快速地搭建一个完整功能的网站。 Expre…...

使用VSCode开发Django指南

使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架&#xff0c;专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用&#xff0c;其中包含三个使用通用基本模板的页面。在此…...

大话软工笔记—需求分析概述

需求分析&#xff0c;就是要对需求调研收集到的资料信息逐个地进行拆分、研究&#xff0c;从大量的不确定“需求”中确定出哪些需求最终要转换为确定的“功能需求”。 需求分析的作用非常重要&#xff0c;后续设计的依据主要来自于需求分析的成果&#xff0c;包括: 项目的目的…...

关于nvm与node.js

1 安装nvm 安装过程中手动修改 nvm的安装路径&#xff0c; 以及修改 通过nvm安装node后正在使用的node的存放目录【这句话可能难以理解&#xff0c;但接着往下看你就了然了】 2 修改nvm中settings.txt文件配置 nvm安装成功后&#xff0c;通常在该文件中会出现以下配置&…...

【解密LSTM、GRU如何解决传统RNN梯度消失问题】

解密LSTM与GRU&#xff1a;如何让RNN变得更聪明&#xff1f; 在深度学习的世界里&#xff0c;循环神经网络&#xff08;RNN&#xff09;以其卓越的序列数据处理能力广泛应用于自然语言处理、时间序列预测等领域。然而&#xff0c;传统RNN存在的一个严重问题——梯度消失&#…...

深度学习习题2

1.如果增加神经网络的宽度&#xff0c;精确度会增加到一个特定阈值后&#xff0c;便开始降低。造成这一现象的可能原因是什么&#xff1f; A、即使增加卷积核的数量&#xff0c;只有少部分的核会被用作预测 B、当卷积核数量增加时&#xff0c;神经网络的预测能力会降低 C、当卷…...

MFC 抛体运动模拟:常见问题解决与界面美化

在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...

Windows安装Miniconda

一、下载 https://www.anaconda.com/download/success 二、安装 三、配置镜像源 Anaconda/Miniconda pip 配置清华镜像源_anaconda配置清华源-CSDN博客 四、常用操作命令 Anaconda/Miniconda 基本操作命令_miniconda创建环境命令-CSDN博客...

人工智能--安全大模型训练计划:基于Fine-tuning + LLM Agent

安全大模型训练计划&#xff1a;基于Fine-tuning LLM Agent 1. 构建高质量安全数据集 目标&#xff1a;为安全大模型创建高质量、去偏、符合伦理的训练数据集&#xff0c;涵盖安全相关任务&#xff08;如有害内容检测、隐私保护、道德推理等&#xff09;。 1.1 数据收集 描…...