脚本之家

电脑版
提示:原网页已由神马搜索转码, 内容由www.jb51.net提供.
您的位置:首页软件编程java→ springboot 代码自动生成器

springboot整合freemarker代码自动生成器

  更新时间:2021年05月27日 11:38:26  作者:结构化思维wz 
最近做了一个工具,可以实现代码自动生成,今天整理出来分享给大家,需要的朋友们下面随着小编来一起学习学习吧

手撸一个代码自动生成器!!

实现功能:MyBatis 逆向工程

技术架构

页面是用 Vue ,element-ui开发;网络请求是 Axios。
服务端是 Spring Boot
页面模版是 Freemarker:

在这里插入图片描述

开发步骤:

一、创建工程

在这里插入图片描述

二、数据库连接操作

1.所需包结构

在这里插入图片描述

2.在model包中创建Db类

作用:用于接受前端传来数据库连接相关的值(username,password,url)

package com.example.generate_code.model;
/**
* @author: 王泽
*/
public class Db {
private String username;
private String password;
private String url;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = url;
}
}

3.在model中创建RespBean类

自定义响应类,返回数据更方便

package com.example.generate_code.model;
/**
* @author: 王泽
*/
public class RespBean {
private Integer status;
private String msg;
private Object obj;
public static RespBean ok(String msg,Object obj) {
return new RespBean(200, msg, obj);
}
public static RespBean ok(String msg) {
return new RespBean(200, msg, null);
}
public static RespBean error(String msg,Object obj) {
return new RespBean(500, msg, obj);
}
public static RespBean error(String msg) {
return new RespBean(500, msg, null);
}
private RespBean() {
}
private RespBean(Integer status, String msg, Object obj) {
this.status = status;
this.msg = msg;
this.obj = obj;
}
public Integer getStatus() {
return status;
}
public void setStatus(Integer status) {
this.status = status;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public Object getObj() {
return obj;
}
public void setObj(Object obj) {
this.obj = obj;
}
}

4.在Utils中创建DBUtils

JDBC连接工具类

public class DbUtils {
private static Connection connection;
public static Connection getConnection() {
return connection;
}
public static Connection initDb(Db db) {
if (connection == null) {
try {
Class.forName("com.mysql.cj.jdbc.Driver");
connection = DriverManager.getConnection(db.getUrl(), db.getUsername(), db.getPassword());
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
}
}
return connection;
}
}

5.写一个连接接口DbController

连接数据库

@RestController
public class DbController {
@PostMapping("/connect")
public RespBean connect(@RequestBody Db db) {
Connection con = DBUtils.initDb(db);
if (con != null) {
return RespBean.ok("数据库连接成功");
}
return RespBean.error("数据库连接失败");
}
}

6.创建index页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>代码生成工具</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<table>
<tr>
<td>
<el-tag size="mini">数据库用户名:</el-tag>
</td>
<td>
<el-input size="mini" v-model="db.username"></el-input>
</td>
</tr>
<tr>
<td>
<el-tag size="mini">数据库密码:</el-tag>
</td>
<td>
<el-input size="mini" v-model="db.password"></el-input>
</td>
</tr>
<tr>
<td>
<el-tag size="mini">数据库连接地址:</el-tag>
</td>
<td>
<el-input size="mini" v-model="db.url">
<template slot="prepend">jdbc:mysql://</template>
<template slot="append">
?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
</template>
</el-input>
</td>
</tr>
</table>
<div style="display: flex">
<el-button type="primary" size="mini" @click="connect" :disabled="!connectBtnEnabled">连接数据库</el-button>
<div style="color: #ff018d;font-weight: bold">[{{msg}}]</div>
<el-input v-model="packageName" size="mini" style="width: 300px"></el-input>
<el-button type="primary" size="mini" @click="config">配置</el-button>
</div>
</div>
<script>
new Vue({
el: "#app",
data: function () {
return {
packageName: '',
msg: '数据库未连接',
connectBtnEnabled: true,
db: {
username: "root",
password: "123456",
url: "localhost:3306/"
}
}
},
methods: {

connect() {
let _this = this;
this.db.url = "jdbc:mysql://" + this.db.url + "?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
axios.post('/connect', this.db)
.then(function (response) {
_this.msg = response.data.msg;
_this.db = {
username: "root",
password: "123456",
url: "localhost:3306/"
}
_this.connectBtnEnabled = false;
})
.catch(function (error) {
console.log(error);
});
}
}
})
</script>
</body>
</html>

在这里插入图片描述

三、加载数据表信息

1.服务器端编写

ColumnClass 用来描述表中的每一列

package com.example.generate_code.model;
/**
* @author: 王泽
*/
public class ColumnClass {
private String propertyName; //对应java属性的名字
private String columnName; //数据库中的名字
private String type; //字段类型
private String remark; //备注
private Boolean isPrimary; //字段是不是一个主键
@Override
public String toString() {
return "ColumnClass{" +
"propertyName='" + propertyName + '\'' +
", columnName='" + columnName + '\'' +
", type='" + type + '\'' +
", remark='" + remark + '\'' +
", isPrimary=" + isPrimary +
'}';
}
public String getPropertyName() {
return propertyName;
}
public void setPropertyName(String propertyName) {
this.propertyName = propertyName;
}
public String getColumnName() {
return columnName;
}
public void setColumnName(String columnName) {
this.columnName = columnName;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Boolean getPrimary() {
return isPrimary;
}
public void setPrimary(Boolean primary) {
isPrimary = primary;
}
}

描述一个具体的表的信息 TableClass

package com.example.generate_code.model;
import java.util.List;
/**
* @author: 王泽
*/
public class TableClass {
private String tableName; //表名 ,以下是生成的名字
private String modelName;
private String serviceName;
private String mapperName;
private String controllerName;
private String packageName;
private List<ColumnClass> columns; // 字段
@Override
public String toString() {
return "TableClass{" +
"tableName='" + tableName + '\'' +
", modelName='" + modelName + '\'' +
", serviceName='" + serviceName + '\'' +
", mapperName='" + mapperName + '\'' +
", controllerName='" + controllerName + '\'' +
", packageName='" + packageName + '\'' +
", columns=" + columns +
'}';
}
public String getTableName() {
return tableName;
}
public void setTableName(String tableName) {
this.tableName = tableName;
}
public String getModelName() {
return modelName;
}
public void setModelName(String modelName) {
this.modelName = modelName;
}
public String getServiceName() {
return serviceName;
}
public void setServiceName(String serviceName) {
this.serviceName = serviceName;
}
public String getMapperName() {
return mapperName;
}
public void setMapperName(String mapperName) {
this.mapperName = mapperName;
}
public String getControllerName() {
return controllerName;
}
public void setControllerName(String controllerName) {
this.controllerName = controllerName;
}
public String getPackageName() {
return packageName;
}
public void setPackageName(String packageName) {
this.packageName = packageName;
}
public List<ColumnClass> getColumns() {
return columns;
}
public void setColumns(List<ColumnClass> columns) {
this.columns = columns;
}
}

创建配置接口Controller

用map来接受前端传来的数据

用到了谷歌提供的工具包guava,需要导入依赖

