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 >(); privatestaticfinalMap CLASS_TO_TABLE_MAPPING=newHashMap (); privatestaticfinalStringBuilderSB=newStringBuilder(); privatestaticfinalObjectLOCK=newObject(); @Override publicStringgetColumnName(Fieldfield){ Assert.notNull(field,"属性不能为空"); Map 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()); } } } 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 publicMap getFieldMappings(Class>clazz){ Assert.isTrue(clazz!=null&&clazz.isAnnotationPresent(Table.class),"与Table对应的Class不能为空且必须标识@Table注解"); Map 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); } } } returnFIELD_TO_COLUMN_MAPPINGS.get(clazz); } /** *创建实体到表映射 * *@paramclazz */ privateMap buildMapping(Class>clazz){ buildClassToTableMapping(clazz); Map mappings=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,Map mappings){ 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,Map mappings){ 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 (); List values=newArrayList (); insertSql.append("INSERTINTO").append(tableName).append("("); try{ for(Entry entry: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;i beanClass=bean.getClass(); StringtableName=tableFormat.getTableName(beanClass); StringBuilderupdateSql=newStringBuilder(); updateSql.append("UPDATE").append(tableName).append("SET"); try{ for(Entry entry: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(Entry entry: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(); List columns=newArrayList (); List values=newArrayList (); selectSql.append("SELECT"); try{ for(Entry entry: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语句生成实例代码,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对毛票票网站的支持!