diff --git a/docs/spring/csb9ea5b7a-df47-11ee-91f8-acde48001122.java b/docs/spring/csb9ea5b7a-df47-11ee-91f8-acde48001122.java new file mode 100644 index 00000000..fc708572 --- /dev/null +++ b/docs/spring/csb9ea5b7a-df47-11ee-91f8-acde48001122.java @@ -0,0 +1,58 @@ +package com.huifer.kafka.application.ttl; + +/** + *

Title : BytesUtils

+ *

Description :

+ * + * @author huifer + * @date 2019-06-27 + */ +public class BytesUtils { + + public static void main(String[] args) { + long i = 22L; + byte[] bytes = long2byte(i); + long l = byte2long(bytes); + System.out.println(l); + + int ii = 10; + byte[] bytes1 = int2byte(ii); + int i1 = byte2int(bytes1); + System.out.println(i1); + } + + public static byte[] long2byte(Long ms) { + byte[] buffer = new byte[8]; + for (int i = 0; i < 8; i++) { + int offset = 64 - (i + 1) * 8; + buffer[i] = (byte) ((ms >> offset) & 0xff); + } + return buffer; + } + + public static long byte2long(byte[] bytes) { + long value = 0; + for (int i = 0; i < 8; i++) { + value <<= 8; + value |= (bytes[i] & 0xff); + } + return value; + } + + public static int byte2int(byte[] bytes) { + return (bytes[0] & 0xff) << 24 + | (bytes[1] & 0xff) << 16 + | (bytes[2] & 0xff) << 8 + | (bytes[3] & 0xff); + } + + public static byte[] int2byte(int num) { + byte[] bytes = new byte[4]; + bytes[0] = (byte) ((num >> 24) & 0xff); + bytes[1] = (byte) ((num >> 16) & 0xff); + bytes[2] = (byte) ((num >> 8) & 0xff); + bytes[3] = (byte) (num & 0xff); + return bytes; + } + +} diff --git a/docs/spring/csba39874a-df47-11ee-91f8-acde48001122.java b/docs/spring/csba39874a-df47-11ee-91f8-acde48001122.java new file mode 100644 index 00000000..e756d708 --- /dev/null +++ b/docs/spring/csba39874a-df47-11ee-91f8-acde48001122.java @@ -0,0 +1,70 @@ +package com.huifer.idgen.my.service.conv; + +import com.huifer.idgen.my.service.bean.Id; +import com.huifer.idgen.my.service.bean.IdMeta; +import com.huifer.idgen.my.service.bean.enums.IdType; +import com.huifer.idgen.my.service.factory.IdMetaFactory; + +/** + * @author: wang + * @description: + */ +public class IdConverterImpl implements IdConverter { + + private IdMeta idMeta; + + public IdConverterImpl(IdType idType) { + this(IdMetaFactory.getIdMeta(idType)); + } + + public IdConverterImpl(IdMeta idMeta) { + this.idMeta = idMeta; + } + + + @Override + public long converter(Id id) { + return doConverter(id, this.idMeta); + } + + @Override + public Id converter(long id) { + return doConvert(id, idMeta); + } + + /** + * 根据id生产,根据id元数据生产一个long类型的id + * + * @param id + * @param idMeta + * @return + */ + protected long doConverter(Id id, IdMeta idMeta) { + long res = 0; + res |= id.getMachine(); + res |= id.getSeq() << idMeta.getMachineBits(); + res |= id.getTime() << idMeta.getTimeBitsStartPos(); + res |= id.getGenMethod() << idMeta.getGenMethodBitsStartPos(); + res |= id.getType() << idMeta.getTypeBitsStartPos(); + res |= id.getVersion() << idMeta.getVersionBitsStartPos(); + return res; + } + + /** + * 根据long类型id,根据id元数据返回这个id的意义 + * + * @param id + * @param idMeta + * @return + */ + protected Id doConvert(long id, IdMeta idMeta) { + Id res = new Id(); + res.setMachine(id & idMeta.getMachineBitsMask()); + res.setSeq((id >>> idMeta.getMachineBits()) & idMeta.getSeqBitsMask()); + res.setTime((id >>> idMeta.getTimeBitsStartPos()) & idMeta.getTimeBitsMask()); + res.setGenMethod((id >>> idMeta.getGenMethodBitsStartPos()) & idMeta.getGenMethodBitsMask()); + res.setType((id >>> idMeta.getTypeBitsStartPos()) & idMeta.getTypeBitsMask()); + res.setVersion((id >>> idMeta.getVersionBitsStartPos()) & idMeta.getVersionBitsMask()); + return res; + } +} \ No newline at end of file diff --git a/docs/spring/csba92396c-df47-11ee-91f8-acde48001122.java b/docs/spring/csba92396c-df47-11ee-91f8-acde48001122.java new file mode 100644 index 00000000..c8a49070 --- /dev/null +++ b/docs/spring/csba92396c-df47-11ee-91f8-acde48001122.java @@ -0,0 +1,339 @@ +/** + * Copyright 2009-2019 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ibatis.io; + +import org.apache.ibatis.logging.Log; +import org.apache.ibatis.logging.LogFactory; + +import java.io.*; +import java.net.MalformedURLException; +import java.net.URL; +import java.net.URLEncoder; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.jar.JarEntry; +import java.util.jar.JarInputStream; + +/** + * A default implementation of {@link VFS} that works for most application servers. + * + * @author Ben Gunter + */ +public class DefaultVFS extends VFS { + private static final Log log = LogFactory.getLog(DefaultVFS.class); + + /** The magic header that indicates a JAR (ZIP) file. */ + private static final byte[] JAR_MAGIC = {'P', 'K', 3, 4}; + + @Override + public boolean isValid() { + return true; + } + + @Override + public List list(URL url, String path) throws IOException { + InputStream is = null; + try { + List resources = new ArrayList<>(); + + // First, try to find the URL of a JAR file containing the requested resource. If a JAR + // file is found, then we'll list child resources by reading the JAR. + URL jarUrl = findJarForResource(url); + if (jarUrl != null) { + is = jarUrl.openStream(); + if (log.isDebugEnabled()) { + log.debug("Listing " + url); + } + resources = listResources(new JarInputStream(is), path); + } else { + List children = new ArrayList<>(); + try { + if (isJar(url)) { + // Some versions of JBoss VFS might give a JAR stream even if the resource + // referenced by the URL isn't actually a JAR + is = url.openStream(); + try (JarInputStream jarInput = new JarInputStream(is)) { + if (log.isDebugEnabled()) { + log.debug("Listing " + url); + } + for (JarEntry entry; (entry = jarInput.getNextJarEntry()) != null; ) { + if (log.isDebugEnabled()) { + log.debug("Jar entry: " + entry.getName()); + } + children.add(entry.getName()); + } + } + } else { + /* + * Some servlet containers allow reading from directory resources like a + * text file, listing the child resources one per line. However, there is no + * way to differentiate between directory and file resources just by reading + * them. To work around that, as each line is read, try to look it up via + * the class loader as a child of the current resource. If any line fails + * then we assume the current resource is not a directory. + */ + is = url.openStream(); + List lines = new ArrayList<>(); + try (BufferedReader reader = new BufferedReader(new InputStreamReader(is))) { + for (String line; (line = reader.readLine()) != null; ) { + if (log.isDebugEnabled()) { + log.debug("Reader entry: " + line); + } + lines.add(line); + if (getResources(path + "/" + line).isEmpty()) { + lines.clear(); + break; + } + } + } + if (!lines.isEmpty()) { + if (log.isDebugEnabled()) { + log.debug("Listing " + url); + } + children.addAll(lines); + } + } + } catch (FileNotFoundException e) { + /* + * For file URLs the openStream() call might fail, depending on the servlet + * container, because directories can't be opened for reading. If that happens, + * then list the directory directly instead. + */ + if ("file".equals(url.getProtocol())) { + File file = new File(url.getFile()); + if (log.isDebugEnabled()) { + log.debug("Listing directory " + file.getAbsolutePath()); + } + if (file.isDirectory()) { + if (log.isDebugEnabled()) { + log.debug("Listing " + url); + } + children = Arrays.asList(file.list()); + } + } else { + // No idea where the exception came from so rethrow it + throw e; + } + } + + // The URL prefix to use when recursively listing child resources + String prefix = url.toExternalForm(); + if (!prefix.endsWith("/")) { + prefix = prefix + "/"; + } + + // Iterate over immediate children, adding files and recursing into directories + for (String child : children) { + String resourcePath = path + "/" + child; + resources.add(resourcePath); + URL childUrl = new URL(prefix + child); + resources.addAll(list(childUrl, resourcePath)); + } + } + + return resources; + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + // Ignore + } + } + } + } + + /** + * List the names of the entries in the given {@link JarInputStream} that begin with the + * specified {@code path}. Entries will match with or without a leading slash. + * + * @param jar The JAR input stream + * @param path The leading path to match + * @return The names of all the matching entries + * @throws IOException If I/O errors occur + */ + protected List listResources(JarInputStream jar, String path) throws IOException { + // Include the leading and trailing slash when matching names + if (!path.startsWith("/")) { + path = "/" + path; + } + if (!path.endsWith("/")) { + path = path + "/"; + } + + // Iterate over the entries and collect those that begin with the requested path + List resources = new ArrayList<>(); + for (JarEntry entry; (entry = jar.getNextJarEntry()) != null; ) { + if (!entry.isDirectory()) { + // Add leading slash if it's missing + StringBuilder name = new StringBuilder(entry.getName()); + if (name.charAt(0) != '/') { + name.insert(0, '/'); + } + + // Check file name + if (name.indexOf(path) == 0) { + if (log.isDebugEnabled()) { + log.debug("Found resource: " + name); + } + // Trim leading slash + resources.add(name.substring(1)); + } + } + } + return resources; + } + + /** + * Attempts to deconstruct the given URL to find a JAR file containing the resource referenced + * by the URL. That is, assuming the URL references a JAR entry, this method will return a URL + * that references the JAR file containing the entry. If the JAR cannot be located, then this + * method returns null. + * + * @param url The URL of the JAR entry. + * @return The URL of the JAR file, if one is found. Null if not. + * @throws MalformedURLException + */ + protected URL findJarForResource(URL url) throws MalformedURLException { + if (log.isDebugEnabled()) { + log.debug("Find JAR URL: " + url); + } + + // If the file part of the URL is itself a URL, then that URL probably points to the JAR + boolean continueLoop = true; + while (continueLoop) { + try { + url = new URL(url.getFile()); + if (log.isDebugEnabled()) { + log.debug("Inner URL: " + url); + } + } catch (MalformedURLException e) { + // This will happen at some point and serves as a break in the loop + continueLoop = false; + } + } + + // Look for the .jar extension and chop off everything after that + StringBuilder jarUrl = new StringBuilder(url.toExternalForm()); + int index = jarUrl.lastIndexOf(".jar"); + if (index >= 0) { + jarUrl.setLength(index + 4); + if (log.isDebugEnabled()) { + log.debug("Extracted JAR URL: " + jarUrl); + } + } else { + if (log.isDebugEnabled()) { + log.debug("Not a JAR: " + jarUrl); + } + return null; + } + + // Try to open and test it + try { + URL testUrl = new URL(jarUrl.toString()); + if (isJar(testUrl)) { + return testUrl; + } else { + // WebLogic fix: check if the URL's file exists in the filesystem. + if (log.isDebugEnabled()) { + log.debug("Not a JAR: " + jarUrl); + } + jarUrl.replace(0, jarUrl.length(), testUrl.getFile()); + File file = new File(jarUrl.toString()); + + // File name might be URL-encoded + if (!file.exists()) { + try { + file = new File(URLEncoder.encode(jarUrl.toString(), "UTF-8")); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException("Unsupported encoding? UTF-8? That's unpossible."); + } + } + + if (file.exists()) { + if (log.isDebugEnabled()) { + log.debug("Trying real file: " + file.getAbsolutePath()); + } + testUrl = file.toURI().toURL(); + if (isJar(testUrl)) { + return testUrl; + } + } + } + } catch (MalformedURLException e) { + log.warn("Invalid JAR URL: " + jarUrl); + } + + if (log.isDebugEnabled()) { + log.debug("Not a JAR: " + jarUrl); + } + return null; + } + + /** + * Converts a Java package name to a path that can be looked up with a call to + * {@link ClassLoader#getResources(String)}. + * + * @param packageName The Java package name to convert to a path + */ + protected String getPackagePath(String packageName) { + return packageName == null ? null : packageName.replace('.', '/'); + } + + /** + * Returns true if the resource located at the given URL is a JAR file. + * + * @param url The URL of the resource to test. + */ + protected boolean isJar(URL url) { + return isJar(url, new byte[JAR_MAGIC.length]); + } + + /** + * Returns true if the resource located at the given URL is a JAR file. + * + * @param url The URL of the resource to test. + * @param buffer A buffer into which the first few bytes of the resource are read. The buffer + * must be at least the size of {@link #JAR_MAGIC}. (The same buffer may be reused + * for multiple calls as an optimization.) + */ + protected boolean isJar(URL url, byte[] buffer) { + InputStream is = null; + try { + is = url.openStream(); + is.read(buffer, 0, JAR_MAGIC.length); + if (Arrays.equals(buffer, JAR_MAGIC)) { + if (log.isDebugEnabled()) { + log.debug("Found JAR: " + url); + } + return true; + } + } catch (Exception e) { + // Failure to read the stream means this is not a JAR + } finally { + if (is != null) { + try { + is.close(); + } catch (Exception e) { + // Ignore + } + } + } + + return false; + } +} diff --git a/docs/spring/csbae58112-df47-11ee-91f8-acde48001122.java b/docs/spring/csbae58112-df47-11ee-91f8-acde48001122.java new file mode 100644 index 00000000..4250757a --- /dev/null +++ b/docs/spring/csbae58112-df47-11ee-91f8-acde48001122.java @@ -0,0 +1,69 @@ +package com.huifer.idgen.my.service.util; + +import lombok.extern.slf4j.Slf4j; + +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; + +/** + * @author: wang + * @description: ip获取工具 + */ +@Slf4j +public class IpUtils { + + private IpUtils() { + throw new IllegalStateException("Utility class"); + } + + public static String getHostIp() { + String ip = null; + try { + + Enumeration networkInterfaces = NetworkInterface.getNetworkInterfaces(); + while (networkInterfaces.hasMoreElements()) { + NetworkInterface networkInterface = networkInterfaces.nextElement(); + Enumeration inetAddresses = networkInterface.getInetAddresses(); + while (inetAddresses.hasMoreElements()) { + InetAddress inetAddress = inetAddresses.nextElement(); + if (!inetAddress.isLoopbackAddress() + && !inetAddress.isLinkLocalAddress() + && inetAddress.isSiteLocalAddress() + ) { + ip = inetAddress.getHostAddress(); + } + } + } + } catch (SocketException e) { + log.error("ip 获取异常{}", e); + } + return ip; + } + + public static String getHostName() { + String hostName = null; + try { + Enumeration en = NetworkInterface + .getNetworkInterfaces(); + while (en.hasMoreElements()) { + NetworkInterface intf = en.nextElement(); + Enumeration enumIpAddr = intf.getInetAddresses(); + while (enumIpAddr.hasMoreElements()) { + InetAddress inetAddress = enumIpAddr + .nextElement(); + if (!inetAddress.isLoopbackAddress() + && !inetAddress.isLinkLocalAddress() + && inetAddress.isSiteLocalAddress()) { + hostName = inetAddress.getHostName(); + } + } + } + } catch (SocketException e) { + log.error("host 获取异常{}", e); + } + return hostName; + } + +} \ No newline at end of file diff --git a/docs/spring/csbb3f8b80-df47-11ee-91f8-acde48001122.java b/docs/spring/csbb3f8b80-df47-11ee-91f8-acde48001122.java new file mode 100644 index 00000000..2f14f3a2 --- /dev/null +++ b/docs/spring/csbb3f8b80-df47-11ee-91f8-acde48001122.java @@ -0,0 +1,20 @@ +package com.huifer.jdk.jdk8.stearm; + +import java.util.ArrayList; +import java.util.HashSet; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +/** + * 描述: + * + * @author huifer + * @date 2019-06-16 + */ +public class Demo03 { + public static void main(String[] args) { + Stream stringStream = Stream.of("a", "b", "c"); + ArrayList collect = stringStream.collect(Collectors.toCollection(ArrayList::new)); + HashSet collect1 = stringStream.collect(Collectors.toCollection(HashSet::new)); + } +} diff --git a/docs/spring/csbba72718-df47-11ee-91f8-acde48001122.java b/docs/spring/csbba72718-df47-11ee-91f8-acde48001122.java new file mode 100644 index 00000000..e878c034 --- /dev/null +++ b/docs/spring/csbba72718-df47-11ee-91f8-acde48001122.java @@ -0,0 +1,22 @@ +/** + * Copyright 2009-2015 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ibatis.submitted.xml_external_ref; + +public interface MultipleReverseIncludePersonMapper { + Person select(Integer id); + + Pet selectPet(Integer id); +} diff --git a/docs/spring/csbbf8681c-df47-11ee-91f8-acde48001122.java b/docs/spring/csbbf8681c-df47-11ee-91f8-acde48001122.java new file mode 100644 index 00000000..5d200bde --- /dev/null +++ b/docs/spring/csbbf8681c-df47-11ee-91f8-acde48001122.java @@ -0,0 +1,108 @@ +/** + * Copyright 2009-2019 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ibatis.submitted.multipleresultsetswithassociation; + +import org.apache.ibatis.io.Resources; +import org.apache.ibatis.jdbc.ScriptRunner; +import org.apache.ibatis.session.SqlSession; +import org.apache.ibatis.session.SqlSessionFactory; +import org.apache.ibatis.session.SqlSessionFactoryBuilder; +import org.junit.jupiter.api.Assertions; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +import java.io.Reader; +import java.sql.Connection; +import java.util.List; + +/* + * This class contains tests for multiple result sets with an association mapping. + * This test is based on the org.apache.ibatis.submitted.multiple_resultsets test. + * + */ +class MultipleResultSetTest { + + private static SqlSessionFactory sqlSessionFactory; + + @BeforeAll + static void setUp() throws Exception { + try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/multipleresultsetswithassociation/mybatis-config.xml")) { + sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader); + } + + // populate in-memory database + // Could not get the table creation, procedure creation, and data population to work from the same script. + // Once it was in three scripts, all seemed well. + try (SqlSession session = sqlSessionFactory.openSession(); + Connection conn = session.getConnection()) { + try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/multipleresultsetswithassociation/CreateDB1.sql")) { + runReaderScript(conn, reader); + } + try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/multipleresultsetswithassociation/CreateDB2.sql")) { + runReaderScript(conn, reader); + } + try (Reader reader = Resources.getResourceAsReader("org/apache/ibatis/submitted/multipleresultsetswithassociation/CreateDB3.sql")) { + runReaderScript(conn, reader); + } + } + } + + private static void runReaderScript(Connection conn, Reader reader) { + ScriptRunner runner = new ScriptRunner(conn); + runner.setLogWriter(null); + runner.setSendFullScript(true); + runner.setAutoCommit(true); + runner.setStopOnError(false); + runner.runScript(reader); + } + + @Test + void shouldGetOrderDetailsEachHavingAnOrderHeader() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + Mapper mapper = sqlSession.getMapper(Mapper.class); + List orderDetails = mapper.getOrderDetailsWithHeaders(); + + // There are six order detail records in the database + // As long as the data does not change this should be successful + Assertions.assertEquals(6, orderDetails.size()); + + // Each order detail should have a corresponding OrderHeader + // Only 2 of 6 orderDetails have orderHeaders + for (OrderDetail orderDetail : orderDetails) { + Assertions.assertNotNull(orderDetail.getOrderHeader()); + } + } + } + + @Test + void shouldGetOrderDetailsEachHavingAnOrderHeaderAnnotationBased() { + try (SqlSession sqlSession = sqlSessionFactory.openSession()) { + Mapper mapper = sqlSession.getMapper(Mapper.class); + List orderDetails = mapper.getOrderDetailsWithHeadersAnnotationBased(); + + // There are six order detail records in the database + // As long as the data does not change this should be successful + Assertions.assertEquals(6, orderDetails.size()); + + // Each order detail should have a corresponding OrderHeader + // Only 2 of 6 orderDetails have orderHeaders + for (OrderDetail orderDetail : orderDetails) { + Assertions.assertNotNull(orderDetail.getOrderHeader()); + } + } + } + +} diff --git a/docs/spring/csbc4abc3e-df47-11ee-91f8-acde48001122.java b/docs/spring/csbc4abc3e-df47-11ee-91f8-acde48001122.java new file mode 100644 index 00000000..0e888839 --- /dev/null +++ b/docs/spring/csbc4abc3e-df47-11ee-91f8-acde48001122.java @@ -0,0 +1,86 @@ +/** + * Copyright 2009-2019 the original author or authors. + *

+ * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + *

+ * http://www.apache.org/licenses/LICENSE-2.0 + *

+ * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.ibatis.type; + +import org.junit.jupiter.api.Test; + +import java.time.YearMonth; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNull; +import static org.mockito.Mockito.*; + +/** + * @author Björn Raupach + */ +class YearMonthTypeHandlerTest extends BaseTypeHandlerTest { + + private static final TypeHandler TYPE_HANDLER = new YearMonthTypeHandler(); + private static final YearMonth INSTANT = YearMonth.now(); + + @Override + @Test + public void shouldSetParameter() throws Exception { + TYPE_HANDLER.setParameter(ps, 1, INSTANT, null); + verify(ps).setString(1, INSTANT.toString()); + } + + @Override + @Test + public void shouldGetResultFromResultSetByName() throws Exception { + when(rs.getString("column")).thenReturn(INSTANT.toString()); + assertEquals(INSTANT, TYPE_HANDLER.getResult(rs, "column")); + verify(rs, never()).wasNull(); + } + + @Override + @Test + public void shouldGetResultNullFromResultSetByName() throws Exception { + assertNull(TYPE_HANDLER.getResult(rs, "column")); + verify(rs, never()).wasNull(); + } + + @Override + @Test + public void shouldGetResultFromResultSetByPosition() throws Exception { + when(rs.getString(1)).thenReturn(INSTANT.toString()); + assertEquals(INSTANT, TYPE_HANDLER.getResult(rs, 1)); + verify(rs, never()).wasNull(); + } + + @Override + @Test + public void shouldGetResultNullFromResultSetByPosition() throws Exception { + assertNull(TYPE_HANDLER.getResult(rs, 1)); + verify(rs, never()).wasNull(); + } + + @Override + @Test + public void shouldGetResultFromCallableStatement() throws Exception { + when(cs.getString(1)).thenReturn(INSTANT.toString()); + assertEquals(INSTANT, TYPE_HANDLER.getResult(cs, 1)); + verify(cs, never()).wasNull(); + } + + @Override + @Test + public void shouldGetResultNullFromCallableStatement() throws Exception { + assertNull(TYPE_HANDLER.getResult(cs, 1)); + verify(cs, never()).wasNull(); + } + +}