 @PostMapping("/config")
public RespBean config(@RequestBody Map<String, String> map) {
String packageName = map.get("packageName");
try {
Connection connection = DBUtils.getConnection();
DatabaseMetaData metaData = connection.getMetaData();
ResultSet tables = metaData.getTables(connection.getCatalog(), null, null, null);
List<TableClass> tableClassList = new ArrayList<>();
while (tables.next()) {
TableClass tableClass = new TableClass();
tableClass.setPackageName(packageName);
String table_name = tables.getString("TABLE_NAME");
String modelName = CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, table_name);
tableClass.setTableName(table_name);
tableClass.setModelName(modelName);
tableClass.setControllerName(modelName + "Controller");
tableClass.setMapperName(modelName + "Mapper");
tableClass.setServiceName(modelName+"Service");
tableClassList.add(tableClass);
}
return RespBean.ok("数据库信息读取成功", tableClassList);
} catch (Exception e) {
e.printStackTrace();
}
return RespBean.error("数据库信息读取失败");
}
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>30.1-jre</version>
</dependency>

2.完善index页面

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>代码生成工具</title>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<!-- 引入样式 -->
<link rel="stylesheet" href="https://unpkg.com/element-ui/lib/theme-chalk/index.css">
<!-- 引入组件库 -->
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
</head>
<body>
<div id="app">
<table>
<tr>
<td>
<el-tag size="mini">数据库用户名:</el-tag>
</td>
<td>
<el-input size="mini" v-model="db.username"></el-input>
</td>
</tr>
<tr>
<td>
<el-tag size="mini">数据库密码:</el-tag>
</td>
<td>
<el-input size="mini" v-model="db.password"></el-input>
</td>
</tr>
<tr>
<td>
<el-tag size="mini">数据库连接地址:</el-tag>
</td>
<td>
<el-input size="mini" v-model="db.url">
<template slot="prepend">jdbc:mysql://</template>
<template slot="append">
?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai
</template>
</el-input>
</td>
</tr>
</table>
<div style="display: flex">
<el-button type="primary" size="mini" @click="connect" :disabled="!connectBtnEnabled">连接数据库</el-button>
<div style="color: #ff018d;font-weight: bold">[{{msg}}]</div>
<el-input v-model="packageName" size="mini" style="width: 300px"></el-input>
<el-button type="primary" size="mini" @click="config">配置</el-button>
</div>
<el-table
:data="tableData"
stripe
border
style="width: 100%">
<el-table-column
prop="tableName"
label="表名称"
width="180">
</el-table-column>
<el-table-column
label="实体类名称"
width="180">
<template slot-scope="scope">
<el-input v-model="scope.row.modelName"></el-input>
</template>
</el-table-column>
<el-table-column
label="Mapper名称">
<template slot-scope="scope">
<el-input v-model="scope.row.mapperName"></el-input>
</template>
</el-table-column>
<el-table-column
label="Service名称">
<template slot-scope="scope">
<el-input v-model="scope.row.serviceName"></el-input>
</template>
</el-table-column>
<el-table-column
label="Controller名称">
<template slot-scope="scope">
<el-input v-model="scope.row.controllerName"></el-input>
</template>
</el-table-column>
</el-table>
<div>
<el-button @click="generateCode" type="success">生成代码</el-button>
<div style="color: #ff0114;font-weight: bold">*{{result}}*</div>
<div>{{codePath}}</div>
</div>
</div>
<script>
new Vue({
el: "#app",
data: function () {
return {
tableData: [],
packageName: 'com.wangze.test',
msg: '数据库未连接',
connectBtnEnabled: true,
db: {
username: "root",
password: "123456",
url: "localhost:3306/"
}
}
},
methods: {
generateCode() {
let _this = this;
axios.post('/generateCode', this.tableData)
.then(function (response) {
_this.result = response.data.msg;
_this.codePath = response.data.obj;
})
.catch(function (error) {
});
},
config() {
let _this = this;
axios.post('/config', {packageName: this.packageName})
.then(function (response) {
_this.msg = response.data.msg;
_this.tableData = response.data.obj;
})
.catch(function (error) {
console.log(error);
});
},
connect() {
let _this = this;
this.db.url = "jdbc:mysql://" + this.db.url + "?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai";
axios.post('/connect', this.db)
.then(function (response) {
_this.msg = response.data.msg;
_this.db = {
username: "root",
password: "123456",
url: "localhost:3306/"
}
_this.connectBtnEnabled = false;
})
.catch(function (error) {
console.log(error);
});
}
}
})
</script>
</body>
</html>

在这里插入图片描述

四、代码生成

1.创建模板 Model.java.ftl

package ${packageName}.model;
import java.util.Date;
public class ${modelName}{
<#if columns??>
<#list columns as column>
<#if column.type='VARCHAR'||column.type='TEXT'||column.type='CHAR'>
/**
* ${column.remark}
*/
private String ${column.propertyName?uncap_first};
</#if>
<#if column.type='INT'>
/**
* ${column.remark}
*/
private Integer ${column.propertyName?uncap_first};
</#if>
<#if column.type='DATETIME'>
/**
* ${column.remark}
*/
private Date ${column.propertyName?uncap_first};
</#if>
<#if column.type='BIGINT'>
/**
* ${column.remark}
*/
private Long ${column.propertyName?uncap_first};
</#if>
<#if column.type='DOUBLE'>
/**
* ${column.remark}
*/
private Double ${column.propertyName?uncap_first};
</#if>
<#if column.type='BIT'>
/**
* ${column.remark}
*/
private Boolean ${column.propertyName?uncap_first};
</#if>
</#list>
</#if>
<#if columns??>
<#list columns as column>
<#if column.type='VARCHAR'||column.type='TEXT'||column.type='CHAR'>
public String get${column.propertyName}(){
return ${column.propertyName?uncap_first};
}
public void set${column.propertyName}(String ${column.propertyName?uncap_first}){
this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};
}
</#if>
<#if column.type='INT'>
public Integer get${column.propertyName}(){
return ${column.propertyName?uncap_first};
}
public void set${column.propertyName}(Integer ${column.propertyName?uncap_first}){
this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};
}
</#if>
<#if column.type='DATETIME'>
public Date get${column.propertyName}(){
return ${column.propertyName?uncap_first};
}
public void set${column.propertyName}(Date ${column.propertyName?uncap_first}){
this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};
}
</#if>
<#if column.type='BIGINT'>
public Long get${column.propertyName}(){
return ${column.propertyName?uncap_first};
}
public void set${column.propertyName}(Long ${column.propertyName?uncap_first}){
this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};
}
</#if>
<#if column.type='DOUBLE'>
public Double get${column.propertyName}(){
return ${column.propertyName?uncap_first};
}
public void set${column.propertyName}(Double ${column.propertyName?uncap_first}){
this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};
}
</#if>
<#if column.type='BIT'>
public Boolean get${column.propertyName}(){
return ${column.propertyName?uncap_first};
}
public void set${column.propertyName}(Boolean ${column.propertyName?uncap_first}){
this.${column.propertyName?uncap_first}=${column.propertyName?uncap_first};
}
</#if>
</#list>
</#if>
}

