-

   rss_rss_hh_new

 - e-mail

 

 -

 LiveInternet.ru:
: 17.03.2011
:
:
: 51

:


[ ] , @Cleanup

, 30 2017 . 19:36 +
vtarasoff 19:36

, @Cleanup

, .

- Unknown Ltd. . , .

. , .

. . , . XML, , BLOB. , , , . , . , , . , , , . --. . , :

  • , , ,
  • , , , CLOB XML , BLOB - XML

. .

.

, . , . . . :

public class MigratorV1  {
	
	private Connection conn; // Injected
	private SAXParser xmlParser; // Injected
	private XMLOutputFactory xmlFactory; // Injected
	
    public void migrate() throws Exception {
    	PreparedStatement selectOldContent = conn.prepareStatement("select content from old_data where id = ?");
    	PreparedStatement insertNewContent = conn.prepareStatement("insert into new_data (id, scheme, data) values (?, ?, ?)");
    	
    	ResultSet oldIdResult = conn.createStatement().executeQuery("select id from old_data");
    	
    	while (oldIdResult.next()) {
    		long id = oldIdResult.getLong(1);
    		
    		selectOldContent.setLong(1, id);
    		
        	ResultSet oldContentResult = selectOldContent.executeQuery();
        	oldContentResult.next();
        	
        	Blob oldContent = oldContentResult.getBlob(1);
    		Reader oldContentReader = new InputStreamReader(new GZIPInputStream(oldContent.getBinaryStream()));
    		
    		StringWriter newSchemeWriter = new StringWriter();
    		XMLStreamWriter newSchemeXMLWriter = xmlFactory.createXMLStreamWriter(newSchemeWriter);
    		
    		ByteArrayOutputStream newDataOutput = new ByteArrayOutputStream();
    		GZIPOutputStream newZippedDataOutput = new GZIPOutputStream(newDataOutput);
    		XMLStreamWriter newDataXMLWriter = xmlFactory.createXMLStreamWriter(newZippedDataOutput, "utf-8");
    		
    		xmlParser.parse(new InputSource(oldContentReader), new DefaultHandler() {
    			// Usage of schemeXMLWriter and dataXMLWriter to write XML into String and byte[]
    		});
    		
    		String newScheme = newSchemeWriter.toString();
    		byte[] newData = newDataOutput.toByteArray();
    		
    		StringReader newSchemeReader = new StringReader(newScheme);
    		ByteArrayInputStream newDataInput = new ByteArrayInputStream(newData);
    		
    		insertNewContent.setLong(1, id);
    		insertNewContent.setCharacterStream(2, newSchemeReader, newScheme.length());
    		insertNewContent.setBlob(3, newDataInput, newData.length);
    		
    		insertNewContent.executeUpdate();
    	}
    }
}

, - migrate(). .

- , . , . , , . :

public class MigratorV2  {
	
	private Connection conn; // Injected
	private SAXParser xmlParser; // Injected
	private XMLOutputFactory xmlFactory; // Injected
	
