springboot入门简单使用
- 1、SpringBoot项目创建并配置mysql数据库
- 创建项目
- 编写Controller测试
- 配置数据库
- 2、SpringBoot集成mybatis-plus
- 初始化数据库
- 安装mybatis-plus
- 通过mybatis-plus将数据库数据通过接口显示
- 3、SpringBoot三层架构Controller、Service、Dao
- 4、SpringBoot集成Mabatis-plus编写增删改查接口
- 其他
- 热部署集成
- mybatis-plus日志打印
- 跨域问题解决
- SpringBoot项目配置多环境
- SpringBoot返回结果统一封装
- 分页封装
- 参数校验
- 自定义异常和全局异常捕获
- 自定义异常
- 自动生成entity实体类
1、SpringBoot项目创建并配置mysql数据库
创建项目
开发环境:idea
使用 Spring Initializer 可以快速生成 Spring Boot 应用
首先点击左上角,文件—新建—项目
填写项目信息,注意:Java要选择8版本,然后点击下一步
注释:需要安装的插件
Developer Tools选项下的Spring Boot DevTools和Lombok
Web选项下的Spring Web
SQL选项下的MySQL Driver
看到左下角和右下角都没有进度条初始化项目后,并且右上角已经识别到了是一个Springboot项目后,项目即创建成功
此时,启动一下项目,查看是否正常,提示如下字样即可以正常启动(端口:8080)
使用浏览器打开网址吧,并能显示如下界面
localhost:8080
编写Controller测试
新建TestController
类,放在子包controller
下
新建好后,在里面编写添加如下代码
原始代码:
package com.example.mini_program_yln.controller;
public class TestController {
}
修改后
package com.example.mini_program_yln.controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
//将数据以json格式返回给前端
@RestController
public class TestController {
@GetMapping("/test")
public String test() {
return "Hello world!";
}
}
重新启动下项目,访问
localhost:8080/test
配置数据库
在resource目录下新建application.yml
文件
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mini_program?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 111111
解释:
需要修改的一般有数据库名、mysql账户、mysql密码
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/数据库名字?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: mysql的账号
password: mysql的密码
这里需要提前使用navicat新建数据库
2、SpringBoot集成mybatis-plus
官网:https://www.baomidou.com/
mybatis-plus是用来操作数据库的持久层框架
初始化数据库
按照官网的说法:操作
https://www.baomidou.com/pages/226c21/#%E5%88%9D%E5%A7%8B%E5%8C%96%E5%B7%A5%E7%A8%8B
打开navicat(也可以使用idea链接mysql,也可以使用hedisql等其它工具连接),点击查询,选择刚才创建的的数据库
粘贴下面的代码后点击运行
DROP TABLE IF EXISTS user;
CREATE TABLE user
(
id BIGINT(20) NOT NULL COMMENT '主键ID',
name VARCHAR(30) NULL DEFAULT NULL COMMENT '姓名',
age INT(11) NULL DEFAULT NULL COMMENT '年龄',
email VARCHAR(50) NULL DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY (id)
);
DELETE FROM user;
INSERT INTO user (id, name, age, email) VALUES
(1, 'Jone', 18, 'test1@baomidou.com'),
(2, 'Jack', 20, 'test2@baomidou.com'),
(3, 'Tom', 28, 'test3@baomidou.com'),
(4, 'Sandy', 21, 'test4@baomidou.com'),
(5, 'Billie', 24, 'test5@baomidou.com');
此时就自动创建好了user表,并插入了几条示例数据
安装mybatis-plus
1、在pom.xml文件中引入依赖
<!--mybatis-plus-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.2</version>
</dependency>
2、为了阻止恶意的全表更新删除,配置一下防全表更新与删除插件
针对 update 和 delete 语句 作用: 阻止恶意的全表更新删除
在如下路径下新建一个软件包:config
新建好如图所示
然后在config包下新建MybatisPlusConfig
类
然后添加如下代码,并导入相关的类
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
}
添加成功示例
package com.example.mini_program_yln.config;
import com.baomidou.mybatisplus.extension.plugins.MybatisPlusInterceptor;
import com.baomidou.mybatisplus.extension.plugins.inner.BlockAttackInnerInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
/*
* 针对 update 和 delete 语句 作用: 阻止恶意的全表更新删除
* */
@Configuration
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
return interceptor;
}
}
后续还可能要在这里添加分页配置
通过mybatis-plus将数据库数据通过接口显示
在下面的目录下新建entity子包
然后再entity包下新建User类,添加如下代码
package com.example.mini_program_yln.entity;
import lombok.Data;
@Data
public class User {
//表示id是主键,且插入数据时自增
@TableId(value = "id", type = IdType.AUTO)
private Long id;
private String name;
private Integer age;
private String email;
}
新建mapper子包
新建UserMapper接口,去继承BaseMapper
package com.example.mini_program_yln.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.example.mini_program_yln.entity.User;
import org.apache.ibatis.annotations.Mapper;
@Mapper
public interface UserMapper extends BaseMapper<User> {
}
我们去TestController.java文件测试下mapper
package com.example.mini_program_yln.controller;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
//将数据以json格式返回给前端
@RestController
public class TestController {
@Autowired
private UserMapper userMapper;
@GetMapping("/testList")
public List<User> testList() {
return userMapper.selectList(null);
}
}
访问http://localhost:8080/testList
,返回了数据库User表的全部数据
3、SpringBoot三层架构Controller、Service、Dao
现在我们的项目还差service没有创建
创建后
在service包下新建IUserService
接口,添加如下代码
package com.example.mini_program_yln.servicce;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mini_program_yln.entity.User;
public interface IUserService extends IService<User> {
}
然后再service包下新建impl子包,并在impl包下新建UserServiceImpl
类
添加如下代码
需要继承ServiceImpl,并实现自定义的IUserService
package com.example.mini_program_yln.servicce.impl;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import com.example.mini_program_yln.servicce.IUserService;
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
}
4、SpringBoot集成Mabatis-plus编写增删改查接口
在IUserService.java
中编写代码,定义几个接口
package com.example.mini_program_yln.servicce;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.IService;
import com.example.mini_program_yln.entity.User;
import java.util.List;
public interface IUserService extends IService<User> {
Page<User> page(Integer current, Integer size, String username);
boolean saveOrUpdateById(User user);
boolean deleteBatchIds(List<Integer> ids);
}
在UserServiceImpl.java
中实现一下几个接口
把鼠标放在红色波浪线这一行,点击实现方法
即可,会自动生成方法体
package com.example.mini_program_yln.servicce.impl;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import com.example.mini_program_yln.servicce.IUserService;
import java.util.List;
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
@Override
public Page<User> page(Integer current, Integer size, String username) {
return null;
}
@Override
public boolean saveOrUpdateById(User user) {
return false;
}
@Override
public boolean deleteBatchIds(List<Integer> ids) {
return false;
}
}
写一下逻辑的具体实现
package com.example.mini_program_yln.servicce.impl;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.injector.methods.DeleteBatchByIds;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import com.example.mini_program_yln.servicce.IUserService;
import javax.annotation.Resource;
import java.util.List;
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements IUserService {
@Override
public Page<User> page(Integer current, Integer size, String username) {
LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
if (!"".equals(username)) {
//不为空
//精确查询
//wrapper.eq(User::getName,username);
//模糊查询
wrapper.like(User::getName, username);
}
Page<User> page = page(new Page<>(current, size), wrapper);
return page;
}
@Override
public boolean saveOrUpdateById(User user) {
if (user.getId() != null) {
//更新
return updateById(user);
} else {
//新增
return save(user);
}
}
@Override
public boolean deleteBatchIds(List<Integer> ids) {
return removeByIds(ids);
}
}
然后在controller包下新建UserController.java类
package com.example.mini_program_yln.controller;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.servicce.impl.UserServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
import org.springframework.web.bind.annotation.*;
import java.util.List;
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserServiceImpl userService;
@GetMapping("/page")
@Description("分页列表-模糊查询")
public Page<User> page(@RequestParam(defaultValue = "") String username, @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) {
return userService.page(current, size, username);
}
@PostMapping("/save")
@Description("新增或更新")
public boolean save(@RequestBody User user) {
return userService.saveOrUpdateById(user);
}
@PostMapping("/delete")
@Description("删除")
public boolean delete(@RequestBody List<Integer> ids) {
return userService.deleteBatchIds(ids);
}
}
我们还需要在
MybatisPlusConfig.java
中新增分页配置项,增加下面的一行
public class MybatisPlusConfig {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new BlockAttackInnerInterceptor());
//分页配置
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));
return interceptor;
}
}
此时可以用postman测试接口了
其他
热部署集成
比如我们将代码从左图修改为右图,就需要编译重新启动才可以,这是对资源的浪费,而且耗时,这就需要用到热部署
1、首先点击左上角:文件—设置
找到构建、执行、部署
,点击编译器,勾选自动构建项目
2、然后开启idea的动态自动编译(有些会自动开启,那就不需要操作)
3、开启idea热部署策略
点击右上角项目—编辑配置
点击修改选项
将执行更新操作时
,修改为更新类和资源
4、在pom文件中添加插件
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
此时当idea失去焦点五秒后就会自动更新资源,完成了热部署
mybatis-plus日志打印
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
跨域问题解决
方式一:在Controller类中加入注解
@CrossOrigin("*")
有时Gradle的项目需要使用这个
@CrossOrigin(value = "*",allowCredentials = "true")
方式二:新建跨域配置项解决
在config包下新建CorsConfig
类
package com.example.mini_program_yln.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
@Configuration // 一定不能忽略此注解
public class CorsConfig {
@Bean
public CorsFilter corsFilter() {
// 1.创建 CORS 配置对象
CorsConfiguration config = new CorsConfiguration();
// 支持域
config.addAllowedOriginPattern("*");
// 是否发送 Cookie
config.setAllowCredentials(true);
// 支持请求方式
config.addAllowedMethod("*");
// 允许的原始请求头部信息
config.addAllowedHeader("*");
// 暴露的头部信息
config.addExposedHeader("*");
// 2.添加地址映射
UrlBasedCorsConfigurationSource corsConfigurationSource = new UrlBasedCorsConfigurationSource();
corsConfigurationSource.registerCorsConfiguration("/**", config);
// 3.返回 CorsFilter 对象
return new CorsFilter(corsConfigurationSource);
}
}
SpringBoot项目配置多环境
在resources目录下新建两个文件:application-local.yaml
和application-dev.yaml
application.yaml
active表示当前所处环境:local表示本地开发环境,dev表示线上环境
可以对不同环境设置不同的mysql账号密码等
spring:
profiles:
active: dev
application-local.yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mini_program?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 123456
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
application-dev.yaml
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/mini_program?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=Asia/Shanghai
username: root
password: 1234567
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #开启sql日志
SpringBoot返回结果统一封装
后端提供 RESTful API 给前端时,需要响应前端 API 调用是否成功:
- 如果成功,成功的数据是什么。后续,前端会将数据渲染到页面上
- 如果失败,失败的原因是什么。一般,前端会将原因弹出提示给用户
因此,需要有统一响应,而不能是每个接口定义自己的风格。一般来说,统一响应返回信息如下:
- 成功时,返回成功的状态码 + 数据
- 失败时,返回失败的状态码 + 错误提示
新建common子包
在common
子包下创建CommonResult
类
package com.example.mini_program_yln.common;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class CommonResult<T> {
/**
* 错误码
*/
private Integer code;
/**
* 返回数据
*/
private T data;
/**
* 错误提示,用户可阅读
*/
private String msg;
public static <T> CommonResult<T> success(T data) {
CommonResult<T> result = new CommonResult<>();
result.code = 0;
result.data = data;
result.msg = "";
return result;
}
public static <T> CommonResult<T> error(Integer code, String message) {
CommonResult<T> result = new CommonResult<>();
result.code = code;
result.msg = message;
return result;
}
public static <T> CommonResult<T> error() {
CommonResult<T> result = new CommonResult<>();
result.code = 1;
result.msg = "系统错误,请联系管理员";
return result;
}
}
测试一下
package com.example.mini_program_yln.controller;
import com.example.mini_program_yln.common.CommonResult;
import com.example.mini_program_yln.entity.User;
import com.example.mini_program_yln.mapper.UserMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Description;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
//将数据以json格式返回给前端
@RestController
public class TestController {
@Autowired
private UserMapper userMapper;
@Description("测试统一返回-成功")
@GetMapping("/testResultSuccess")
public CommonResult<List<User>> testResultSuccess() {
return CommonResult.success(userMapper.selectList(null));
}
@Description("测试统一返回-失败")
@GetMapping("/testResultError")
public CommonResult<List<User>> testResultError() {
return CommonResult.error(400, "失败了");
}
}
分页封装
在common包下新建PageParam.java类
package com.example.mini_program_yln.common;
import lombok.Data;
import java.io.Serializable;
@Data
public class PageParam implements Serializable {
private static final Integer PAGE_NO = 1;
private static final Integer PAGE_SIZE = 10;
private Integer pageNo = PAGE_NO;
private Integer pageSize = PAGE_SIZE;
}
之前分页的写法
@GetMapping("/page")
@Description("分页列表-模糊查询")
public Page<User> page(@RequestParam(defaultValue = "") String username, @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) {
return userService.page(current, size, username);
}
现在的写法
@PostMapping("/pageFZ")
@Description("分页列表-分页封装")
public CommonResult<Page<User>> page(@RequestBody PageParam pageInfo) {
Page<User> page = userService.page(
new Page<>(pageInfo.getPageNo(), pageInfo.getPageSize())
);
return CommonResult.success(page);
}
参数校验
例如在上面的分页封装中,我们的pageSize需要一个范围,不能无限大
在pom文件中引入依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
然后修改PageParam.java文件
pageNo页码最小为1
pageSize最小为1,最大为100
package com.example.mini_program_yln.common;
import lombok.Data;
import javax.validation.constraints.Min;
import javax.validation.constraints.Max;
import javax.validation.constraints.NotNull;
import java.io.Serializable;
@Data
public class PageParam implements Serializable {
private static final Integer PAGE_NO = 1;
private static final Integer PAGE_SIZE = 10;
@NotNull(message = "页码不能为空")
@Min(value = 1, message = "页码最小值为 1")
private Integer pageNo = PAGE_NO;
@NotNull(message = "每页条数不能为空")
@Min(value = 1, message = "每页条数最小值为 1")
@Max(value = 100, message = "每页条数最大值为 100")
private Integer pageSize = PAGE_SIZE;
}
测试接口发现确实可以校验,但是会返回一堆堆栈信息,这样并不好,可以进行全局异常捕获
自定义异常和全局异常捕获
创建exception
子包和GlobalExceptionHandler.java
类
package com.example.mini_program_yln.exception;
import com.example.mini_program_yln.common.CommonResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.BindException;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import javax.servlet.http.HttpServletRequest;
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
/*
*
* 运行时异常
* */
@ExceptionHandler(RuntimeException.class)
@ResponseBody
public CommonResult<?> ExceptionHandler() {
return CommonResult.error();
}
/*
*
* 自定义异常
* */
@ExceptionHandler(CustomException.class)
@ResponseBody
public CommonResult<?> CustomExceptionHandler(CustomException e) {
return CommonResult.error(400, e.getMessage());
}
/**
* 处理 SpringMVC 参数校验不正确
*/
@ExceptionHandler(MethodArgumentNotValidException.class)
@ResponseBody
public CommonResult<?> methodArgumentNotValidExceptionExceptionHandler(MethodArgumentNotValidException ex) {
FieldError fieldError = ex.getBindingResult().getFieldError();
assert fieldError != null; // 断言,避免告警
return CommonResult.error(400, String.format("请求参数不正确:%s:%s", fieldError.getField(), fieldError.getDefaultMessage()));
}
/**
* 处理系统异常,兜底处理所有的一切
*/
@ExceptionHandler(value = Exception.class)
@ResponseBody
public CommonResult<?> defaultExceptionHandler(HttpServletRequest req, Throwable ex) {
// 返回 ERROR CommonResult
return CommonResult.error(400, "未知异常,请联系管理员");
}
}
此时分页参数传递错误,就可以正常捕获到
自定义异常
在exception下创建CustomException.java类
package com.example.mini_program_yln.exception;
import lombok.Getter;
@Getter
public class CustomException extends RuntimeException {
private Integer code;
public CustomException(Integer code, String msg) {
super(msg);
this.code = code;
}
public CustomException( String msg) {
super(msg);
this.code = 400;
}
}
代码中使用
@GetMapping("/page")
@Description("分页列表-模糊查询")
public Page<User> page(@RequestParam(defaultValue = "") String username, @RequestParam(defaultValue = "1") Integer current, @RequestParam(defaultValue = "10") Integer size) {
throw new CustomException(404,"aaa");
// return userService.page(current, size, username);
}
自动生成entity实体类
在utils包下新建SqlHelper类
使用之前一般需要修改packageOutPath、tablename、URL、NAME、PASS
package com.example.mini_program_yln.utils;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* 从数据库表反射出实体类,自动生成实体类
*
* @author xxxx
*/
public class SqlHelper {
//基本数据配置
private String packageOutPath = "com.example.mini_program_yln.entity";// 指定实体生成所在包的路径,要修改
private String authorName = "xxxx";// 作者名字
private String tablename = "news";// 表名,要修改
private String[] colnames; // 列名数组
private String[] colTypes; // 列名类型数组
private String version = "V0.01"; // 版本
private int[] colSizes; // 列名大小数组
private boolean f_util = false; // 是否需要导入包java.util.*
private boolean f_sql = false; // 是否需要导入包java.sql.*
private boolean f_lang = false; // 是否需要导入包java.sql.*
private String defaultPath = "/src/main/java/";
// 数据库连接
private static final String URL = "jdbc:mysql://localhost:3306/mini_program?useUnicode=true&characterEncoding=UTF-8&useSSL=false&serverTimezone=UTC";//要修改
private static final String NAME = "root";//要修改
private static final String PASS = "123456";//要修改
private static final String DRIVER = "com.mysql.jdbc.Driver";
/*
* 构造函数
*/
public SqlHelper() {
// 创建连接
Connection con;
// 查要生成实体类的表
String sql = "select * from " + tablename;
PreparedStatement pStemt = null;
try {
try {
Class.forName(DRIVER);
} catch (ClassNotFoundException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
con = DriverManager.getConnection(URL, NAME, PASS);
pStemt = con.prepareStatement(sql);
ResultSetMetaData rsmd = pStemt.getMetaData();
int size = rsmd.getColumnCount(); // 统计列
colnames = new String[size];
colTypes = new String[size];
colSizes = new int[size];
for (int i = 0; i < size; i++) {
colnames[i] = rsmd.getColumnName(i + 1);
colTypes[i] = rsmd.getColumnTypeName(i + 1);
//自动生成包配置
// if (colTypes[i].equalsIgnoreCase("datetime")) {
// f_util = true;
// }
if (colTypes[i].equalsIgnoreCase("image") || colTypes[i].equalsIgnoreCase("text")
|| colTypes[i].equalsIgnoreCase("datetime") || colTypes[i].equalsIgnoreCase("time")
|| colTypes[i].equalsIgnoreCase("date") || colTypes[i].equalsIgnoreCase("datetime2")) {
f_sql = true;
}
// if (colTypes[i].equalsIgnoreCase("int")) {
// f_lang = true;
// }
colSizes[i] = rsmd.getColumnDisplaySize(i + 1);
}
String content = parse(colnames, colTypes, colSizes);
try {
File directory = new File("");
String path = this.getClass().getResource("").getPath();
System.out.println(path);
String outputPath = directory.getAbsolutePath() + this.defaultPath
+ this.packageOutPath.replace(".", "/") + "/" + initcap(underlineToHump(tablename)) + ".java";
System.out.println("执行完毕,生成路径为:" + outputPath);
FileWriter fw = new FileWriter(outputPath);
PrintWriter pw = new PrintWriter(fw);
pw.println(content);
pw.flush();
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
}
}
/**
* 功能:生成实体类主体代码
*
* @param colnames
* @param colTypes
* @param colSizes
* @return
*/
private String parse(String[] colnames, String[] colTypes, int[] colSizes) {
StringBuffer sb = new StringBuffer();
// 生成package包路径
sb.append("package " + this.packageOutPath + ";\r\n");
// 判断是否导入工具包
if (f_util) {
sb.append("import java.util.Date;\r\n");
}
if (f_sql) {
sb.append("import java.sql.*;\r\n");
}
if (f_lang) {
sb.append("import java.lang.*;\r\n");
}
sb.append("import lombok.Data;\r\n");
sb.append("\r\n");
// 注释部分
sb.append(" /**\r\n");
sb.append(" * @文件名称:" + initcap(underlineToHump(this.tablename)) + ".java\r\n");
sb.append(" * @创建时间:" + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()) + "\r\n");
sb.append(" * @创 建 人:" + this.authorName + " \r\n");
sb.append(" * @文件描述:" + tablename + " 实体类\r\n");
sb.append(" * @文件版本:" + this.version + " \r\n");
sb.append(" */ \r\n");
sb.append("\n\r\n@Data");
// 实体部分
sb.append("\npublic class " + initcap(underlineToHump(tablename)) + "{\r\n");
processAllAttrs(sb);// 属性
// processAllMethod(sb);// get set方法
sb.append("}\r\n");
// System.out.println(sb.toString());
return sb.toString();
}
/**
* 功能:生成所有属性
*
* @param sb
*/
private void processAllAttrs(StringBuffer sb) {
for (int i = 0; i < colnames.length; i++) {
sb.append("\tprivate " + sqlType2JavaType(colTypes[i]) + " " + this.underlineToHump(colnames[i]) + ";\r\n");
}
}
/**
* 功能:生成所有方法
*
* @param sb
*/
// private void processAllMethod(StringBuffer sb) {
//
// for (int i = 0; i < colnames.length; i++) {
// sb.append("\tpublic void set" + initcap(colnames[i]) + "(" + sqlType2JavaType(colTypes[i]) + " "
// + colnames[i] + "){\r\n");
// sb.append("\tthis." + colnames[i] + "=" + colnames[i] + ";\r\n");
// sb.append("\t}\r\n");
// sb.append("\tpublic " + sqlType2JavaType(colTypes[i]) + " get" + initcap(colnames[i]) + "(){\r\n");
// sb.append("\t\treturn " + colnames[i] + ";\r\n");
// sb.append("\t}\r\n");
// }
//
// }
/**
* 功能:将输入字符串的首字母改成大写
*
* @param str
* @return
*/
private String initcap(String str) {
char[] ch = str.toCharArray();
if (ch[0] >= 'a' && ch[0] <= 'z') {
ch[0] = (char) (ch[0] - 32);
}
return new String(ch);
}
/**
* 功能:获得列的数据类型
*
* @param sqlType
* @return
*/
private String sqlType2JavaType(String sqlType) {
if (sqlType.equalsIgnoreCase("bit")) {
return "Boolean";
} else if (sqlType.equalsIgnoreCase("decimal") || sqlType.equalsIgnoreCase("money")
|| sqlType.equalsIgnoreCase("smallmoney") || sqlType.equalsIgnoreCase("numeric")
|| sqlType.equalsIgnoreCase("bigint")) {
return "Long";
} else if (sqlType.equalsIgnoreCase("float")) {
return "Double";
} else if (sqlType.equalsIgnoreCase("int") || sqlType.equalsIgnoreCase("int identity")) {
return "Integer";
} else if (sqlType.equalsIgnoreCase("image") || sqlType.equalsIgnoreCase("varbinary(max)")
|| sqlType.equalsIgnoreCase("varbinary") || sqlType.equalsIgnoreCase("udt")
|| sqlType.equalsIgnoreCase("binary")) {
return "Byte[]";
} else if (sqlType.equalsIgnoreCase("nchar") || sqlType.equalsIgnoreCase("nvarchar(max)")
|| sqlType.equalsIgnoreCase("nvarchar") || sqlType.equalsIgnoreCase("nvarchar(ntext)")
|| sqlType.equalsIgnoreCase("uniqueidentifier") || sqlType.equalsIgnoreCase("xml")
|| sqlType.equalsIgnoreCase("char") || sqlType.equalsIgnoreCase("varchar(max)")
|| sqlType.equalsIgnoreCase("text") || sqlType.equalsIgnoreCase("varchar")) {
return "String";
} else if (sqlType.equalsIgnoreCase("real")) {
return "Float";
} else if (sqlType.equalsIgnoreCase("smallint") || sqlType.equalsIgnoreCase("tinyint")) {
return "Short";
} else if (sqlType.equalsIgnoreCase("date") || sqlType.equalsIgnoreCase("datetime")
|| sqlType.equalsIgnoreCase("time") || sqlType.equalsIgnoreCase("datetime2")
|| sqlType.equalsIgnoreCase("timestamp")) {
return "Date";
} else {
System.out.println("数据类型异常,类型为:" + sqlType);
}
return null;
}
/**
* 下划线转驼峰
*
* @String para
*/
private String underlineToHump(String para) {
StringBuilder result = new StringBuilder();
String a[] = para.split("_");
for (String s : a) {
if (result.length() == 0) {
result.append(s.toLowerCase());
} else {
result.append(s.substring(0, 1).toUpperCase());
result.append(s.substring(1).toLowerCase());
}
}
return result.toString();
}
/**
* 出口 TODO
*
* @param args
*/
public static void main(String[] args) {
new SqlHelper();
}
}