Mybatis基于注解形式的sql语句生成实例代码
对其做了些优化,但此种sql生成方式仅适用于复杂程度不高的sql,所以实用性不是很高,仅仅是写着玩的,知道点mybatis的注解形式的使用方式,可能以后会逐渐完善起来。第一次写博客,写的简单点。
packagecom.bob.config.mvc.mybatis;
importjava.lang.annotation.Documented;
importjava.lang.annotation.ElementType;
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
importjava.lang.annotation.Target;
/**
*实体类对应的列
*
*@authorjjb
*@create2017-09-0814:42
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD,ElementType.METHOD})
public@interfaceColumn{
/**
*当前属性对应的列名
*
*@return
*/
Stringvalue()default"";
/**
*当前属性是不是表必须的
*
*@return
*/
booleanrequired()defaulttrue;
}
packagecom.bob.config.mvc.mybatis;
importjava.lang.annotation.Documented;
importjava.lang.annotation.ElementType;
importjava.lang.annotation.Retention;
importjava.lang.annotation.RetentionPolicy;
importjava.lang.annotation.Target;
/**
*实体类对应的表
*
*@authorjjb
*@create2017-09-0814:44
*/
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.TYPE})
public@interfaceTable{
Stringvalue()default"";
/**
*当前表的主键
*
*@return
*/
Stringkey();
}
packagecom.bob.config.mvc.mybatis; importorg.apache.ibatis.annotations.DeleteProvider; importorg.apache.ibatis.annotations.InsertProvider; importorg.apache.ibatis.annotations.Options; importorg.apache.ibatis.annotations.SelectProvider; importorg.apache.ibatis.annotations.UpdateProvider; /** *Mybatis基础Mapper * *@authorjjb *@create2017-09-0814:37 */ publicinterfaceBaseMapper{ /** *插入语句 * *@parambean *@return */ @Options(useGeneratedKeys=true) @InsertProvider(type=SqlProvider.class,method="insert") publicintinsert(Tbean); /** *删除语句 * *@parambean *@return */ @DeleteProvider(type=SqlProvider.class,method="delete") publicintdelete(Tbean); /** *更新语句 * *@parambean *@return */ @UpdateProvider(type=SqlProvider.class,method="update") publicintupdate(Tbean); /** *查找语句 * *@parambean *@return */ @SelectProvider(type=SqlProvider.class,method="select") publicTfindFirst(Tbean); }
packagecom.bob.config.mvc.mybatis;
importjava.time.LocalDate;
/**
*Mybatis实体类
*
*@authorjjb
*@create2017-09-0817:16
*/
@Table(key="id")
publicclassMybatisEntity{
@Column()
privateStringid;
@Column("USER_NAME")
privateStringname;
@Column()
privateIntegerage;
privateLocalDatedate;
@Column("ADRESS_NUMBER")
privateIntegeruserAdressNumber;
publicStringgetId(){
returnid;
}
publicvoidsetId(Stringid){
this.id=id;
}
publicStringgetName(){
returnname;
}
publicvoidsetName(Stringname){
this.name=name;
}
publicIntegergetAge(){
returnage;
}
publicvoidsetAge(Integerage){
this.age=age;
}
@Column("CUR_DATE")
publicLocalDategetDate(){
returndate;
}
publicvoidsetDate(LocalDatedate){
this.date=date;
}
publicIntegergetUserAdressNumber(){
returnuserAdressNumber;
}
publicvoidsetUserAdressNumber(IntegeruserAdressNumber){
this.userAdressNumber=userAdressNumber;
}
}
packagecom.bob.config.mvc.mybatis;
importjava.lang.reflect.Field;
importjava.util.Map;
/**
*表到实体的格式化器
*
*@authorjjb
*@create2017-09-0814:51
*/
publicinterfaceTableFormatter{
/**
*根据属性获取字段名称
*
*@paramfield
*@return
*/
publicStringgetColumnName(Fieldfield);
/**
*获取主键属性对应的列名
*
*@return
*/
publicStringgetKeyColumnName(Class>clazz);
/**
*获取主键的属性名称
*
*@paramclazz
*@return
*/
publicStringgetKeyFiledName(Class>clazz);
/**
*根据类获取表名称
*
*@paramclazz
*@return
*/
publicStringgetTableName(Class>clazz);
/**
*获取一个类的所有属性的映射信息
*
*@paramclazz
*@return
*/
publicMapgetFieldMappings(Class>clazz);
}
packagecom.bob.config.mvc.mybatis;
importjava.lang.reflect.Field;
importjava.lang.reflect.Modifier;
importjava.util.HashMap;
importjava.util.Map;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.beans.BeanUtils;
importorg.springframework.stereotype.Component;
importorg.springframework.util.Assert;
importorg.springframework.util.ReflectionUtils;
importorg.springframework.util.StringUtils;
/**
*依据驼峰原则来将表的信息格式化为实体类的信息,在驼峰处改小写同时插入下划线
*
*@authorjjb
*@create2017-09-0814:55
*/
@Component
publicclassHumpToUnderLineFormatterimplementsTableFormatter{
privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(HumpToUnderLineFormatter.class);
privatestaticfinalMap,Map>FIELD_TO_COLUMN_MAPPINGS=newHashMap,Map>();
privatestaticfinalMapCLASS_TO_TABLE_MAPPING=newHashMap();
privatestaticfinalStringBuilderSB=newStringBuilder();
privatestaticfinalObjectLOCK=newObject();
@Override
publicStringgetColumnName(Fieldfield){
Assert.notNull(field,"属性不能为空");
Mapmappings=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());
}
}
}
returnmappings.get(field);
}
@Override
publicStringgetKeyColumnName(Class>clazz){
Tabletable=checkClass(clazz);
returngetColumnName(ReflectionUtils.findField(clazz,table.key()));
}
@Override
publicStringgetKeyFiledName(Class>clazz){
Tabletable=checkClass(clazz);
Fieldfield=ReflectionUtils.findField(clazz,table.key());
Assert.state(field!=null,"@Table的key()指定的属性必须存在");
returnfield.getName();
}
privateTablecheckClass(Class>clazz){
Assert.isTrue(clazz!=null,"与Table对应的Class不能为空");
Tabletable=clazz.getAnnotation(Table.class);
Assert.isTrue(table!=null&&StringUtils.hasText(table.key()),"["+clazz.getName()+"]必须标识@Table注解且key()不能为空");
returntable;
}
@Override
publicStringgetTableName(Class>clazz){
Assert.notNull(clazz,"类不能为空");
Assert.isTrue(clazz.isAnnotationPresent(Table.class),"["+clazz.getName()+"]类上必须含有@Table注解");
Stringname=CLASS_TO_TABLE_MAPPING.get(clazz);
if(name==null){
synchronized(LOCK){
name=CLASS_TO_TABLE_MAPPING.get(clazz);
if(name==null){
buildMapping(clazz);
}
}
}
returnCLASS_TO_TABLE_MAPPING.get(clazz);
}
@Override
publicMapgetFieldMappings(Class>clazz){
Assert.isTrue(clazz!=null&&clazz.isAnnotationPresent(Table.class),"与Table对应的Class不能为空且必须标识@Table注解");
Mapmappings=FIELD_TO_COLUMN_MAPPINGS.get(clazz);
if(mappings==null){
synchronized(LOCK){
mappings=FIELD_TO_COLUMN_MAPPINGS.get(clazz);
if(mappings==null){
mappings=buildMapping(clazz);
}
}
}
returnFIELD_TO_COLUMN_MAPPINGS.get(clazz);
}
/**
*创建实体到表映射
*
*@paramclazz
*/
privateMapbuildMapping(Class>clazz){
buildClassToTableMapping(clazz);
Mapmappings=newHashMap();
FIELD_TO_COLUMN_MAPPINGS.put(clazz,mappings);
buildFiledToColumnMapping(clazz,mappings);
buildFiledToColumnMappingWithGetter(clazz,mappings);
returnmappings;
}
/**
*创建类名到表名的名称映射
*
*@paramclazz
*/
privatevoidbuildClassToTableMapping(Class>clazz){
Tabletable=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建立属性名称到字段名称的映射
*
*@paramclazz
*@parammappings
*/
privatevoidbuildFiledToColumnMapping(Class>clazz,Mapmappings){
ReflectionUtils.doWithLocalFields(clazz,(field)->{
Columncolumn=field.getAnnotation(Column.class);
if(column!=null){
if(Modifier.isStatic(field.getModifiers())){
LOGGER.error("[{}]注解不适用于静态方法:[{}]",Column.class.toString(),field);
return;
}
mappings.put(field,StringUtils.hasText(column.value())?column.value():doFormatWithHunmRule(field.getName()));
}
}
);
}
/**
*通过getter()建立属性名称到字段名称的映射
*
*@paramclazz
*@parammappings
*/
privatevoidbuildFiledToColumnMappingWithGetter(Class>clazz,Mapmappings){
ReflectionUtils.doWithLocalMethods(clazz,(method)->{
Columncolumn=method.getAnnotation(Column.class);
if(column!=null){
if(Modifier.isStatic(method.getModifiers())){
LOGGER.warn("[{}]注解不适用于静态方法:[{}]",Column.class.toString(),method);
return;
}
if(!method.getName().startsWith("get")||method.getParameterTypes().length>0){
LOGGER.warn("[{}]注解只适用于getter方法,而非:[{}]方法",Column.class.toString(),method);
return;
}
StringfieldName=BeanUtils.findPropertyForMethod(method).getName();
mappings.put(ReflectionUtils.findField(clazz,fieldName),
StringUtils.hasText(column.value())?column.value():doFormatWithHunmRule(fieldName));
}
}
);
}
/**
*依据驼峰原则格式化属性或者类名称,在驼峰处改小写同时前一位插入下划线,忽略首字母
*
*@paramname
*@return
*/
privatestaticStringdoFormatWithHunmRule(Stringname){
Assert.hasText(name,"属性或者类名称不能为空");
SB.delete(0,SB.length());
SB.append(toUpperCase(name.charAt(0)));
for(inti=1;i
packagecom.bob.config.mvc.mybatis;
importjava.lang.reflect.Field;
importjava.util.ArrayList;
importjava.util.List;
importjava.util.Map.Entry;
importorg.slf4j.Logger;
importorg.slf4j.LoggerFactory;
importorg.springframework.util.StringUtils;
/**
*Mybatis的SQL语句供应器
*
*@authorjjb
*@create2017-09-0814:37
*/
publicclassSqlProvider{
privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(SqlProvider.class);
privateTableFormattertableFormat=newHumpToUnderLineFormatter();
/**
*根据Bean对象生成插入SQL语句
*
*@parambean
*@return
*/
publicStringinsert(Objectbean){
Class>beanClass=bean.getClass();
StringtableName=tableFormat.getTableName(beanClass);
StringBuilderinsertSql=newStringBuilder();
Listcolumns=newArrayList();
Listvalues=newArrayList();
insertSql.append("INSERTINTO").append(tableName).append("(");
try{
for(Entryentry:tableFormat.getFieldMappings(beanClass).entrySet()){
Fieldfield=entry.getKey();
field.setAccessible(true);
if(field.get(bean)!=null){
columns.add(entry.getValue());
values.add("#{"+field.getName()+"}");
}
}
}catch(Exceptione){
newRuntimeException("getinsertsqlhasexceptoin:"+e);
}
intcolumnSize=columns.size();
for(inti=0;ibeanClass=bean.getClass();
StringtableName=tableFormat.getTableName(beanClass);
StringBuilderupdateSql=newStringBuilder();
updateSql.append("UPDATE").append(tableName).append("SET");
try{
for(Entryentry:tableFormat.getFieldMappings(beanClass).entrySet()){
Fieldfield=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(Exceptione){
newRuntimeException("getupdatesqlisexceptoin:"+e);
}
updateSql.append("WHERE").append(tableFormat.getKeyColumnName(beanClass)+"=#{"+tableFormat.getKeyFiledName(beanClass)+"}");
returnupdateSql.toString();
}
/**
*根据Bean对象生成删除SQL语句
*
*@parambean
*@return
*/
publicStringdelete(Objectbean){
Class>beanClass=bean.getClass();
StringtableName=tableFormat.getTableName(beanClass);
StringBuilderdeleteSql=newStringBuilder();
deleteSql.append("DELETEFROM").append(tableName).append("WHERE");
try{
for(Entryentry:tableFormat.getFieldMappings(beanClass).entrySet()){
Fieldfield=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(Exceptione){
newRuntimeException("getdeletesqlisexceptoin:"+e);
}
returndeleteSql.toString();
}
/**
*生成查询SQL语句
*
*@parambean
*@return
*/
publicStringselect(Objectbean){
Class>beanClass=bean.getClass();
StringtableName=tableFormat.getTableName(beanClass);
StringBuilderselectSql=newStringBuilder();
Listcolumns=newArrayList();
Listvalues=newArrayList();
selectSql.append("SELECT");
try{
for(Entryentry:tableFormat.getFieldMappings(beanClass).entrySet()){
Fieldfield=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(Exceptione){
newRuntimeException("getselectsqlisexceptoin:"+e);
}
selectSql.append("FROM").append(tableName).append("WHERE");
intcolumnSize=columns.size();
for(inti=0;i
packagecom.bob.test.concrete.mysqlGenerate;
importjava.time.LocalDate;
importcom.bob.config.mvc.mybatis.MybatisEntity;
importcom.bob.config.mvc.mybatis.SqlProvider;
importorg.junit.Before;
importorg.junit.Test;
/**
*Mysql基于注解形式的sql语句生成测试
*
*@authorjjb
*@create2017-09-1111:10
*/
publicclassMysqlGenerateTest{
privateSqlProvidersqlProvider;
privateMybatisEntitymybatisEntity;
@Before
publicvoiddoBefore(){
sqlProvider=newSqlProvider();
mybatisEntity=newMybatisEntity();
mybatisEntity.setId("0015415");
mybatisEntity.setName("lanboal");
mybatisEntity.setAge(28);
mybatisEntity.setDate(LocalDate.now());
mybatisEntity.setUserAdressNumber(24);
}
@Test
publicvoidtestInsert(){
Stringsql=sqlProvider.insert(mybatisEntity);
System.out.println(sql);
}
@Test
publicvoidtestUpdate(){
Stringsql=sqlProvider.update(mybatisEntity);
System.out.println(sql);
}
@Test
publicvoidtestDelete(){
Stringsql=sqlProvider.delete(mybatisEntity);
System.out.println(sql);
}
@Test
publicvoidtestSelect(){
Stringsql=sqlProvider.select(mybatisEntity);
System.out.println(sql);
}
}
总结
以上所述是小编给大家介绍的Mybatis基于注解形式的sql语句生成实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!