    public void migrate() throws Exception {
    	try (
			PreparedStatement selectOldContent = conn.prepareStatement("select content from old_data where id = ?");
	    	PreparedStatement insertNewContent = conn.prepareStatement("insert into new_data (id, scheme, data) values (?, ?, ?)");
	    	
	    	ResultSet oldIdResult = conn.createStatement().executeQuery("select id from old_data");
    	){
    		while (oldIdResult.next()) {
        		long id = oldIdResult.getLong(1);
        		
        		selectOldContent.setLong(1, id);
        		
        		try (ResultSet oldContentResult = selectOldContent.executeQuery()) {
        			oldContentResult.next();
                	
        			String newScheme;
        			byte[] newData;
        			
        			Blob oldContent = null;
        			try {
        				oldContent = oldContentResult.getBlob(1);
        				
        				try (
        					Reader oldContentReader = new InputStreamReader(new GZIPInputStream(oldContent.getBinaryStream()));
        					
        					StringWriter newSchemeWriter = new StringWriter();
        					
    						ByteArrayOutputStream newDataOutput = new ByteArrayOutputStream();
                    		GZIPOutputStream newZippedDataOutput = new GZIPOutputStream(newDataOutput);
        				){
        					XMLStreamWriter newSchemeXMLWriter = null;
        					XMLStreamWriter newDataXMLWriter = null;
        					try {
        						newSchemeXMLWriter = xmlFactory.createXMLStreamWriter(newSchemeWriter);
                        		newDataXMLWriter = xmlFactory.createXMLStreamWriter(newZippedDataOutput, "utf-8");
                        		
                        		xmlParser.parse(new InputSource(oldContentReader), new DefaultHandler() {
                        			// Usage of schemeXMLWriter and dataXMLWriter to write XML into String and byte[]
                        		});
        					} finally {
        						if (newSchemeXMLWriter != null) {
                					try {
                						newSchemeXMLWriter.close();
                					} catch (XMLStreamException e) {}
                				}
        						if (newDataXMLWriter != null) {
                					try {
                						newDataXMLWriter.close();
                					} catch (XMLStreamException e) {}
                				}
        					}
        					
        					newScheme = newSchemeWriter.toString();
                    		newData = newDataOutput.toByteArray();
        				}
        			} finally {
        				if (oldContent != null) {
        					try {
        						oldContent.free();
        					} catch (SQLException e) {}
        				}
        			}
        			
        			try (
        				StringReader newSchemeReader = new StringReader(newScheme);
                		ByteArrayInputStream newDataInput = new ByteArrayInputStream(newData);
            		){
            			insertNewContent.setLong(1, id);
                		insertNewContent.setCharacterStream(2, newSchemeReader, newScheme.length());
                		insertNewContent.setBlob(3, newDataInput, newData.length);
                		
                		insertNewContent.executeUpdate();
            		}
        		}
        	}
    	}
    }
}

! . ? , , , , - . , , :

public class MigratorV3  {
	
	private Connection conn; // Injected
	private SAXParser xmlParser; // Injected
	private XMLOutputFactory xmlFactory; // Injected
	
	@RequiredArgsConstructor
	private static class NewData {
		final String scheme;
		final byte[] data;
	}
	
	private List loadIds() throws Exception {
		List ids = new ArrayList<>();
		
		try (ResultSet oldIdResult = conn.createStatement().executeQuery("select id from old_data")) {
			while (oldIdResult.next()) {
				ids.add(oldIdResult.getLong(1));
			}
		}
		
		return ids;
	}
	
	private Blob loadOldContent(PreparedStatement selectOldContent, long id) throws Exception {
		selectOldContent.setLong(1, id);
		
		try (ResultSet oldContentResult = selectOldContent.executeQuery()) {
			oldContentResult.next();
			
			return oldContentResult.getBlob(1);
		}
	}
	
	private void oldContentToNewData(Reader oldContentReader, StringWriter newSchemeWriter, GZIPOutputStream newZippedDataOutput) throws Exception {
		XMLStreamWriter newSchemeXMLWriter = null;
		XMLStreamWriter newDataXMLWriter = null;
		try {
			newSchemeXMLWriter = xmlFactory.createXMLStreamWriter(newSchemeWriter);
    		newDataXMLWriter = xmlFactory.createXMLStreamWriter(newZippedDataOutput, "utf-8");
    		
    		xmlParser.parse(new InputSource(oldContentReader), new DefaultHandler() {
    			// Usage of schemeXMLWriter and dataXMLWriter to write XML into String and byte[]
    		});
		} finally {
			if (newSchemeXMLWriter != null) {
				try {
					newSchemeXMLWriter.close();
				} catch (XMLStreamException e) {}
			}
			if (newDataXMLWriter != null) {
				try {
					newDataXMLWriter.close();
				} catch (XMLStreamException e) {}
			}
		}
	}
	