Service.java.ftl

package ${packageName}.service;
import ${packageName}.model.${modelName};
import ${packageName}.mapper.${mapperName};
import org.springframework.stereotype.Service;
import org.springframework.beans.factory.annotation.Autowired;
import java.util.List;
@Service
public class ${serviceName}{
@Autowired
${mapperName} ${mapperName?uncap_first};
public List<${modelName}> getAll${modelName}s(){
return ${mapperName?uncap_first}.getAll${modelName}s();
}
}

Controller.java.ftl

package ${packageName}.controller;
import ${packageName}.model.${modelName};
import ${packageName}.service.${serviceName};
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.GetMapping;
import java.util.List;
@RestController
public class ${controllerName}{
@Autowired
${serviceName} ${serviceName?uncap_first};
@GetMapping("/${modelName?lower_case}s")
public List<${modelName}> getAll${modelName}s(){
return ${serviceName?uncap_first}.getAll${modelName}s();
}
}

Mapper.java.ftl

package ${packageName}.mapper;
import ${packageName}.model.${modelName};
import org.apache.ibatis.annotations.Mapper;
import java.util.List;
@Mapper
public interface ${mapperName}{
List<${modelName}> getAll${modelName}s();
}

Mapper.xml.ftl

<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="${packageName}.mapper.${mapperName}">
<resultMap id="BaseResultMap" type="${packageName}.model.${modelName}">
<#list columns as column>
<<#if column.primary??>id<#else>result</#if> column="${column.columnName}" property="${column.propertyName?uncap_first}" jdbcType="<#if column.type='INT'>INTEGER<#elseif column.type='DATETIME'>TIMESTAMP<#elseif column.type='TEXT'>VARCHAR<#else>${column.type}</#if>" />
</#list>
</resultMap>
<select id="getAll${modelName}s" resultMap="BaseResultMap">
select * from ${tableName};
</select>
</mapper>

