AOP應用,根據java實體自動創建更新數據庫SQLServer

主要思想:1.自定義註解,標識實體和字段,填寫字段類型、備註等信息 2.實現切面,動態拼接sql,執行更新數據庫(Mybatis/Hibernat/Jdbc)操作。3.添加啓動器,只在項目啓動時執行一次。

功能上 類似於SpringData JPA的自動更新、校驗數據庫

javax.servlet.ServletContextListener
WebApplicationContext webApplicationContext = WebApplicationContextUtils.getWebApplicationContext(event.getServletContext());
	
logger.info("hibernate.hbm2ddl.auto:"+systemService.getHibernate_hbm2ddl_auto());
		if (!"none".equals(systemService.getHibernate_hbm2ddl_auto())) {
		
					
				    long a=	DateUtils.getMillis();
					SessionFactory sessionFactory = (SessionFactory) webApplicationContext.getBean("sessionFactory");
					JdbcTemplate jdbcTemplate = (JdbcTemplate) webApplicationContext.getBean("jdbcTemplate");
					Map<String, ClassMetadata> map= sessionFactory.getAllClassMetadata();
					logger.info("處理數據庫字段類型長度備註開始,預計耗時 "+map.size()*5236+"ms");
					for (int i = 0; i < map.size(); i++) {
						System.out.print("-");
					}
					System.out.println();
					
					for(Entry<String, ClassMetadata> entry:map.entrySet()){
						ArrayList<String> arrayList=new ArrayList<String>();
					
						ClassMetadata classMetadata=entry.getValue();
						String[] propertyNames= classMetadata.getPropertyNames();
						Map<String, String> propertyNameMap=new HashMap<String, String>();
						for (String propertyName : propertyNames) {
							propertyNameMap.put("get"+propertyName.toLowerCase(), propertyName);
						}
						propertyNameMap.put("get"+classMetadata.getIdentifierPropertyName().toLowerCase(), classMetadata.getIdentifierPropertyName());
						
						Table table=(Table) classMetadata.getMappedClass().getAnnotation(Table.class);//獲取實體類上的Table 註解
						String tableName=table.name();
						Comment comment=(Comment) classMetadata.getMappedClass().getAnnotation(Comment.class);//獲取實體類上的Table 註解
						Method [] methods= classMetadata.getMappedClass().getMethods();//實體中所有的get方法
						//添加表註釋
						 if (comment!=null) {
							 arrayList.add(String.format ("EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'%s' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'%s'",comment.value(),tableName));
							 arrayList.add(String.format ("EXEC sys.sp_updateextendedproperty @name=N'MS_Description', @value=N'%s' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'%s'",comment.value(),tableName));
						}
						 for (Method method : methods) {
							 Comment commentCol=(Comment) method.getAnnotation(Comment.class);//獲取get方法上的 註解
							 Column column=(Column) method.getAnnotation(Column.class);//獲取get方法上的 註解
							 String colName=null;
							 if (column!=null) {
								if (StringUtil.isNotBlank(column.name())  ) {
									colName=column.name();
								}else {
									colName=propertyNameMap.get(method.getName().toLowerCase());
								}
							}
							 if (commentCol!=null&&colName!=null) {
								 arrayList.add( String.format (" EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'%s' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'%s', @level2type=N'COLUMN',@level2name=N'%s'",commentCol.value(),tableName,colName));
								 arrayList.add( String.format (" EXEC sys.sp_updateextendedproperty  @name=N'MS_Description', @value=N'%s' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'%s', @level2type=N'COLUMN',@level2name=N'%s'",commentCol.value(),tableName,colName));
							}
							 if (column!=null&&method.getReturnType().equals(String.class)) {
								 if (commentCol!=null&&StringUtil.isNotEmpty(commentCol.fieldType())) {//如果定義了字段類型
									 if (colName.equals(classMetadata.getIdentifierPropertyName())) {//主鍵
										 StringBuilder sql=new StringBuilder();
										 sql.append("   DECLARE @s nvarchar(500); ");
										 sql.append("   SELECT  ");
										 sql.append("   	@s = 'alter   table ' + b.name + ' drop constraint ' + a.name ");
										 sql.append("   FROM sysobjects a  ");
										 sql.append("   LEFT JOIN sysobjects b  ");
										 sql.append("   	ON a.parent_obj = b.id  ");
										 sql.append("   WHERE a.xtype = 'PK' ");
										 sql.append("   AND b.name = '"+tableName+"'   ; ");
										 sql.append("   EXEC (@s)	; ");	
										 sql.append(String.format (" alter table %s alter column %s %s not null  ;", tableName, colName,commentCol.fieldType() ))	 ;
										 sql.append(String.format (" alter table %s add constraint  PK_%s   primary key( %s  );",tableName,tableName,colName));
										 arrayList.add( sql.toString());
									}else {
										 arrayList.add( String.format (" alter table %s alter column %s %s ", tableName, colName,commentCol.fieldType() ));
									}
								}else {
									if (colName.equals(classMetadata.getIdentifierPropertyName())) {//主鍵
										 StringBuilder sql=new StringBuilder();
										 sql.append("   DECLARE @s nvarchar(500); ");
										 sql.append("   SELECT  ");
										 sql.append("   	@s = 'alter   table ' + b.name + ' drop constraint ' + a.name ");
										 sql.append("   FROM sysobjects a  ");
										 sql.append("   LEFT JOIN sysobjects b  ");
										 sql.append("   	ON a.parent_obj = b.id  ");
										 sql.append("   WHERE a.xtype = 'PK' ");
										 sql.append("   AND b.name = '"+tableName+"'   ; ");
										 sql.append("   EXEC (@s)	; ");	
										 sql.append(String.format (" alter table %s alter column %s nvarchar(%d) not null  ;", tableName, colName,column.length() ))	 ;
										 sql.append(String.format (" alter table %s add constraint  PK_%s   primary key( %s  );",tableName,tableName,colName));
										 arrayList.add( sql.toString());
									}else {
										 arrayList.add( String.format (" alter table %s alter column %s nvarchar(%d) ", tableName, colName,column.length() ));
									}
								}
								 
								
							}
						}
						for (String string : arrayList) {
							try {
								jdbcTemplate.execute(string);
								logger.debug("execSQL{}"+string);
							} catch (Exception e) {
								// TODO: handle exception
							}
							
						} 
						
						System.out.print(">");
					}
					System.out.println();
					long b=		DateUtils.getMillis();
					logger.info("處理數據庫字段類型長度備註結束 耗時:{}"+(b-a)+"ms");
		
		}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章