first commit

This commit is contained in:
Frank 2023-06-28 00:54:18 +08:00
commit 3aeda46b0b
14 changed files with 943 additions and 0 deletions

39
.gitignore vendored Normal file
View File

@ -0,0 +1,39 @@
target/
!.mvn/wrapper/maven-wrapper.jar
!**/src/main/**/target/
!**/src/test/**/target/
### IntelliJ IDEA ###
.idea/
.idea/modules.xml
.idea/jarRepositories.xml
.idea/compiler.xml
.idea/libraries/
*.iws
*.iml
*.ipr
### Eclipse ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/
build/
!**/src/main/**/build/
!**/src/test/**/build/
### VS Code ###
.vscode/
### Mac OS ###
.DS_Store

80
pom.xml Normal file
View File

@ -0,0 +1,80 @@
<?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>net.javase.db</groupId>
<artifactId>mysql-tool</artifactId>
<version>1.0.0</version>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<mysql.version>8.0.30</mysql.version>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13.2</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>commons-beanutils</groupId>
<artifactId>commons-beanutils</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
<build>
<finalName>mysql-tool</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.8.1</version>
<configuration>
<source>${maven.compiler.source}</source>
<target>${maven.compiler.target}</target>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.1.1</version>
<executions>
<execution>
<phase>package</phase>
<goals>
<goal>jar</goal>
</goals>
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-source-plugin</artifactId>
<version>3.1.0</version>
<executions>
<execution>
<id>nexus-release</id>
<phase>package</phase>
<goals>
<goal>jar-no-fork</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>

View File

@ -0,0 +1,38 @@
package net.javase.db.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* Column
*
* @author frank
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Column {
/**
* column name
*
* @return column name
*/
String name();
/**
* not null
*
* @return true | false
*/
boolean notNull() default false;
/**
* default value
*
* @return default value
*/
String defaultValue();
}

View File

@ -0,0 +1,24 @@
package net.javase.db.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 实体类注解
*
* @author frank
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.TYPE)
public @interface Entity {
/**
* 自定义表名
*
* @return table name
*/
String table() default "";
}

View File

@ -0,0 +1,17 @@
package net.javase.db.annotation;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 主键注解
*
* @author frank
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface Id {
}

View File