	private NewData generateNewDataFromOldContent(PreparedStatement selectOldContent, long id) throws Exception {
		Blob oldContent = null;
		try {
			oldContent = loadOldContent(selectOldContent, id);
			
			try (
				Reader oldContentReader = new InputStreamReader(new GZIPInputStream(oldContent.getBinaryStream()));
				
				StringWriter newSchemeWriter = new StringWriter();
				
				ByteArrayOutputStream newDataOutput = new ByteArrayOutputStream();
        		GZIPOutputStream newZippedDataOutput = new GZIPOutputStream(newDataOutput);
			){
				oldContentToNewData(oldContentReader, newSchemeWriter, newZippedDataOutput);
				
				return new NewData(newSchemeWriter.toString(), newDataOutput.toByteArray());
			}
		} finally {
			if (oldContent != null) {
				try {
					oldContent.free();
				} catch (SQLException e) {}
			}
		}
	}
	
	private void storeNewData(PreparedStatement insertNewContent, long id, String newScheme, byte[] newData) throws Exception {
		try (
			StringReader newSchemeReader = new StringReader(newScheme);
    		ByteArrayInputStream newDataInput = new ByteArrayInputStream(newData);
		){
			insertNewContent.setLong(1, id);
    		insertNewContent.setCharacterStream(2, newSchemeReader, newScheme.length());
    		insertNewContent.setBlob(3, newDataInput, newData.length);
    		
    		insertNewContent.executeUpdate();
		}
	}
	
    public void migrate() throws Exception {
    	List ids = loadIds();
    	
    	try (
			PreparedStatement selectOldContent = conn.prepareStatement("select content from old_data where id = ?");
	    	PreparedStatement insertNewContent = conn.prepareStatement("insert into new_data (id, scheme, data) values (?, ?, ?)");
    	){
    		for (Long id : ids) {
    			NewData newData = generateNewDataFromOldContent(selectOldContent, id);
    			storeNewData(insertNewContent, id, newData.scheme, newData.data);
    		}
    	}
    }
}

, , migrate(). , , SAX , , , .

. . XMLStreamWriter Blob Autoloseable, :

public class MigratorV4  {
	
	private Connection conn; // Injected
	private SAXParser xmlParser; // Injected
	private XMLOutputFactory xmlFactory; // Injected
	
	@RequiredArgsConstructor
	private static class NewData {
		final String scheme;
		final byte[] data;
	}
	
	@RequiredArgsConstructor
	private static class SmartXMLStreamWriter implements AutoCloseable {
		final XMLStreamWriter writer;

		@Override
		public void close() throws Exception {
			writer.close();
		}
	}
	
	@RequiredArgsConstructor
	private static class SmartBlob implements AutoCloseable {
		final Blob blob;

		@Override
		public void close() throws Exception {
			blob.free();
		}
	}
	
	private List loadIds() throws Exception {
		List ids = new ArrayList<>();
		
		try (ResultSet oldIdResult = conn.createStatement().executeQuery("select id from old_data")) {
			while (oldIdResult.next()) {
				ids.add(oldIdResult.getLong(1));
			}
		}
		
		return ids;
	}
	
	private Blob loadOldContent(PreparedStatement selectOldContent, long id) throws Exception {
		selectOldContent.setLong(1, id);
		
		try (ResultSet oldContentResult = selectOldContent.executeQuery()) {
			oldContentResult.next();
			
			return oldContentResult.getBlob(1);
		}
	}
	
	private void oldContentToNewData(Reader oldContentReader, StringWriter newSchemeWriter, GZIPOutputStream newZippedDataOutput) throws Exception {
		try (
			SmartXMLStreamWriter newSchemeXMLWriter = new SmartXMLStreamWriter(xmlFactory.createXMLStreamWriter(newSchemeWriter));
			SmartXMLStreamWriter newDataXMLWriter = new SmartXMLStreamWriter(xmlFactory.createXMLStreamWriter(newZippedDataOutput, "utf-8"));
		){
			xmlParser.parse(new InputSource(oldContentReader), new DefaultHandler() {
				// Usage of schemeXMLWriter and dataXMLWriter to write XML into String and byte[]
			});
		}
	}
	
