• ORM框架,反射,泛型,注解,CRUD实现


    注解与反射:

    注:内容介绍_哔哩哔哩_bilibili

    注解就是对代码的注释,反射就是java理解注解的方式。反射可以在类运行时获取类相关属性,方法等。

    声明注解:@interface

    元注解:@Target @Retention @Document和@Inherited

    定义一个注解

    1. /**
    2. * RetentionPolicy:
    3. * SOURCE:在代码中,不会在class中
    4. * CLASS: 编译在class,jvm会忽略
    5. * RUNTTIME: 运行时生效
    6. */
    7. @Target(ElementType.METHOD) //可以表明注解用在类/方法/字段上
    8. @Retention(RetentionPolicy.RUNTIME) //保留策略
    9. public @interface MyAnno {
    10. //默认的方法,会带到jvm中,会在反射中获得这些值
    11. String value();
    12. }

    定义一个反射类

    1. @TableName(value = "类上注解")
    2. public class User {
    3. // @MyAnno(value = "通过反射获取默认值")
    4. @TableField(value = "变量注解")
    5. private String userId;
    6. @MyAnno(value = "通过反射获取方法注解")
    7. private void work(String userId){
    8. System.out.println("");
    9. }
    10. }

     获取相关属性

    1. public class ReflecDemo {
    2. public static void main(String[] args) {
    3. TableName tableName = User.class.getAnnotation(TableName.class); //通过反射获取对象
    4. System.out.println(tableName.value());
    5. Field[] declaredFields = User.class.getDeclaredFields(); //获取对象变量
    6. for (Field field : declaredFields) {
    7. TableField tableField = field.getAnnotation(TableField.class);
    8. if(null != tableField){
    9. System.out.println(field.getName() + " - " + tableField.value());
    10. }
    11. }
    12. Method[] declaredMethods = User.class.getDeclaredMethods();
    13. for (Method method : declaredMethods) {
    14. MyAnno myAnno = method.getAnnotation(MyAnno.class);
    15. if(null != myAnno){
    16. System.out.println(method.getName() + " - " + myAnno.value()); //获取方法上注解
    17. }
    18. }
    19. }
    20. }

    实现一个ORM框架

    目标:通过一个包含自定义注解的POJO类,来描述POJO与数据库中表的对应关系,然后由框架统一完成对数据库中表的CRUD操作。

    代码:许宇 (xuyu294636185) - Gitee.com

    步骤:

    1.定义实体与注解,从实体中解析出CRUD对应的SQL语句

    1. /**
    2. * 定义table注解:指明orderInfo实体对应数据库的那张表
    3. */
    4. @Target(ElementType.TYPE)
    5. @Retention(RetentionPolicy.RUNTIME)
    6. public @interface Table {
    7. public String tableName(); //对应表名
    8. public String orderBy() default ""; //排序字段,可为空
    9. public String order() default ""; //升降序
    10. }
    1. /**
    2. * 表中字段对应关系
    3. */
    4. @Target(ElementType.FIELD)
    5. @Retention(RetentionPolicy.RUNTIME)
    6. public @interface TableColumn {
    7. public String dbColumn(); //对应数据库列
    8. public String isPK() default ""; //是否主键
    9. public String dbColumnType() default ""; //数据库字段类型
    10. }
    1. @Table(tableName = "order_info",orderBy = "order_date",order = "desc")
    2. public class OrderInfo {
    3. @TableColumn(dbColumn = "order_id",isPK = "true")
    4. private int orderId;
    5. @TableColumn(dbColumn = "client_name")
    6. private String clientName;
    7. @TableColumn(dbColumn = "produce_name")
    8. private String productName;
    9. @TableColumn(dbColumn = "order_date")
    10. private Date orderDate;
    11. public int getOrderId() {
    12. return orderId;
    13. }
    14. public void setOrderId(int orderId) {
    15. this.orderId = orderId;
    16. }
    17. public String getClientName() {
    18. return clientName;
    19. }
    20. public void setClientName(String clientName) {
    21. this.clientName = clientName;
    22. }
    23. public String getProductName() {
    24. return productName;
    25. }
    26. public void setProductName(String productName) {
    27. this.productName = productName;
    28. }
    29. public Date getOrderDate() {
    30. return orderDate;
    31. }
    32. public void setOrderDate(Date orderDate) {
    33. this.orderDate = orderDate;
    34. }
    35. }
    1. /**
    2. * 对OrderInfo对象生成sql语句
    3. */
    4. public class SQLProvider {
    5. //select xxx,xxx from table where xxx = 'xxx' and xxx = 'xxx' order by xxx desc|asc
    6. public String genQuerySQL(OrderInfo orderInfo) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    7. StringBuffer sql = new StringBuffer("select ");
    8. StringBuffer paramSql = new StringBuffer();
    9. StringBuffer whereSql = new StringBuffer(" where 1=1 ");
    10. Classextends OrderInfo> clazz = orderInfo.getClass();
    11. Table table = clazz.getAnnotation(Table.class);
    12. if (table == null) {
    13. System.out.println("no table");
    14. }
    15. //拿到表名和排序字段和顺序
    16. String tableName = table.tableName();
    17. String order = table.order();
    18. String orderBy = table.orderBy();
    19. Field[] fields = clazz.getDeclaredFields();
    20. for (Field field : fields) {
    21. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    22. if (tableColumn != null) {
    23. paramSql.append(tableColumn.dbColumn()).append(",");
    24. }
    25. String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
    26. Object fieldValue = clazz.getMethod(getterName).invoke(orderInfo);//相当于orderInfo.getOrderId();
    27. if(null==fieldValue || StringUtils.isEmpty(field.toString())){
    28. continue;
    29. }
    30. fieldValue = getColumnType(field, fieldValue);
    31. whereSql.append(" and ").append(tableColumn.dbColumn()).append(" = ").append(fieldValue);
    32. }
    33. sql.append(paramSql.substring(0, paramSql.length() - 1)).append(" from ").append(tableName).append(whereSql);
    34. if (!StringUtils.isEmpty(orderBy)) {
    35. sql.append(" order by ").append(orderBy);
    36. if (!StringUtils.isEmpty(order)) {
    37. sql.append(" " + order);
    38. }
    39. }
    40. return sql.toString();
    41. }
    42. //update table set tableColumn = 'xxx',tableColumn = 'xxx' where pk = ?
    43. public String genUpdateSQL(OrderInfo orderInfo) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    44. StringBuffer sql = new StringBuffer("update ");
    45. StringBuffer setSql = new StringBuffer(" set ");
    46. StringBuffer whereSql = new StringBuffer();
    47. StringBuffer columnSql = new StringBuffer();
    48. Classextends OrderInfo> clazz = orderInfo.getClass();
    49. Table table = clazz.getAnnotation(Table.class);
    50. if (null == table) {
    51. System.out.println("未配置表名");
    52. }
    53. String tableName = table.tableName();
    54. //遍历tableColumn属性
    55. for (Field field : clazz.getDeclaredFields()) {
    56. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    57. if (tableColumn == null) {
    58. continue;
    59. }
    60. if (StringUtils.isEmpty(tableColumn.isPK())) {
    61. String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
    62. Object fieldValue = clazz.getMethod(getterName).invoke(orderInfo);//相当于orderInfo.getField();
    63. if (null == fieldValue) {
    64. continue;
    65. }
    66. fieldValue = getColumnType(field, fieldValue);
    67. columnSql.append(tableColumn.dbColumn()).append(" = ").append(fieldValue).append(" , ");
    68. }
    69. }
    70. setSql.append(columnSql.substring(0, columnSql.length() - 2));
    71. for (Field field : clazz.getDeclaredFields()) {
    72. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    73. boolean ss = StringUtils.isEmpty(whereSql.toString());
    74. if (!StringUtils.isEmpty(tableColumn.isPK()) && ss) {
    75. String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
    76. Object fieldValue = clazz.getMethod(getterName).invoke(orderInfo);//相当于orderInfo.getOrderId();
    77. if (null == fieldValue || StringUtils.isEmpty(field.toString())) {
    78. continue;
    79. }
    80. fieldValue = getColumnType(field, fieldValue);
    81. whereSql.append(" where ");
    82. whereSql.append(tableColumn.dbColumn()).append(" = ").append(fieldValue);
    83. }
    84. if (StringUtils.isEmpty(whereSql.toString())) {
    85. System.out.println("未设置主键,无法修改");
    86. }
    87. }
    88. sql.append(tableName);
    89. sql.append(setSql);
    90. sql.append(whereSql);
    91. return sql.toString();
    92. }
    93. //delete from table where pk = ?
    94. public String genDeleteSQL(OrderInfo orderInfo) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    95. StringBuffer sql = new StringBuffer("delete from ");
    96. StringBuffer where = new StringBuffer();
    97. //找到表名
    98. Classextends OrderInfo> clazz = orderInfo.getClass(); //获取类对象
    99. Table tableAnno = clazz.getAnnotation(Table.class); //反射获取类属性
    100. String tableName = tableAnno.tableName(); //拿到表名
    101. if (null == tableAnno) {
    102. System.out.println("未配置table注解");
    103. }
    104. //找到列名
    105. Field[] fields = clazz.getDeclaredFields();
    106. for (Field field : fields) {
    107. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    108. if (null == tableColumn) {
    109. continue;
    110. }
    111. if (!StringUtils.isEmpty(tableColumn.isPK()) && StringUtils.isEmpty(where.toString())) {
    112. //通过反射找到get方法获取orderid值
    113. String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
    114. Object fieldValue = clazz.getMethod(getterName).invoke(orderInfo);//相当于orderInfo.getOrderId();
    115. if (null == fieldValue) {
    116. System.out.println("未设置主键,无法删除");
    117. continue;
    118. }
    119. fieldValue = getColumnType(field, fieldValue);
    120. where.append(" WHERE ");
    121. where.append(tableColumn.dbColumn()).append(" = ").append(fieldValue);
    122. }
    123. //没有找到主键
    124. if (StringUtils.isEmpty(where.toString())) {
    125. System.out.println("未设置主键,无法删除");
    126. }
    127. }
    128. //拼接sql
    129. sql.append(tableName).append(where);
    130. return sql.toString();
    131. }
    132. public String genUpdateSQL2(OrderInfo orderInfo) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    133. StringBuffer sql = new StringBuffer("update ");
    134. StringBuffer setSql = new StringBuffer(" set ");
    135. StringBuffer whereSql = new StringBuffer();
    136. Classextends OrderInfo> clazz = orderInfo.getClass();
    137. Table table = clazz.getAnnotation(Table.class);
    138. if (table == null) {
    139. System.out.println("table null");
    140. }
    141. String tableName = table.tableName();
    142. Field[] fields = clazz.getDeclaredFields();
    143. for (Field field : fields) {
    144. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    145. if (tableColumn == null) {
    146. continue;
    147. }
    148. //通过反射找到get方法获取orderid值
    149. String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
    150. Object fieldValue = clazz.getMethod(getterName).invoke(orderInfo);//相当于orderInfo.getOrderId();
    151. if (null != fieldValue && !StringUtils.isEmpty(fieldValue.toString()) && StringUtils.isEmpty(tableColumn.isPK())) {
    152. setSql.append(tableColumn.dbColumn()).append(" = ").append(fieldValue).append(",");
    153. }
    154. if (!StringUtils.isEmpty(tableColumn.isPK()) && StringUtils.isEmpty(whereSql.toString())) {
    155. if (null == fieldValue) {
    156. System.out.println("pk is null");
    157. }
    158. fieldValue = getColumnType(field, fieldValue);
    159. whereSql.append(" WHERE ");
    160. whereSql.append(tableColumn.dbColumn()).append(" = ").append(fieldValue);
    161. }
    162. }
    163. if (setSql.length() <= 5) {
    164. System.out.println("no column update");
    165. }
    166. if (StringUtils.isEmpty(whereSql.toString())) {
    167. System.out.println("pk is null");
    168. }
    169. sql.append(tableName).append(setSql.substring(0, setSql.length() - 1)).append(whereSql);
    170. return sql.toString();
    171. }
    172. private Object getColumnType(Field field, Object fieldValue) {
    173. //参数类型转换
    174. if (field.getType() == String.class) {
    175. fieldValue = "'" + fieldValue + "'";
    176. } else if (field.getType() == int.class || field.getType() == Integer.class) {
    177. //...各种类型转换
    178. }
    179. return fieldValue;
    180. }
    181. }
    1. public class ReflectTest {
    2. public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
    3. //解析出orderInfo对应的CRUD操作的sql语句
    4. OrderInfo orderInfo = new OrderInfo();
    5. orderInfo.setOrderId(10001);
    6. orderInfo.setClientName("客户1");
    7. orderInfo.setProductName("商品1");
    8. SQLProvider sqlProvider = new SQLProvider();
    9. System.out.println("增 :" + sqlProvider.genUpdateSQL2(orderInfo));
    10. System.out.println("查 :" + sqlProvider.genQuerySQL(orderInfo));
    11. System.out.println("删 :" + sqlProvider.genDeleteSQL(orderInfo));
    12. }
    13. }

     遗留的问题:

    ①-传入参数是OederInfo,过于具体

    ②-异常没有处理

    ③-参数类型处理没有抽象出来

    2.封装成通用的Service

    1. /**
    2. * 单例数据库链接
    3. */
    4. public class DBUtil {
    5. private volatile static Connection connection;
    6. public static Connection getConnection(){
    7. if(null == connection){
    8. synchronized (DBUtil.class){
    9. if(null == connection){
    10. try {
    11. Class.forName("com.mysql.cj.jdbc.Driver");
    12. connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai","root","root");
    13. }catch (ClassNotFoundException e){
    14. e.printStackTrace();
    15. }catch (SQLException ex){
    16. ex.printStackTrace();
    17. }
    18. }
    19. }
    20. }
    21. return connection;
    22. }
    23. }
    1. /**
    2. * 统一的增删改查
    3. */
    4. public interface BaseService {
    5. //查
    6. List queryData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException, InstantiationException;
    7. //改
    8. int updateData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException;
    9. //删
    10. int deleteData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException;
    11. }
    1. public class BaseServiceImpl implements BaseService {
    2. private Connection connection = DBUtil.getConnection();
    3. private GenSQLProvider genSQLProvider = new GenSQLProvider();
    4. //查询后结果需要通过反射把值设置进去
    5. public List queryData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException, InstantiationException {
    6. ArrayList result = new ArrayList();
    7. //拿到泛型的类类型,不要new对象获取,太low了,用反射
    8. ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
    9. Class repoClazz = (Class)type.getActualTypeArguments()[0];
    10. String sql = genSQLProvider.genQuerySQL(obj);
    11. Statement statement = connection.createStatement();
    12. ResultSet resultSet = statement.executeQuery(sql);
    13. while(resultSet.next()){
    14. //拿到泛型的类类型,不要new对象获取,太low了,用反射
    15. Object instance = repoClazz.newInstance();
    16. Field[] fields = repoClazz.getDeclaredFields();
    17. for (Field field : fields) {
    18. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    19. String columnKey;
    20. //扩展:没有注解也给映射
    21. Object fieldRes;
    22. if(null!= tableColumn){
    23. columnKey = tableColumn.dbColumn();
    24. }else {
    25. columnKey = field.getName(); //没有则用字段的名字做列
    26. }
    27. try {
    28. fieldRes = resultSet.getObject(columnKey, field.getType());
    29. }catch (SQLException e){
    30. continue;
    31. }
    32. String setterName = "set" + field.getName().substring(0,1).toUpperCase() + field.getName().substring(1);
    33. repoClazz.getMethod(setterName,field.getType()).invoke(instance,fieldRes); //相当于instance.setxxx(fieldRes);
    34. }
    35. result.add((T)instance);
    36. }
    37. return result;
    38. }
    39. public int updateData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException {
    40. String sql = genSQLProvider.genUpdateSQL2(obj);
    41. Statement statement = connection.createStatement();
    42. return statement.executeUpdate(sql);
    43. }
    44. public int deleteData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException {
    45. String sql = genSQLProvider.genDeleteSQL(obj);
    46. Statement statement = connection.createStatement();
    47. return statement.executeUpdate(sql);
    48. }
    49. }
    1. /**
    2. * 对OrderInfo对象生成sql语句
    3. */
    4. public class GenSQLProvider {
    5. //select xxx,xxx from table where xxx = 'xxx' and xxx = 'xxx' order by xxx desc|asc
    6. public String genQuerySQL(Object obj) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    7. StringBuffer sql = new StringBuffer("select ");
    8. StringBuffer paramSql = new StringBuffer();
    9. StringBuffer whereSql = new StringBuffer(" where 1=1 ");
    10. Class clazz = obj.getClass();
    11. Table table = clazz.getAnnotation(Table.class);
    12. if (table == null) {
    13. System.out.println("no table");
    14. }
    15. //拿到表名和排序字段和顺序
    16. String tableName = table.tableName();
    17. String order = table.order();
    18. String orderBy = table.orderBy();
    19. Field[] fields = clazz.getDeclaredFields();
    20. for (Field field : fields) {
    21. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    22. if (tableColumn != null) {
    23. paramSql.append(tableColumn.dbColumn()).append(",");
    24. }
    25. String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
    26. Object fieldValue = clazz.getMethod(getterName).invoke(obj);//相当于orderInfo.getOrderId();
    27. if(null==fieldValue || StringUtils.isEmpty(field.toString())){
    28. continue;
    29. }
    30. fieldValue = getColumnType(field, fieldValue);
    31. whereSql.append(" and ").append(tableColumn.dbColumn()).append(" = ").append(fieldValue);
    32. }
    33. sql.append(paramSql.substring(0, paramSql.length() - 1)).append(" from ").append(tableName).append(whereSql);
    34. if (!StringUtils.isEmpty(orderBy)) {
    35. sql.append(" order by ").append(orderBy);
    36. if (!StringUtils.isEmpty(order)) {
    37. sql.append(" " + order);
    38. }
    39. }
    40. return sql.toString();
    41. }
    42. private Object getColumnType(Field field, Object fieldValue) {
    43. //参数类型转换
    44. if (field.getType() == String.class) {
    45. fieldValue = "'" + fieldValue + "'";
    46. } else if (field.getType() == int.class || field.getType() == Integer.class) {
    47. //...各种类型转换
    48. }
    49. return fieldValue;
    50. }
    51. }

    遗留问题:

    ①异常处理

    ②数据库链接参数配置项 --整合MyBatis,主要是集成参数类型转换功能。

    2.2整合MyBatis

    复写Service实现

    1. /**
    2. * 传入的Bean对象
    3. * 不创建对象而使用HasHMap传参是因为会有分页需求,获取版本号之类的
    4. */
    5. @Component
    6. public class MBBaseServiceImpl implements BaseService {
    7. @Autowired
    8. BaseMapper baseMapper;
    9. //TODO:https://www.bilibili.com/video/BV1hd4y1d788?p=14&spm_id_from=pageDriver&vd_source=85a097599612a3ab01f6d380f0d6b0ef
    10. @Override
    11. public List queryData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException, InstantiationException {
    12. ArrayList result = new ArrayList<>();
    13. //拿到要操作Bean对象的类型,repoClazz代表T的具体类型(OrderInfo.class)
    14. ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
    15. Class repoClazz = (Class) type.getActualTypeArguments()[0];
    16. //具体参数的类型
    17. Class objClazz = obj.getClass();
    18. Map paramMap = new HashMap<>();
    19. Field[] fields = objClazz.getDeclaredFields();
    20. for (Field field : fields) {
    21. String getterName = "get" + field.getName().substring(0, 1).toUpperCase() + field.getName().substring(1);
    22. Object fieldValue = obj.getClass().getMethod(getterName).invoke(obj);
    23. if (null != fieldValue) {
    24. paramMap.put(field.getName(), fieldValue);
    25. }
    26. }
    27. List> queryData = baseMapper.selectData(paramMap, repoClazz);
    28. //通过反射来做封装,将Map封装成T实例
    29. for (Map data : queryData) {
    30. Object instance = repoClazz.newInstance();
    31. Field[] fields2 = repoClazz.getDeclaredFields();
    32. for (Field field2 : fields2) {
    33. TableColumn tableColumn = field2.getAnnotation(TableColumn.class);
    34. String columnKey;
    35. Object fieldsRes;
    36. if (null != tableColumn) {
    37. columnKey = tableColumn.dbColumn();
    38. } else {
    39. columnKey = field2.getName();
    40. }
    41. //TODO 要异常处理
    42. fieldsRes = data.get(columnKey);
    43. String setterName = "set" + field2.getName().substring(0, 1) + field2.getName().substring(1);
    44. repoClazz.getMethod(setterName, field2.getType()).invoke(instance, (Integer)fieldsRes);
    45. }
    46. result.add((T) instance);
    47. }
    48. return result;
    49. }
    50. @Override
    51. public int updateData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException {
    52. //拿到要操作Bean对象的类型,repoClazz代表T的具体类型(OrderInfo.class)
    53. ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
    54. Class repoClazz = (Class) type.getActualTypeArguments()[0];
    55. //具体参数的类型
    56. Class objClazz = obj.getClass();
    57. Map param = new HashMap<>();
    58. Field[] fields = objClazz.getDeclaredFields();
    59. for (Field field : fields) {
    60. Object fieldValue = ReflectUtil.getValue(obj, field);
    61. if (null != fieldValue) {
    62. param.put(field.getName(), fieldValue);
    63. }
    64. }
    65. return baseMapper.updateData(param, repoClazz);
    66. }
    67. @Override
    68. public int deleteData(Object obj) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, SQLException {
    69. ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
    70. Class repoClazz = (Class) type.getActualTypeArguments()[0];
    71. Class objClazz = obj.getClass();
    72. Map param = new HashMap<>();
    73. Field[] fields = objClazz.getDeclaredFields();
    74. for (Field field : fields) {
    75. Object fieldValue = ReflectUtil.getValue(obj, field);
    76. if (null != fieldValue) {
    77. param.put(field.getName(), fieldValue);
    78. }
    79. }
    80. int i = baseMapper.deleteData(param, repoClazz);
    81. return i;
    82. }
    83. }
    1. public interface BaseMapper {
    2. /**
    3. * @UpdateProvider:动态生成sql,不用在xml中写。type:指定生成的类。method:指定那个方法生成的
    4. * @param param:传入参数
    5. * @param repo:操作对象
    6. * @return
    7. */
    8. @UpdateProvider(type = MySqlProvider.class, method = "genUpdateSql")
    9. public Integer updateData(@Param("requestData") Map param, @Param("repoClass") Class repo);
    10. @DeleteProvider(type = MySqlProvider.class, method = "genDeleteSql")
    11. public Integer deleteData(@Param("requestData") Map param, @Param("repoClass") Class repo);
    12. @SelectProvider(type = MySqlProvider.class, method = "genSelectSql")
    13. public List> selectData(@Param("requestData") Map param, @Param("repoClass") Class repo);
    14. }
    1. public class MySqlProvider {
    2. public String genUpdateSql(Map param) {
    3. Map paramMap = (Map) param.get("requestData");
    4. Class repoClass = (Class) param.get("repoClass");
    5. Table table = repoClass.getAnnotation(Table.class);
    6. String tableName = table.tableName();
    7. //update table set col1 = #{requestData.attr1},col2=#{requestData.attr2} where orderId = #{request.orderId}
    8. SQL sql = new SQL();
    9. Field[] fields = repoClass.getDeclaredFields();
    10. for (Field field : fields) {
    11. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    12. if (null == tableColumn) {
    13. continue;
    14. }
    15. if (paramMap.containsKey(field.getName()) && StringUtils.isEmpty(tableColumn.isPK())) {
    16. sql.SET(tableColumn.dbColumn() + "= #{requestData." + field.getName() + "}");
    17. }
    18. if (!StringUtils.isEmpty(tableColumn.isPK())) {
    19. sql.WHERE(tableColumn.dbColumn() + " = #{requestData." + field.getName() + "}");
    20. continue;
    21. }
    22. }
    23. sql.UPDATE(tableName);
    24. System.out.println(sql.toString());
    25. return sql.toString();
    26. }
    27. public String genDeleteSql(Map param) {
    28. Map paramMap = (Map) param.get("requestData");
    29. Class repoClass = (Class) param.get("repoClass");
    30. Table table = repoClass.getAnnotation(Table.class);
    31. String tableName = table.tableName();
    32. //delete from order_info where orderId = #{requestData.orderId}
    33. SQL sql = new SQL();
    34. Field[] fields = repoClass.getDeclaredFields();
    35. for (Field field : fields) {
    36. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    37. if (null == tableColumn) {
    38. continue;
    39. }
    40. if (!StringUtils.isEmpty(tableColumn.isPK())) {
    41. sql.WHERE(tableColumn.dbColumn() + " = #{requestData." + field.getName() + "}");
    42. break;
    43. }
    44. }
    45. sql.DELETE_FROM(tableName);
    46. System.out.println(sql.toString());
    47. return sql.toString();
    48. }
    49. public String genSelectSql(Map param) {
    50. Map paramMap = (Map) param.get("requestData");
    51. Class repoClass = (Class) param.get("repoClass");
    52. Table table = repoClass.getAnnotation(Table.class);
    53. String tableName = table.tableName();
    54. //select ***,*** from order_info where xxx = #{xxx} and xxx = #{xxx} order by xxx desc|asc
    55. SQL sql = new SQL();
    56. Field[] fields = repoClass.getDeclaredFields();
    57. for (Field field : fields) {
    58. TableColumn tableColumn = field.getAnnotation(TableColumn.class);
    59. if (null == tableColumn) {
    60. continue;
    61. }
    62. sql.SELECT(tableColumn.dbColumn());
    63. if (paramMap.containsKey(field.getName())) {
    64. sql.WHERE(tableColumn.dbColumn() + " = #{requestData." + field.getName() + "}");
    65. }
    66. }
    67. sql.FROM(tableName);
    68. if (!StringUtils.isEmpty(table.orderBy())) {
    69. sql.ORDER_BY(table.orderBy());
    70. if (!StringUtils.isEmpty(table.order())) {
    71. //添加排序顺序
    72. }
    73. }
    74. System.out.println(sql.toString());
    75. return sql.toString();
    76. }
    77. }
    1. @RunWith(SpringRunner.class)
    2. @SpringBootTest
    3. public class AnnoDemoTest {
    4. @Autowired
    5. OrderInfoService orderInfoService;
    6. @Test
    7. public void queryData() throws Exception {
    8. OrderInfo orderInfo = new OrderInfo();
    9. orderInfo.setOrderId(10003);
    10. orderInfo.setClientName("xuyu");
    11. // int i = orderInfoService.deleteData(orderInfo);
    12. // System.out.println(i);
    13. // int j = orderInfoService.updateData(orderInfo);
    14. // System.out.println(j);
    15. List orderInfos = orderInfoService.queryData(orderInfo);
    16. for (OrderInfo info : orderInfos) {
    17. System.out.println(info);
    18. }
    19. }
    20. }

    3.自动生成

    POJO属性类型有要求,必须与JDBC的返回结果一致。实现将采用自动生成的方式来生成POJO对象。

    1.怎么拿到数据库的表结构?(通过JDBC连接获取)

    1. /**
    2. * 通过JDBC连接获取数据库表结构
    3. */
    4. public class JDBCTest {
    5. public static void main(String[] args) throws ClassNotFoundException, SQLException {
    6. Class.forName("com.mysql.cj.jdbc.Driver");
    7. Properties properties = new Properties();
    8. properties.put("user", "root");
    9. properties.put("password", "root");
    10. properties.put("userInformationSchema", "true"); //加上这个参数就可以从jdbc连接中获取我们想要的结果
    11. Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/test?characterEncoding=utf8&serverTimezone=Asia/Shanghai",
    12. properties);
    13. DatabaseMetaData meta = connection.getMetaData();
    14. System.out.println("==================映射表结构============");
    15. ResultSet tables = meta.getTables("test", "%", "order_info", new String[]{"TABLE"}); //拿到对应的表;参数:库名,全匹配,表名
    16. while (tables.next()) {
    17. ResultSetMetaData metaData = tables.getMetaData();
    18. String table_name = tables.getString("TABLE_NAME"); //拿到表名
    19. String remarks = tables.getString("REMARKS"); //拿到备注
    20. System.out.println("Number for Column:" + metaData.getColumnCount()); //拿到对应列
    21. for (int i = 1; i < metaData.getColumnCount(); i++) {
    22. int metaType = metaData.getColumnType(i);
    23. String metaName = metaData.getColumnName(i);
    24. }
    25. }
    26. System.out.println("==================映射列结构============");
    27. ResultSet columns = meta.getColumns("test", "%", "order_info", "%");//拿到对应列,参数,同上 + 列的全匹配
    28. while (columns.next()) {
    29. String column_name = columns.getString("COLUMN_NAME");//列名
    30. String type_name = columns.getString("TYPE_NAME");//类型
    31. int column_size = columns.getInt("COLUMN_SIZE");//列大小
    32. int decimal_digits = columns.getInt("DECIMAL_DIGITS");//小数点后位数
    33. int nullable = columns.getInt("NULLABLE");//是否为空
    34. String remarks = columns.getString("REMARKS");//注解
    35. System.out.println(column_name + " " + type_name + " " + column_size + " " + decimal_digits + " " + nullable + " " + remarks);
    36. }
    37. System.out.println("==================映射主键信息============");
    38. ResultSet primaryKeys = meta.getPrimaryKeys("test", "%", "order_info");
    39. while (primaryKeys.next()){
    40. ResultSetMetaData metaData = primaryKeys.getMetaData();
    41. int columnCount = metaData.getColumnCount();
    42. for (int i = 1; i < columnCount; i++) {
    43. System.out.println(metaData.getColumnName(i) + " " + primaryKeys.getString(metaData.getColumnName(i)));
    44. }
    45. }
    46. }
    47. }

    2.怎么生成POJO?(①使用StringBuffer拼凑完成的java代码通过流方式实现-MyBatis实现,②freemarker模板引擎)

    https://gitee.com/xuyu294636185/AnnoDemo.git

  • 相关阅读:
    基于springboot的校园二手网站
    深度学习---三好学生各成绩所占权重问题(3)
    Ant Design RangePicker 默认选择时间
    社区治理进化史!拓世法宝化身“虚拟社工”,点亮智能社区的每一个角落
    文件上传预览下载
    基于SpringBoot的学生班级考勤管理系统
    MAC修改python3命令为py
    书籍《佛畏系统》观后感
    HBase 2.x ---- HBase快速入门
    计算机二级WPS 选择题(模拟和解析一)
  • 原文地址:https://blog.csdn.net/xy294636185/article/details/126813661