@ -0,0 +1,102 @@
package net.javase.db.config;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;
/**
* DbConfig
*
* @author Frank
*/
public class DbConfig {
private static final String FILE_NAME = "mysql.properties";
private static Properties p = null;
private static DbConfig dbConfig = null;
/**
* driver
*/
private String driver;
/**
* url
*/
private String url;
/**
* username
*/
private String username;
/**
* password
*/
private String password;
public DbConfig(String driver, String url, String username, String password) {
this.driver = driver;
this.url = url;
this.username = username;
this.password = password;
}
public String getUrl() {
return url;
}
public void setUrl(String url) {
this.url = 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 getDriver() {
return driver;
}
public void setDriver(String driver) {
this.driver = driver;
}
static {
InputStream inputStream = ClassLoader.getSystemResourceAsStream(FILE_NAME);
p = new Properties();
try {
p.load(inputStream);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
/**
* 获取配置信息对象
*/
public static DbConfig get() {
if (dbConfig == null) {
dbConfig = new DbConfig(
p.getProperty("driver"),
p.getProperty("url"),
p.getProperty("username"),
p.getProperty("password")
);
}
return dbConfig;
}
}

View File

@ -0,0 +1,5 @@
package net.javase.db.utils;
public class BeanUtil {
}

View File

@ -0,0 +1,297 @@
package net.javase.db.utils;
import net.javase.db.annotation.Column;
import net.javase.db.annotation.Entity;
import net.javase.db.annotation.Id;
import net.javase.db.config.DbConfig;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.sql.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.beanutils.PropertyUtils;
/**
* DbUtil
*
* @author Frank
*/
public class DbUtil {
private static Connection conn;
static {
try {
Class.forName(DbConfig.get().getDriver());
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
/**
* 获取数据库连接对象
*
* @return {@link Connection}
*/
public static Connection getConnection() {
// 获取连接并捕获异常
try {
if (conn == null || conn.isClosed())
conn = DriverManager.getConnection(
DbConfig.get().getUrl(),
DbConfig.get().getUsername(),
DbConfig.get().getPassword());
} catch (SQLException e) {
e.printStackTrace();
}
return conn;// 返回连接对象
}
/**
* 关闭数据库连接
*
* @param conn {@link Connection} 数据库连接
*/
public static void closeConn(Connection conn) {
try {
if (conn != null && !conn.isClosed())
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 关闭数据库连接
*
* @param conn 数据库连接
* @param stmt Statement对象
* @param rs 结果集
*/
public static void closeAll(Connection conn, Statement stmt, ResultSet rs) {
// 若结果集对象不为空则关闭
try {
if (rs != null && !rs.isClosed())
rs.close();
} catch (Exception e) {
e.printStackTrace();
}
// 若Statement对象不为空则关闭
try {
if (stmt != null && !stmt.isClosed())
stmt.close();
} catch (Exception e) {
e.printStackTrace();
}
// 若数据库连接对象不为空则关闭
try {
if (conn != null && !conn.isClosed())
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 改操作
*
* @param sql sql语句
* @param params 参数数组
* @return 执行结果
*/
public static int executeUpdate(String sql, Object... params) {
int result = 0;
conn = getConnection();
PreparedStatement pstmt = null;
try {
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
result = pstmt.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
} finally {
closeAll(null, pstmt, null);
}
return result;
}
/**
* 查询操作
*
* @param sql sql语句
* @param params 参数数组
* @return 查询结果集
*/
public static ResultSet executeQuery(String sql, Object... params) {
conn = getConnection();
PreparedStatement pstmt = null;
ResultSet rs = null;
try {
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
rs = pstmt.executeQuery();
} catch (SQLException e) {
e.printStackTrace();
}
return rs;
}
/**
* 查询实体列表
*
* @param <T> T
* @param clazz entity class
* @param sql 查询sql
* @param params sql参数
* @return entity list
*/
public static <T> List<T> selectList(Class<T> clazz, String sql, Object... params) {
conn = getConnection();
PreparedStatement pstmt = null;
ResultSet rs = null;
List<T> list = new ArrayList<T>();
try {
pstmt = conn.prepareStatement(sql);
for (int i = 0; i < params.length; i++) {
pstmt.setObject(i + 1, params[i]);
}
rs = pstmt.executeQuery();
Map<String, String> entityMateData = getMetaData(clazz);
ResultSetMetaData rsmd = rs.getMetaData();
int columnCount = rsmd.getColumnCount();
while (rs.next()) {
T obj = clazz.newInstance();
for (int i = 1; i <= columnCount; i++) {
String columnName = rsmd.getColumnName(i);
Object value = rs.getObject(i);
try {
if (entityMateData.get(columnName) != null) {
PropertyUtils.setProperty(obj, entityMateData.get(columnName), value);
}
} catch (InvocationTargetException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
}
}
list.add(obj);
}
entityMateData = null;
} catch (SQLException | InstantiationException | IllegalAccessException e) {
throw new RuntimeException(e);
} finally {
closeAll(conn, pstmt, rs);
}
return list;
}
/**
* 获取entity对应的column对应关系
*
* @param <T> T
* @param clazz entity class
* @return map
*/
private static <T> Map<String, String> getMetaData(Class<T> clazz) {
Map<String, String> map = new HashMap<>();
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
Column c = field.getAnnotation(Column.class);
if (c != null) {
if (StrUtil.notBlank(c.name())) {
map.put(c.name(), field.getName());
}
}
map.put(field.getName(), field.getName());
}
return map;
}
/**
* 生成建表语句
*
* @param clazz 实体类
* @param underline 是否下划线命名
* @param <T> 实体类
* @return sql
*/
public static <T> String createSchemaSql(Class<T> clazz, boolean underline) {
String table = clazz.getSimpleName();
Entity e = clazz.getAnnotation(Entity.class);
if (e != null && !StrUtil.isBlank(e.table())) {
table = e.table();
} else {
table = StrUtil.camelToUnderscore(table);
}
StringBuilder sqlBuilder = new StringBuilder();
sqlBuilder.append("CREATE TABLE IF NOT EXISTS `").append(table).append("` (");
Field[] fields = clazz.getDeclaredFields();
for (Field field : fields) {
String columnName = field.getName();
String jdbcType = ""; // 类型
boolean notNull = false; // 是否为空
String defaultValue = ""; // 默认值
boolean isKey = false;
Id id = field.getAnnotation(Id.class);
if (id != null) {
isKey = true;
notNull = true;
}
Column c = field.getAnnotation(Column.class);
if (c != null) {
if (StrUtil.notBlank(c.name())) {
columnName = c.name();
}
notNull = c.notNull();
defaultValue = c.defaultValue();
}
Class<?> fieldType = field.getType();
if (String.class.equals(fieldType)) {
jdbcType = "VARCHAR(255)";
} else if (Integer.class.equals(fieldType) || int.class.equals(fieldType)) {
jdbcType = "INT";
} else if (Long.class.equals(fieldType) || long.class.equals(fieldType)) {
jdbcType = "BIGINT";
} else if (Boolean.class.equals(fieldType) || boolean.class.equals(fieldType)) {
jdbcType = "BOOLEAN";
} else if (Double.class.equals(fieldType) || double.class.equals(fieldType)) {
jdbcType = "DOUBLE";
} else if (Date.class.equals(fieldType) || java.util.Date.class.equals(fieldType)) {
jdbcType = "datetime";
} else if (Float.class.equals(fieldType) || float.class.equals(fieldType)) {
jdbcType = "float";
} else {
jdbcType = "VARCHAR(255)";
}
if (underline) {
columnName = StrUtil.camelToUnderscore(columnName);
}
sqlBuilder.append("`").append(columnName).append("` ")
.append(jdbcType).append(" ")
.append(notNull ? "NOT NULL" : "NULL").append(" ")
.append(StrUtil.notBlank(defaultValue) ? "DEFAULT '" + defaultValue + "'" : "").append(" ")
.append(isKey ? "PRIMARY KEY AUTO_INCREMENT" : "")
.append(",");
}
// 去掉最后一个逗号
if (fields.length > 0) {
sqlBuilder.deleteCharAt(sqlBuilder.length() - 1);
}
sqlBuilder.append(") ENGINE=InnoDB DEFAULT CHARSET=utf8;");
return sqlBuilder.toString();
}
}

View File

@ -0,0 +1,86 @@
package net.javase.db.utils;
/**
* StrUtil
*
* @author Frank
*/
public class StrUtil {
/**
* 判断字符串是否为空
*
* @param str 字符串
* @return true | false
*/
public static boolean isBlank(String str) {
return str == null || str.length() == 0 || str.trim().length() == 0;
}
/**
* 字符串是否不为null或者''
*
* @param str 字符串
* @return true | false
*/
public static boolean notBlank(String str) {
return !isBlank(str);
}
/**
* 驼峰转下划线
*
* @param str 驼峰字符串
* @return 下划线字符串
*/
public static String camelToUnderscore(String str) {
if (str == null || str.isEmpty()) {
return str;
}
StringBuilder result = new StringBuilder();
char[] chars = str.toCharArray();
for (int i = 0; i < chars.length; i++) {
char ch = chars[i];
if (i == 0) {
result.append(Character.toLowerCase(ch));
continue;
}
if (Character.isUpperCase(ch)) {
result.append("_").append(Character.toLowerCase(ch));
} else if (Character.isDigit(ch)) {
result.append("_").append(ch);
} else {
result.append(ch);
}
}
return result.toString();
}
/**
* 下划线转驼峰
*
* @param underLineStr 下划线字符串
* @return 驼峰字符串
*/
public static String underlineToCamel(String underLineStr) {
StringBuilder result = new StringBuilder();
// 标记当前字符是否为下划线后的第一个字符
boolean flag = false;
// 遍历字符串将下划线后的第一个字符转换成大写字母
for (int i = 0; i < underLineStr.length(); i++) {
char currentChar = underLineStr.charAt(i);
if (currentChar == '_') {
flag = true;
} else {
if (flag) {
result.append(Character.toUpperCase(currentChar));
flag = false;
} else {
result.append(Character.toLowerCase(currentChar));
}
}
}
return result.toString();
}
}

View File

@ -0,0 +1,85 @@
package net.javase.db.test;
import net.javase.db.annotation.Entity;
import net.javase.db.annotation.Id;
import java.util.Date;
/**
* BankAccount
* @author frank
*/
@Entity
public class BankAccount {
@Id
private int id;
private String username;
private String realName;
private String password;
private String optPassword;
private String balance;
private Date createTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getRealName() {
return realName;
}
public void setRealName(String realName) {
this.realName = realName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getOptPassword() {
return optPassword;
}
public void setOptPassword(String optPassword) {
this.optPassword = optPassword;
}
public String getBalance() {
return balance;
}
public void setBalance(String balance) {
this.balance = balance;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

View File

@ -0,0 +1,86 @@
package net.javase.db.test;
import net.javase.db.annotation.Entity;
import net.javase.db.annotation.Id;
import java.util.Date;
/**
* BankAccountLog
*
* @author frank
*/
@Entity
public class BankAccountLog {
@Id
private int id;
private int accountId;
private String username;
private String optType;
private String optAmount;
private String desc;
private Date createTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getAccountId() {
return accountId;
}
public void setAccountId(int accountId) {
this.accountId = accountId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getOptType() {
return optType;
}
public void setOptType(String optType) {
this.optType = optType;
}
public String getOptAmount() {
return optAmount;
}
public void setOptAmount(String optAmount) {
this.optAmount = optAmount;
}
public String getDesc() {
return desc;
}
public void setDesc(String desc) {
this.desc = desc;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}

View File

@ -0,0 +1,28 @@
package net.javase.db.test;
import net.javase.db.utils.DbUtil;
import java.util.List;
import org.junit.Test;
/**
* MainTest
*
* @author Frank
*/
public class DbUtilTest {
@Test
public void testCreateTableSql() {
System.out.println(DbUtil.createSchemaSql(BankAccount.class, true));
System.out.println("\n");
System.out.println(DbUtil.createSchemaSql(BankAccountLog.class, true));
}
@Test
public void testQueryList() {
List<Product> list = DbUtil.selectList(Product.class, "select * from sys_product");
list.forEach(item -> System.out.println(item));
}
}

View File

@ -0,0 +1,52 @@
package net.javase.db.test;
public class Product {
private Integer pid;
private String pname;
private Double pprice;
private Integer stock;
public String getPname() {
return pname;
}
public void setPname(String pname) {
this.pname = pname;
}
public Integer getPid() {
return pid;
}
public void setPid(Integer pid) {
this.pid = pid;
}
public Double getPprice() {
return pprice;
}
public void setPprice(Double pprice) {
this.pprice = pprice;
}
public Integer getStock() {
return stock;
}
public void setStock(Integer stock) {
this.stock = stock;
}
@Override
public String toString() {
return "Product [pid=" + pid + ", pname=" + pname + ", pprice=" + pprice + ", stock=" + stock + "]";
}
}

View File

@ -0,0 +1,4 @@
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/demo?characterEncoding=utf-8&serverTimezone=GMT%2b8
username=root
password=root