	private NewData generateNewDataFromOldContent(PreparedStatement selectOldContent, long id) throws Exception {
		try (
			SmartBlob oldContent = new SmartBlob(loadOldContent(selectOldContent, id));
			
			Reader oldContentReader = new InputStreamReader(new GZIPInputStream(oldContent.blob.getBinaryStream()));
				
			StringWriter newSchemeWriter = new StringWriter();
			
			ByteArrayOutputStream newDataOutput = new ByteArrayOutputStream();
    		GZIPOutputStream newZippedDataOutput = new GZIPOutputStream(newDataOutput);
		){
			oldContentToNewData(oldContentReader, newSchemeWriter, newZippedDataOutput);
			return new NewData(newSchemeWriter.toString(), newDataOutput.toByteArray());
		}
	}
	
	private void storeNewData(PreparedStatement insertNewContent, long id, String newScheme, byte[] newData) throws Exception {
		try (
			StringReader newSchemeReader = new StringReader(newScheme);
    		ByteArrayInputStream newDataInput = new ByteArrayInputStream(newData);
		){
			insertNewContent.setLong(1, id);
    		insertNewContent.setCharacterStream(2, newSchemeReader, newScheme.length());
    		insertNewContent.setBlob(3, newDataInput, newData.length);
    		
    		insertNewContent.executeUpdate();
		}
	}
	
    public void migrate() throws Exception {
    	List ids = loadIds();
    	
    	try (
			PreparedStatement selectOldContent = conn.prepareStatement("select content from old_data where id = ?");
	    	PreparedStatement insertNewContent = conn.prepareStatement("insert into new_data (id, scheme, data) values (?, ?, ?)");
    	){
    		for (Long id : ids) {    			
    			NewData newData = generateNewDataFromOldContent(selectOldContent, id);
    			storeNewData(insertNewContent, id, newData.scheme, newData.data);
    		}
    	}
    }
}

SmartXMLStreamWriter SmartBlob, XMLStreamWriter Blob try-with-resources.

, AutoCloseable, ? . , Java 8:

public class MigratorV5  {
	
	private Connection conn; // Injected
	private SAXParser xmlParser; // Injected
	private XMLOutputFactory xmlFactory; // Injected
	
	@RequiredArgsConstructor
	private static class NewData {
		final String scheme;
		final byte[] data;
	}
	
	private List loadIds() throws Exception {
		List ids = new ArrayList<>();
		
		try (ResultSet oldIdResult = conn.createStatement().executeQuery("select id from old_data")) {
			while (oldIdResult.next()) {
				ids.add(oldIdResult.getLong(1));
			}
		}
		
		return ids;
	}
	
	private Blob loadOldContent(PreparedStatement selectOldContent, long id) throws Exception {
		selectOldContent.setLong(1, id);
		
		try (ResultSet oldContentResult = selectOldContent.executeQuery()) {
			oldContentResult.next();
			
			return oldContentResult.getBlob(1);
		}
	}
	
	private void oldContentToNewData(Reader oldContentReader, StringWriter newSchemeWriter, GZIPOutputStream newZippedDataOutput) throws Exception {
		XMLStreamWriter newSchemeXMLWriter;
		XMLStreamWriter newDataXMLWriter;
		try (
			AutoCloseable fake1 = (newSchemeXMLWriter = xmlFactory.createXMLStreamWriter(newSchemeWriter))::close;
			AutoCloseable fake2 = (newDataXMLWriter = xmlFactory.createXMLStreamWriter(newZippedDataOutput, "utf-8"))::close;
		){
			xmlParser.parse(new InputSource(oldContentReader), new DefaultHandler() {
				// Usage of schemeXMLWriter and dataXMLWriter to write XML into String and byte[]
			});
		}
	}
	
