一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達(dá)式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - Mybatis基于注解形式的sql語句生成實(shí)例代碼

Mybatis基于注解形式的sql語句生成實(shí)例代碼

2021-01-01 12:13jjb_hz Java教程

這篇文章主要介紹了 Mybatis基于注解形式的sql語句生成實(shí)例代碼,需要的朋友可以參考下

對(duì)其做了些優(yōu)化,但此種sql生成方式僅適用于復(fù)雜程度不高的sql,所以實(shí)用性不是很高,僅僅是寫著玩的,知道點(diǎn)mybatis的注解形式的使用方式,可能以后會(huì)逐漸完善起來。第一次寫博客,寫的簡單點(diǎn)。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
package com.bob.config.mvc.mybatis;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 實(shí)體類對(duì)應(yīng)的列
 *
 * @author jjb
 * @create 2017-09-08 14:42
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.METHOD})
public @interface Column {
  /**
   * 當(dāng)前屬性對(duì)應(yīng)的列名
   *
   * @return
   */
  String value() default "";
  /**
   * 當(dāng)前屬性是不是表必須的
   *
   * @return
   */
  boolean required() default true;
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.bob.config.mvc.mybatis;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
 * 實(shí)體類對(duì)應(yīng)的表
 *
 * @author jjb
 * @create 2017-09-08 14:44
 */
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public @interface Table {
  String value() default "";
  /**
   * 當(dāng)前表的主鍵
   *
   * @return
   */
  String key();
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.bob.config.mvc.mybatis;
import org.apache.ibatis.annotations.DeleteProvider;
import org.apache.ibatis.annotations.InsertProvider;
import org.apache.ibatis.annotations.Options;
import org.apache.ibatis.annotations.SelectProvider;
import org.apache.ibatis.annotations.UpdateProvider;
/**
 * Mybatis基礎(chǔ)Mapper
 *
 * @author jjb
 * @create 2017-09-08 14:37
 */
public interface BaseMapper<T> {
  /**
   * 插入語句
   *
   * @param bean
   * @return
   */
  @Options(useGeneratedKeys = true)
  @InsertProvider(type = SqlProvider.class, method = "insert")
  public int insert(T bean);
  /**
   * 刪除語句
   *
   * @param bean
   * @return
   */
  @DeleteProvider(type = SqlProvider.class, method = "delete")
  public int delete(T bean);
  /**
   * 更新語句
   *
   * @param bean
   * @return
   */
  @UpdateProvider(type = SqlProvider.class, method = "update")
  public int update(T bean);
  /**
   * 查找語句
   *
   * @param bean
   * @return
   */
  @SelectProvider(type = SqlProvider.class, method = "select")
  public T findFirst(T bean);
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
package com.bob.config.mvc.mybatis;
import java.time.LocalDate;
/**
 * Mybatis實(shí)體類
 *
 * @author jjb
 * @create 2017-09-08 17:16
 */
@Table(key = "id")
public class MybatisEntity {
  @Column()
  private String id;
  @Column("USER_NAME")
  private String name;
  @Column()
  private Integer age;
  private LocalDate date;
  @Column("ADRESS_NUMBER")
  private Integer userAdressNumber;
  public String getId() {
    return id;
  }
  public void setId(String id) {
    this.id = id;
  }
  public String getName() {
    return name;
  }
  public void setName(String name) {
    this.name = name;
  }
  public Integer getAge() {
    return age;
  }
  public void setAge(Integer age) {
    this.age = age;
  }
  @Column("CUR_DATE")
  public LocalDate getDate() {
    return date;
  }
  public void setDate(LocalDate date) {
    this.date = date;
  }
  public Integer getUserAdressNumber() {
    return userAdressNumber;
  }
  public void setUserAdressNumber(Integer userAdressNumber) {
    this.userAdressNumber = userAdressNumber;
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
package com.bob.config.mvc.mybatis;
import java.lang.reflect.Field;
import java.util.Map;
/**
 * 表到實(shí)體的格式化器
 *
 * @author jjb
 * @create 2017-09-08 14:51
 */
public interface TableFormatter {
  /**
   * 根據(jù)屬性獲取字段名稱
   *
   * @param field
   * @return
   */
  public String getColumnName(Field field);
  /**
   * 獲取主鍵屬性對(duì)應(yīng)的列名
   *
   * @return
   */
  public String getKeyColumnName(Class<?> clazz);
  /**
   * 獲取主鍵的屬性名稱
   *
   * @param clazz
   * @return
   */
  public String getKeyFiledName(Class<?> clazz);
  /**
   * 根據(jù)類獲取表名稱
   *
   * @param clazz
   * @return
   */
  public String getTableName(Class<?> clazz);
  /**
   * 獲取一個(gè)類的所有屬性的映射信息
   *
   * @param clazz
   * @return
   */
  public Map<Field, String> getFieldMappings(Class<?> clazz);
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
package com.bob.config.mvc.mybatis;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.HashMap;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Component;
import org.springframework.util.Assert;
import org.springframework.util.ReflectionUtils;
import org.springframework.util.StringUtils;
/**
 * 依據(jù)駝峰原則來將表的信息格式化為實(shí)體類的信息,在駝峰處改小寫同時(shí)插入下劃線
 *
 * @author jjb
 * @create 2017-09-08 14:55
 */
@Component
public class HumpToUnderLineFormatter implements TableFormatter {
  private static final Logger LOGGER = LoggerFactory.getLogger(HumpToUnderLineFormatter.class);
  private static final Map<Class<?>, Map<Field, String>> FIELD_TO_COLUMN_MAPPINGS = new HashMap<Class<?>, Map<Field, String>>();
  private static final Map<Class, String> CLASS_TO_TABLE_MAPPING = new HashMap<Class, String>();
  private static final StringBuilder SB = new StringBuilder();
  private static final Object LOCK = new Object();
  @Override
  public String getColumnName(Field field) {
    Assert.notNull(field, "屬性不能為空");
    Map<Field, String> mappings = FIELD_TO_COLUMN_MAPPINGS.get(field.getDeclaringClass());
    if (mappings == null) {
      synchronized (LOCK) {
        mappings = FIELD_TO_COLUMN_MAPPINGS.get(field.getDeclaringClass());
        if (mappings == null) {
          mappings = buildMapping(field.getDeclaringClass());
        }
      }
    }
    return mappings.get(field);
  }
  @Override
  public String getKeyColumnName(Class<?> clazz) {
    Table table = checkClass(clazz);
    return getColumnName(ReflectionUtils.findField(clazz,table.key()));
  }
  @Override
  public String getKeyFiledName(Class<?> clazz) {
    Table table = checkClass(clazz);
    Field field = ReflectionUtils.findField(clazz,table.key());
    Assert.state(field != null,"@Table的key()指定的屬性必須存在");
    return field.getName();
  }
  private Table checkClass(Class<?> clazz){
    Assert.isTrue(clazz != null , "與Table對(duì)應(yīng)的Class不能為空");
    Table table = clazz.getAnnotation(Table.class);
    Assert.isTrue(table != null && StringUtils.hasText(table.key()),"["+clazz.getName()+"]必須標(biāo)識(shí)@Table注解且key()不能為空");
    return table;
  }
  @Override
  public String getTableName(Class<?> clazz) {
    Assert.notNull(clazz, "類不能為空");
    Assert.isTrue(clazz.isAnnotationPresent(Table.class), "[" + clazz.getName() + "]類上必須含有@Table注解");
    String name = CLASS_TO_TABLE_MAPPING.get(clazz);
    if (name == null) {
      synchronized (LOCK) {
        name = CLASS_TO_TABLE_MAPPING.get(clazz);
        if (name == null) {
          buildMapping(clazz);
        }
      }
    }
    return CLASS_TO_TABLE_MAPPING.get(clazz);
  }
  @Override
  public Map<Field, String> getFieldMappings(Class<?> clazz) {
    Assert.isTrue(clazz != null && clazz.isAnnotationPresent(Table.class), "與Table對(duì)應(yīng)的Class不能為空且必須標(biāo)識(shí)@Table注解");
    Map<Field, String> mappings = FIELD_TO_COLUMN_MAPPINGS.get(clazz);
    if (mappings == null) {
      synchronized (LOCK) {
        mappings = FIELD_TO_COLUMN_MAPPINGS.get(clazz);
        if (mappings == null) {
          mappings = buildMapping(clazz);
        }
      }
    }
    return FIELD_TO_COLUMN_MAPPINGS.get(clazz);
  }
  /**
   * 創(chuàng)建實(shí)體到表映射
   *
   * @param clazz
   */
  private Map<Field, String> buildMapping(Class<?> clazz) {
    buildClassToTableMapping(clazz);
    Map<Field, String> mappings = new HashMap<Field, String>();
    FIELD_TO_COLUMN_MAPPINGS.put(clazz, mappings);
    buildFiledToColumnMapping(clazz, mappings);
    buildFiledToColumnMappingWithGetter(clazz, mappings);
    return mappings;
  }
  /**
   * 創(chuàng)建類名到表名的名稱映射
   *
   * @param clazz
   */
  private void buildClassToTableMapping(Class<?> clazz) {
    Table table = clazz.getAnnotation(Table.class);
    Assert.notNull(table, "[" + clazz.getName() + "]類上必須有@Table注解");
    CLASS_TO_TABLE_MAPPING.put(clazz, StringUtils.hasText(table.value()) ? table.value() : doFormatWithHunmRule(clazz.getSimpleName()));
  }
  /**
   * 通過Filed建立屬性名稱到字段名稱的映射
   *
   * @param clazz
   * @param mappings
   */
  private void buildFiledToColumnMapping(Class<?> clazz, Map<Field, String> mappings) {
    ReflectionUtils.doWithLocalFields(clazz, (field) -> {
        Column column = field.getAnnotation(Column.class);
        if (column != null) {
          if (Modifier.isStatic(field.getModifiers())) {
            LOGGER.error("[{}]注解不適用于靜態(tài)方法:[{}]", Column.class.toString(), field);
            return;
          }
          mappings.put(field, StringUtils.hasText(column.value()) ? column.value() : doFormatWithHunmRule(field.getName()));
        }
      }
    );
  }
  /**
   * 通過getter()建立屬性名稱到字段名稱的映射
   *
   * @param clazz
   * @param mappings
   */
  private void buildFiledToColumnMappingWithGetter(Class<?> clazz, Map<Field, String> mappings) {
    ReflectionUtils.doWithLocalMethods(clazz, (method) -> {
        Column column = method.getAnnotation(Column.class);
        if (column != null) {
          if (Modifier.isStatic(method.getModifiers())) {
            LOGGER.warn("[{}]注解不適用于靜態(tài)方法: [{}]", Column.class.toString(), method);
            return;
          }
          if (!method.getName().startsWith("get") || method.getParameterTypes().length > 0) {
            LOGGER.warn("[{}]注解只適用于getter方法,而非: [{}]方法", Column.class.toString(), method);
            return;
          }
          String fieldName = BeanUtils.findPropertyForMethod(method).getName();
          mappings.put(ReflectionUtils.findField(clazz, fieldName),
            StringUtils.hasText(column.value()) ? column.value() : doFormatWithHunmRule(fieldName));
        }
      }
    );
  }
  /**
   * 依據(jù)駝峰原則格式化屬性或者類名稱,在駝峰處改小寫同時(shí)前一位插入下劃線,忽略首字母
   *
   * @param name
   * @return
   */
  private static String doFormatWithHunmRule(String name) {
    Assert.hasText(name, "屬性或者類名稱不能為空");
    SB.delete(0, SB.length());
    SB.append(toUpperCase(name.charAt(0)));
    for (int i = 1; i < name.length(); i++) {
      if (isUpperCase(name.charAt(i))) {
        SB.append("_");
      }
      SB.append(toUpperCase(name.charAt(i)));
    }
    return SB.toString();
  }
  /**
   * 將字符轉(zhuǎn)換為大寫
   *
   * @param ch
   * @return
   */
  private static char toUpperCase(char ch) {
    return Character.toUpperCase(ch);
  }
  /**
   * 判斷是否為大寫
   *
   * @param ch
   * @return
   */
  private static boolean isUpperCase(char ch) {
    return Character.isUpperCase(ch);
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package com.bob.config.mvc.mybatis;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import java.util.Map.Entry;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.StringUtils;
/**
 * Mybatis的SQL語句供應(yīng)器
 *
 * @author jjb
 * @create 2017-09-08 14:37
 */
public class SqlProvider {
  private static final Logger LOGGER = LoggerFactory.getLogger(SqlProvider.class);
  private TableFormatter tableFormat = new HumpToUnderLineFormatter();
  /**
   * 根據(jù)Bean對(duì)象生成插入SQL語句
   *
   * @param bean
   * @return
   */
  public String insert(Object bean) {
    Class<?> beanClass = bean.getClass();
    String tableName = tableFormat.getTableName(beanClass);
    StringBuilder insertSql = new StringBuilder();
    List<String> columns = new ArrayList<String>();
    List<String> values = new ArrayList<String>();
    insertSql.append("INSERT INTO ").append(tableName).append("(");
    try {
      for (Entry<Field, String> entry : tableFormat.getFieldMappings(beanClass).entrySet()) {
        Field field = entry.getKey();
        field.setAccessible(true);
        if (field.get(bean) != null) {
          columns.add(entry.getValue());
          values.add("#{" + field.getName() + "}");
        }
      }
    } catch (Exception e) {
      new RuntimeException("get insert sql has exceptoin:" + e);
    }
    int columnSize = columns.size();
    for (int i = 0; i < columnSize; i++) {
      insertSql.append(columns.get(i));
      insertSql.append(i != columnSize - 1 ? "," : ") VALUES(");
    }
    for (int i = 0; i < columnSize; i++) {
      insertSql.append(values.get(i));
      insertSql.append(i != columnSize - 1 ? "," : ")");
    }
    return insertSql.toString();
  }
  /**
   * 根據(jù)Bean對(duì)象生成更新SQL語句
   *
   * @param bean
   * @return
   */
  public String update(Object bean) {
    Class<?> beanClass = bean.getClass();
    String tableName = tableFormat.getTableName(beanClass);
    StringBuilder updateSql = new StringBuilder();
    updateSql.append(" UPDATE ").append(tableName).append(" SET ");
    try {
      for (Entry<Field, String> entry : tableFormat.getFieldMappings(beanClass).entrySet()) {
        Field field = entry.getKey();
        field.setAccessible(true);
        if (field.get(bean) != null) {
          updateSql.append(entry.getValue()).append("=#{").append(field.getName()).append("},");
        }
      }
      updateSql.deleteCharAt(updateSql.length() - 1);
    } catch (Exception e) {
      new RuntimeException("get update sql is exceptoin:" + e);
    }
    updateSql.append(" WHERE ").append(tableFormat.getKeyColumnName(beanClass) + " =#{" + tableFormat.getKeyFiledName(beanClass) + "}");
    return updateSql.toString();
  }
  /**
   * 根據(jù)Bean對(duì)象生成刪除SQL語句
   *
   * @param bean
   * @return
   */
  public String delete(Object bean) {
    Class<?> beanClass = bean.getClass();
    String tableName = tableFormat.getTableName(beanClass);
    StringBuilder deleteSql = new StringBuilder();
    deleteSql.append(" DELETE FROM ").append(tableName).append(" WHERE ");
    try {
      for (Entry<Field, String> entry : tableFormat.getFieldMappings(beanClass).entrySet()) {
        Field field = entry.getKey();
        field.setAccessible(true);
        if (field.get(bean) != null) {
          deleteSql.append(entry.getValue()).append("=#{").append(field.getName()).append("} AND ");
        }
      }
      deleteSql.delete(deleteSql.length() - 5, deleteSql.length() - 1);
    } catch (Exception e) {
      new RuntimeException("get delete sql is exceptoin:" + e);
    }
    return deleteSql.toString();
  }
  /**
   * 生成查詢SQL語句
   *
   * @param bean
   * @return
   */
  public String select(Object bean) {
    Class<?> beanClass = bean.getClass();
    String tableName = tableFormat.getTableName(beanClass);
    StringBuilder selectSql = new StringBuilder();
    List<String> columns = new ArrayList<String>();
    List<String> values = new ArrayList<String>();
    selectSql.append("SELECT ");
    try {
      for (Entry<Field, String> entry : tableFormat.getFieldMappings(beanClass).entrySet()) {
        Field field = entry.getKey();
        field.setAccessible(true);
        selectSql.append(entry.getValue() + ",");
        if (field.get(bean) != null) {
          columns.add(entry.getValue());
          values.add("#{" + field.getName() + "}");
        }
      }
      selectSql.deleteCharAt(selectSql.length() - 1);
    } catch (Exception e) {
      new RuntimeException("get select sql is exceptoin:" + e);
    }
    selectSql.append(" FROM ").append(tableName).append(" WHERE ");
    int columnSize = columns.size();
    for (int i = 0; i < columnSize; i++) {
      selectSql.append(columns.get(i)).append("=").append(values.get(i)).append(" AND ");
    }
    selectSql.delete(selectSql.length() - 5, selectSql.length() - 1);
    return selectSql.toString();
  }
}
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
package com.bob.test.concrete.mysqlGenerate;
import java.time.LocalDate;
import com.bob.config.mvc.mybatis.MybatisEntity;
import com.bob.config.mvc.mybatis.SqlProvider;
import org.junit.Before;
import org.junit.Test;
/**
 * Mysql基于注解形式的sql語句生成測(cè)試
 *
 * @author jjb
 * @create 2017-09-11 11:10
 */
public class MysqlGenerateTest {
  private SqlProvider sqlProvider;
  private MybatisEntity mybatisEntity;
  @Before
  public void doBefore(){
    sqlProvider = new SqlProvider();
    mybatisEntity = new MybatisEntity();
    mybatisEntity.setId("0015415");
    mybatisEntity.setName("lanboal");
    mybatisEntity.setAge(28);
    mybatisEntity.setDate(LocalDate.now());
    mybatisEntity.setUserAdressNumber(24);
  }
  @Test
  public void testInsert(){
    String sql = sqlProvider.insert(mybatisEntity);
    System.out.println(sql);
  }
  @Test
  public void testUpdate(){
    String sql = sqlProvider.update(mybatisEntity);
    System.out.println(sql);
  }
  @Test
  public void testDelete(){
    String sql = sqlProvider.delete(mybatisEntity);
    System.out.println(sql);
  }
  @Test
  public void testSelect(){
    String sql = sqlProvider.select(mybatisEntity);
    System.out.println(sql);
  }
}

總結(jié)

以上所述是小編給大家介紹的 Mybatis基于注解形式的sql語句生成實(shí)例代碼,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)服務(wù)器之家網(wǎng)站的支持!

原文鏈接:http://blog.csdn.net/longdayu4544/article/details/77931795

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 全是女性放屁角色的手游 | 好爽好深好猛好舒服视频上 | 大乳孕妇一级毛片 | japanese乱子mate| 公交车揉捏大乳呻吟喘娇 | 欧美不卡一区二区三区免 | 三上悠亚国产精品一区 | 999久久久免费精品国产牛牛 | 精品丰满人妻无套内射 | 热久久最新地址 | 日本特黄一级大片 | 日本激情小说 | 美女吃男生鸡鸡 | 韩国丽卡三级作品 | 国产成人www免费人成看片 | 91chinese 永久免费 | 亚洲第一天堂无码专区 | 九九精品成人免费国产片 | 久久精品熟女亚洲AV国产 | 美女扒开胸罩露出奶了无遮挡免费 | 99九九精品视频 | 欧美日韩国产精品综合 | 暖暖 免费 高清 日本 中文 | 娇妻被又大又粗又长又硬好爽 | 男人香蕉好大好爽视频 | 国产99久久久国产精品成人 | 国产精品一级片 | 好大用力深一点视频 | 日本96在线精品视频免费观看 | a级黄色片免费 | 亚洲欧美日韩精品久久亚洲区 | 成人免费公开视频 | 青青草精品在线观看 | 色偷偷亚洲综合网亚洲 | 欧美亚洲一区二区三区在线 | 精品久久久久久久国产潘金莲 | 天天干夜夜拍 | 古代双性美人被老糟蹋 | 40岁女人三级全黄 | 日韩免费观看成第15集 | 欧美同志gaypronvideos |