背景
现在的需求是根据类的文本文件获取类型,属性名称等信息创建数据库中的表。
实操
创建表
大致思路:
将类中的属性名称类型等信息通过反射拿到,然后通过拼接字符串的形式变成sql语句,使用JDBCTemplate.excute 方法执行sql语句实现创表效果。
@Resource private JdbcTemplate jdbcTemplate; public static void main(String[] args) throws ClassNotFoundException { String classPath = "com.tfjybj.service.User"; Class stu = Class.forName(classPath); List fieldsList = new ArrayList<Field[]>(); // 保存属性对象数组到列表 while (stu != null) { // 遍历所有父类字节码对象 Field[] declaredFields = stu.getDeclaredFields(); // 获取字节码对象的属性对象数组 fieldsList.add(declaredFields); stu = stu.getSuperclass(); // 获得父类的字节码对象 } String classPathEnd = classPath.substring(classPath.lastIndexOf(".")+1); StringBuffer stringSql = new StringBuffer(); stringSql.append("create table " + classPathEnd +"(\r\n") ; String sqlFieldType = ""; String sqlFieldName = ""; for (Object fields:fieldsList) { // 打印当前类以及其父类的多有属性对象 Field[] f = (Field[]) fields; for (Field field : f) { String type = field.getType().toString(); String typeEnd = type.substring(type.lastIndexOf(".")+1); System.out.println(typeEnd); System.out.println(field.getName()); sqlFieldName = field.getName(); if(typeEnd == "String"){ sqlFieldType = "varchar(20)"; }else if(typeEnd =="Long") { sqlFieldType = "bigint(200)"; }else { sqlFieldType = "varchar(20)"; } stringSql.append(sqlFieldName+" "+sqlFieldType+","+"\r\n"); } } stringSql.deleteCharAt(stringSql.length()-3); stringSql.append("\n)"); String strEnd = stringSql.toString(); System.out.println(strEnd); jdbcTemplate.execute(stringSQL); }
插入数据
实现思路:
insert 语句前边的属性 对应他真正的属性值 所以如何找对应关系 使用拼接字符串,找到get方法,反射出来对象对应的属性值。
Class detailClass = user.getClass(); List fieldsList = new ArrayList<Field[]>(); // 保存属性对象数组到列表 // while (detailClass != null) { // 遍历所有父类字节码对象 Field[] declaredFields = detailClass.getDeclaredFields(); // 获取字节码对象的属性对象数组 fieldsList.add(declaredFields); // detailClass = detailClass.getSuperclass(); // 获得父类的字节码对象 // } Map<String, String> map = new HashMap<>(); String className = detailClass.getName(); StringBuffer stringSql = new StringBuffer(); stringSql.append("insert into " + "user" + " ("); StringBuffer stringField = new StringBuffer(); StringBuffer strWhat = new StringBuffer(); StringBuffer endGoods = new StringBuffer(); String sqlFieldType = ""; String sqlFieldName = ""; String fieldName1 = ""; // String endGoods = ""; List<Object> args = new ArrayList<>(); for (Object fields : fieldsList) { // 打印当前类以及其父类的多有属性对象 Field[] f = (Field[]) fields; for (Field field : f) { String fieldname = field.getName(); stringField.append(fieldname + ","); strWhat.append("?" + ","); fieldName1 = fieldname; fieldName1 = fieldName1.substring(0, 1).toUpperCase() + fieldName1.substring(1); String fieldMethod = "get" + fieldName1; Method method = detailClass.getMethod(fieldMethod); Object endThing = method.invoke(user); endGoods.append("\""); endGoods.append(endThing); args.add(endThing); endGoods.append("\"" + ","); // endGoods.append("\"" + endGoods +"\""+","); // map.put(fieldname,endThing.toString()); } } stringField.deleteCharAt(stringField.length() - 1); endGoods.deleteCharAt(endGoods.length() - 1); stringSql.append(stringField); stringSql.append(")"); strWhat.deleteCharAt(strWhat.length() - 1); stringSql.append(" values " + "("); stringSql.append(strWhat); stringSql.append(")"); System.out.println(stringSql.toString()); System.out.println(endGoods.toString()); String endGoodsStr = endGoods.toString(); endGoodsStr = endGoodsStr.substring(1, endGoodsStr.length() - 1); List<String> detailValueList = new ArrayList<>(); // String detailValue = // String insertSql = // //首先拼接好所有的sql // //拼接好入参 // //进行调用 // String sql = stringSql.toString(); System.out.println(sql); // args[0]= "aaa"; // System.out.println(args); // //参数一:插入数据的SQL语句,参数二:对应SQL语句中占位符?的参数 return jdbcTemplate.update(sql, args.toArray()); }
注意:
使用JDBCTemplate插入记录的时候遇见这样一个问题,要传数组,但是我传的是一个字符串。所以调用JDBCTemplate方法的时候会报错。
报找不到第二个参数。
下边是可以的。
最终发现传入的是字符串,而不是一个数组。
代码做和如下改动:
就能插库了。
总结
在使用Spring的JdbcTemplate来将类转换成表并插入数据时,需要定义实体类与数据库表之间的映射关系,并使用JdbcTemplate执行插入操作。以下是一个示例,演示如何解决这个问题:
假设我们有一个实体类User,对应数据库中的users表,表结构如下:
CREATE TABLE users ( id INT PRIMARY KEY, username VARCHAR(50), email VARCHAR(100) );
首先,我们需要定义User类,该类的字段与表的列对应:
public class User { private int id; private String username; private String email; // 构造函数、getter和setter等方法省略 }
接下来,我们使用JdbcTemplate来将类转换成表并插入数据:
import org.springframework.jdbc.core.JdbcTemplate; import javax.sql.DataSource; public class UserDao { private final JdbcTemplate jdbcTemplate; public UserDao(DataSource dataSource) { this.jdbcTemplate = new JdbcTemplate(dataSource); } public void saveUser(User user) { String sql = "INSERT INTO users (id, username, email) VALUES (?, ?, ?)"; jdbcTemplate.update(sql, user.getId(), user.getUsername(), user.getEmail()); } }
在这里,我们创建了一个UserDao类,其中的saveUser方法用于将User类对象插入到数据库中。我们使用JdbcTemplate的update方法执行插入操作,传递SQL语句和对应的参数。JdbcTemplate会自动将实体类的字段映射到数据库表的列,并插入相应的数据。
为了使用上述UserDao类,我们需要配置数据源(DataSource),并将其注入到UserDao中。在Spring配置文件中,我们可以这样定义数据源和JdbcTemplate:
<!-- 数据源配置 --> <bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> <property name="driverClassName" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/mydb" /> <property name="username" value="root" /> <property name="password" value="password" /> </bean> <!-- JdbcTemplate配置 --> <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"> <constructor-arg ref="dataSource" /> </bean>
然后,我们在应用代码中可以使用UserDao来插入数据:
public class Main { public static void main(String[] args) { ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml"); UserDao userDao = context.getBean(UserDao.class); User user = new User(); user.setId(1); user.setUsername("john_doe"); user.setEmail("john@example.com"); userDao.saveUser(user); } }
通过上述配置和代码,我们可以使用JdbcTemplate将类转换成表并插入数据。在实际应用中,通常会根据实际需求,定义更多的CRUD操作,并在Service或Repository层中调用相应的DAO来操作数据库。