	private NewData generateNewDataFromOldContent(PreparedStatement selectOldContent, long id) throws Exception {
		Blob oldContent;
		try (
			AutoCloseable fake = (oldContent = loadOldContent(selectOldContent, id))::free;
			
			Reader oldContentReader = new InputStreamReader(new GZIPInputStream(oldContent.getBinaryStream()));
				
			StringWriter newSchemeWriter = new StringWriter();
			
			ByteArrayOutputStream newDataOutput = new ByteArrayOutputStream();
    		GZIPOutputStream newZippedDataOutput = new GZIPOutputStream(newDataOutput);
		){
			oldContentToNewData(oldContentReader, newSchemeWriter, newZippedDataOutput);
			return new NewData(newSchemeWriter.toString(), newDataOutput.toByteArray());
		}
	}
	
	private void storeNewData(PreparedStatement insertNewContent, long id, String newScheme, byte[] newData) throws Exception {
		try (
			StringReader newSchemeReader = new StringReader(newScheme);
    		ByteArrayInputStream newDataInput = new ByteArrayInputStream(newData);
		){
			insertNewContent.setLong(1, id);
    		insertNewContent.setCharacterStream(2, newSchemeReader, newScheme.length());
    		insertNewContent.setBlob(3, newDataInput, newData.length);
    		
    		insertNewContent.executeUpdate();
		}
	}
	
    public void migrate() throws Exception {
    	List ids = loadIds();
    	
    	try (
			PreparedStatement selectOldContent = conn.prepareStatement("select content from old_data where id = ?");
	    	PreparedStatement insertNewContent = conn.prepareStatement("insert into new_data (id, scheme, data) values (?, ?, ?)");
    	){
    		for (Long id : ids) {    			
    			NewData newData = generateNewDataFromOldContent(selectOldContent, id);
    			storeNewData(insertNewContent, id, newData.scheme, newData.data);
    		}
    	}
    }
}

--, , : . . , .

, : @RequiredArgsConstructor. ! Lombok @Cleanup, , Java . - try-finally . , , close(), free() - , ( , ).

@Cleanup:

public class MigratorV6  {
	
	private Connection conn; // Injected
	private SAXParser xmlParser; // Injected
	private XMLOutputFactory xmlFactory; // Injected
	
	@RequiredArgsConstructor
	private static class NewData {
		final String scheme;
		final byte[] data;
	}
	
	private List loadIds() throws Exception {
		List ids = new ArrayList<>();
		
		try (ResultSet oldIdResult = conn.createStatement().executeQuery("select id from old_data")) {
			while (oldIdResult.next()) {
				ids.add(oldIdResult.getLong(1));
			}
		}
		
		return ids;
	}
	
	private Blob loadOldContent(PreparedStatement selectOldContent, long id) throws Exception {
		selectOldContent.setLong(1, id);
		
		try (ResultSet oldContentResult = selectOldContent.executeQuery()) {
			oldContentResult.next();
			
			return oldContentResult.getBlob(1);
		}
	}
	
	private void oldContentToNewData(Reader oldContentReader, StringWriter newSchemeWriter, GZIPOutputStream newZippedDataOutput) throws Exception {
		@Cleanup XMLStreamWriter newSchemeXMLWriter = xmlFactory.createXMLStreamWriter(newSchemeWriter);
		@Cleanup XMLStreamWriter newDataXMLWriter = xmlFactory.createXMLStreamWriter(newZippedDataOutput, "utf-8");
		
		xmlParser.parse(new InputSource(oldContentReader), new DefaultHandler() {
			// Usage of schemeXMLWriter and dataXMLWriter to write XML into String and byte[]
		});
	}
	
	private NewData generateNewDataFromOldContent(PreparedStatement selectOldContent, long id) throws Exception {
		@Cleanup("free") Blob oldContent = loadOldContent(selectOldContent, id);
		
		try (
			Reader oldContentReader = new InputStreamReader(new GZIPInputStream(oldContent.getBinaryStream()));
				
			StringWriter newSchemeWriter = new StringWriter();
			
			ByteArrayOutputStream newDataOutput = new ByteArrayOutputStream();
    		GZIPOutputStream newZippedDataOutput = new GZIPOutputStream(newDataOutput);
		){
			oldContentToNewData(oldContentReader, newSchemeWriter, newZippedDataOutput);
			return new NewData(newSchemeWriter.toString(), newDataOutput.toByteArray());
		}
	}
	