2.代码生成Controller

package com.example.generate_code.controller;
import com.example.generate_code.model.RespBean;
import com.example.generate_code.model.TableClass;
import com.example.generate_code.service.GenerateCodeService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
@RestController
public class GenerateCodeController {
@Autowired
GenerateCodeService generateCodeService;
@PostMapping("/generateCode")
public RespBean generateCode(@RequestBody List<TableClass> tableClassList, HttpServletRequest req) {
return generateCodeService.generateCode(tableClassList, req.getServletContext().getRealPath("/"));
}
}

3.编写service

package com.example.generate_code.service;
import com.example.generate_code.model.ColumnClass;
import com.example.generate_code.model.RespBean;
import com.example.generate_code.model.TableClass;
import com.example.generate_code.utils.DBUtils;
import com.google.common.base.CaseFormat;
import freemarker.cache.ClassTemplateLoader;
import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import org.springframework.stereotype.Service;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.List;
@Service
public class GenerateCodeService {
Configuration cfg = null;
{
cfg = new Configuration(Configuration.VERSION_2_3_30);
cfg.setTemplateLoader(new ClassTemplateLoader(GenerateCodeService.class, "/templates"));
cfg.setDefaultEncoding("UTF-8");
}
public RespBean generateCode(List<TableClass> tableClassList, String realPath) {
try {
Template modelTemplate = cfg.getTemplate("Model.java.ftl");
Template mapperJavaTemplate = cfg.getTemplate("Mapper.java.ftl");
Template mapperXmlTemplate = cfg.getTemplate("Mapper.xml.ftl");
Template serviceTemplate = cfg.getTemplate("Service.java.ftl");
Template controllerTemplate = cfg.getTemplate("Controller.java.ftl");
Connection connection = DBUtils.getConnection();
DatabaseMetaData metaData = connection.getMetaData();
for (TableClass tableClass : tableClassList) {
ResultSet columns = metaData.getColumns(connection.getCatalog(), null, tableClass.getTableName(), null);
ResultSet primaryKeys = metaData.getPrimaryKeys(connection.getCatalog(), null, tableClass.getTableName());
List<ColumnClass> columnClassList = new ArrayList<>();
while (columns.next()) {
String column_name = columns.getString("COLUMN_NAME");
String type_name = columns.getString("TYPE_NAME");
String remarks = columns.getString("REMARKS");
ColumnClass columnClass = new ColumnClass();
columnClass.setRemark(remarks);
columnClass.setColumnName(column_name);
columnClass.setType(type_name);
columnClass.setPropertyName(CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, column_name));
primaryKeys.first();
while (primaryKeys.next()) {
String pkName = primaryKeys.getString("COLUMN_NAME");
if (column_name.equals(pkName)) {
columnClass.setPrimary(true);
}
}
columnClassList.add(columnClass);
}
tableClass.setColumns(columnClassList);
String path = realPath + "/" + tableClass.getPackageName().replace(".", "/");
generate(modelTemplate, tableClass, path + "/model/");
generate(mapperJavaTemplate, tableClass, path + "/mapper/");
generate(mapperXmlTemplate, tableClass, path + "/mapper/");
generate(serviceTemplate, tableClass, path + "/service/");
generate(controllerTemplate, tableClass, path + "/controller/");
}
return RespBean.ok("代码已生成", realPath);
} catch (Exception e) {
e.printStackTrace();
}
return RespBean.error("代码生成失败");
}
private void generate(Template template, TableClass tableClass, String path) throws IOException, TemplateException {
File folder = new File(path);
if (!folder.exists()) {
folder.mkdirs();
}
String fileName = path + "/" + tableClass.getModelName() + template.getName().replace(".ftl", "").replace("Model", "");
FileOutputStream fos = new FileOutputStream(fileName);
OutputStreamWriter out = new OutputStreamWriter(fos);
template.process(tableClass,out);
fos.close();
out.close();
}
}

五、测试

在这里插入图片描述

在这里插入图片描述

这时候已经找到了,我们来验证一下效果!

在这里插入图片描述

修改写配置

spring.datasource.name=root
spring.datasource.password=123456
spring.datasource.url=jdbc:mysql://localhost:3306/boot_crm?useUnicode=true&characterEncoding=UTF-8&serverTimezone=Asia/Shanghai

pom.xml

<resources>
<resource>
<directory>src/main/java</directory>
<includes>
<include>**/*.xml</include>
</includes>
</resource>
<resource>
<directory>src/main/resources</directory>
</resource>
</resources>

导入生成的代码

在这里插入图片描述

运行测试

一个基本的mybatis逆向工程就完成了!

最后附上项目源代码:Gitee

到此这篇关于springboot整合freemarker代码自动生成器的文章就介绍到这了,更多相关springboot 代码自动生成器内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

    • 本篇文章主要是对通过url方式传递中文乱码的解决方法进行了介绍,需要的朋友可以过来参考下,希望对大家有所帮助
      2013-12-12
    • JDK开放给用户的源码中随处可见Native方法,被Native关键字声明的方法说明该方法不是以Java语言实现的,而是以本地语言实现的,Java可以直接拿来用。这里介绍下查找native方法的本地实现函数native_function,感兴趣的朋友跟随小编一起看看吧
      2021-12-12
    • 这篇文章主要介绍了Restful之通用返回格式类设计,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
      2023-12-12
    • 这篇文章主要介绍了Java实现数据库连接池的方法,涉及java数据库连接池的创建、连接、刷新、关闭及状态获取的常用技巧,具有一定参考借鉴价值,需要的朋友可以参考下
      2015-07-07
    • 这篇文章主要介绍了SpringCloud整合OpenFeign问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
      2024-05-05
    • 这篇文章主要给大家介绍了关于JDK更换IDEA如何修改的相关资料,Java的不同版本的JDK之间存在细微的差别,文中通过图文介绍的非常详细,需要的朋友可以参考下
      2023-07-07
    • 本篇文章主要介绍了SSM项目中配置LOG4J日志的方法,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
      2017-09-09
    • 本篇文章主要介绍了springMVC 几种页面跳转方式,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
      2017-02-02
    • 这篇文章主要介绍了Spring框架中Bean的各种加载方式详解,在Java中,"Bean"通常指的是由Spring框架管理的对象实例,Spring提供了多种方式来加载Bean,以满足不同的需求和场景,需要的朋友可以参考下
      2023-08-08
    • 今天小编就为大家分享一篇关于基于Java语言实现Socket通信的实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
      2019-01-01

    最新评论