	private void storeNewData(PreparedStatement insertNewContent, long id, String newScheme, byte[] newData) throws Exception {
		try (
			StringReader newSchemeReader = new StringReader(newScheme);
    		ByteArrayInputStream newDataInput = new ByteArrayInputStream(newData);
		){
			insertNewContent.setLong(1, id);
    		insertNewContent.setCharacterStream(2, newSchemeReader, newScheme.length());
    		insertNewContent.setBlob(3, newDataInput, newData.length);
    		
    		insertNewContent.executeUpdate();
		}
	}
	
    public void migrate() throws Exception {
    	List ids = loadIds();
    	
    	try (
			PreparedStatement selectOldContent = conn.prepareStatement("select content from old_data where id = ?");
	    	PreparedStatement insertNewContent = conn.prepareStatement("insert into new_data (id, scheme, data) values (?, ?, ?)");
    	){
    		for (Long id : ids) {    			
    			NewData newData = generateNewDataFromOldContent(selectOldContent, id);
    			storeNewData(insertNewContent, id, newData.scheme, newData.data);
    		}
    	}
    }
}

, , , .

. . , @Cleanup. , AutoCloseable , . ? ! ? . , . :

public class MigratorV7  {
	
	private Connection conn; // Injected
	private SAXParser xmlParser; // Injected
	private XMLOutputFactory xmlFactory; // Injected
	
    public void migrate() throws Exception {
    	@Cleanup PreparedStatement selectOldContent = conn.prepareStatement("select content from old_data where id = ?");
    	@Cleanup PreparedStatement insertNewContent = conn.prepareStatement("insert into new_data (id, scheme, data) values (?, ?, ?)");
    	
    	@Cleanup ResultSet oldIdResult = conn.createStatement().executeQuery("select id from old_data");
    	
    	while (oldIdResult.next()) {
    		long id = oldIdResult.getLong(1);
    		
    		selectOldContent.setLong(1, id);
    		
    		@Cleanup ResultSet oldContentResult = selectOldContent.executeQuery();
        	oldContentResult.next();
        	
        	@Cleanup("free") Blob oldContent = oldContentResult.getBlob(1);
        	@Cleanup Reader oldContentReader = new InputStreamReader(new GZIPInputStream(oldContent.getBinaryStream()));
    		
        	@Cleanup StringWriter newSchemeWriter = new StringWriter();
        	@Cleanup XMLStreamWriter newSchemeXMLWriter = xmlFactory.createXMLStreamWriter(newSchemeWriter);
    		
        	ByteArrayOutputStream newDataOutput = new ByteArrayOutputStream();
        	@Cleanup GZIPOutputStream newZippedDataOutput = new GZIPOutputStream(newDataOutput);
        	@Cleanup XMLStreamWriter newDataXMLWriter = xmlFactory.createXMLStreamWriter(newZippedDataOutput, "utf-8");
    		
    		xmlParser.parse(new InputSource(oldContentReader), new DefaultHandler() {
    			// Usage of schemeXMLWriter and dataXMLWriter to write XML into String and byte[]
    		});
    		
    		String newScheme = newSchemeWriter.toString();
    		byte[] newData = newDataOutput.toByteArray();
    		
    		@Cleanup StringReader newSchemeReader = new StringReader(newScheme);
    		@Cleanup ByteArrayInputStream newDataInput = new ByteArrayInputStream(newData);
    		
    		insertNewContent.setLong(1, id);
    		insertNewContent.setCharacterStream(2, newSchemeReader, newScheme.length());
    		insertNewContent.setBlob(3, newDataInput, newData.length);
    		
    		insertNewContent.executeUpdate();
    	}
    }
}

-. . , , , . , , , , .

. . . MigratorV5 , Java 8.

.

, , , , - -, , . , ( -). . @Cleanup , , try-with-resources, , . , , ?
Original source: habrahabr.ru (comments, light).

https://habrahabr.ru/post/339046/

:  

: [1] []
 

:
: 

: ( )

:

  URL