Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

A new type handler for SQLXML data type. #1221

Merged
merged 3 commits into from
May 2, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 72 additions & 0 deletions src/main/java/org/apache/ibatis/type/SqlxmlTypeHandler.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
/**
* Copyright 2009-2018 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 java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.SQLXML;

/**
* Convert <code>String</code> to/from <code>SQLXML</code>.
*
* @since 3.5.0
* @author Iwao AVE!
*/
public class SqlxmlTypeHandler extends BaseTypeHandler<String> {

@Override
public void setNonNullParameter(PreparedStatement ps, int i, String parameter, JdbcType jdbcType)
throws SQLException {
SQLXML sqlxml = ps.getConnection().createSQLXML();
try {
sqlxml.setString(parameter);
ps.setSQLXML(i, sqlxml);
} finally {
sqlxml.free();
}
}

@Override
public String getNullableResult(ResultSet rs, String columnName) throws SQLException {
return sqlxmlToString(rs.getSQLXML(columnName));
}

@Override
public String getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return sqlxmlToString(rs.getSQLXML(columnIndex));
}

@Override
public String getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return sqlxmlToString(cs.getSQLXML(columnIndex));
}

protected String sqlxmlToString(SQLXML sqlxml) throws SQLException {
if (sqlxml == null) {
return null;
}
try {
String result = sqlxml.getString();
return result;
} finally {
sqlxml.free();
}
}

}
2 changes: 2 additions & 0 deletions src/main/java/org/apache/ibatis/type/TypeHandlerRegistry.java
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ public TypeHandlerRegistry() {
register(java.sql.Time.class, new SqlTimeTypeHandler());
register(java.sql.Timestamp.class, new SqlTimestampTypeHandler());

register(String.class, JdbcType.SQLXML, new SqlxmlTypeHandler());

// mybatis-typehandlers-jsr310
if (Jdk.dateAndTimeApiExists) {
this.register(Instant.class, InstantTypeHandler.class);
Expand Down
167 changes: 167 additions & 0 deletions src/test/java/org/apache/ibatis/type/SqlxmlTypeHandlerTest.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
/**
* Copyright 2009-2018 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 static org.junit.Assert.*;

import java.io.Reader;
import java.nio.file.Paths;
import java.sql.Connection;
import java.util.Collections;

import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.jdbc.ScriptRunner;
import org.apache.ibatis.mapping.Environment;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.ibatis.test.EmbeddedPostgresqlTests;
import org.apache.ibatis.transaction.jdbc.JdbcTransactionFactory;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.experimental.categories.Category;

import ru.yandex.qatools.embed.postgresql.EmbeddedPostgres;
import ru.yandex.qatools.embed.postgresql.util.SocketUtil;

@Category(EmbeddedPostgresqlTests.class)
public class SqlxmlTypeHandlerTest {
private static final EmbeddedPostgres postgres = new EmbeddedPostgres();

private static SqlSessionFactory sqlSessionFactory;

@BeforeClass
public static void setUp() throws Exception {
// Launch PostgreSQL server. Download / unarchive if necessary.
String url = postgres.start(
EmbeddedPostgres.cachedRuntimeConfig(Paths.get(System.getProperty("java.io.tmpdir"), "pgembed")), "localhost",
SocketUtil.findFreePort(), "postgres_sqlxml", "postgres", "root", Collections.emptyList());

Configuration configuration = new Configuration();
Environment environment = new Environment("development", new JdbcTransactionFactory(), new UnpooledDataSource(
"org.postgresql.Driver", url, null));
configuration.setEnvironment(environment);
configuration.setUseGeneratedKeys(true);
configuration.addMapper(Mapper.class);
sqlSessionFactory = new SqlSessionFactoryBuilder().build(configuration);

try (SqlSession session = sqlSessionFactory.openSession();
Connection conn = session.getConnection();
Reader reader = Resources
.getResourceAsReader("org/apache/ibatis/type/SqlxmlTypeHandlerTest.sql")) {
ScriptRunner runner = new ScriptRunner(conn);
runner.setLogWriter(null);
runner.runScript(reader);
}
}

@AfterClass
public static void tearDown() {
postgres.stop();
}

@Test
public void shouldReturnXmlAsString() throws Exception {
SqlSession session = sqlSessionFactory.openSession();
try {
Mapper mapper = session.getMapper(Mapper.class);
XmlBean bean = mapper.select(1);
assertEquals("<title>XML data</title>",
bean.getContent());
} finally {
session.close();
}
}

@Test
public void shouldReturnNull() throws Exception {
SqlSession session = sqlSessionFactory.openSession();
try {
Mapper mapper = session.getMapper(Mapper.class);
XmlBean bean = mapper.select(2);
assertNull(bean.getContent());
} finally {
session.close();
}
}

@Test
public void shouldInsertXmlString() throws Exception {
final Integer id = 100;
final String content = "<books><book><title>Save XML</title></book><book><title>Get XML</title></book></books>";
// Insert
{
SqlSession session = sqlSessionFactory.openSession();
try {
Mapper mapper = session.getMapper(Mapper.class);
XmlBean bean = new XmlBean();
bean.setId(id);
bean.setContent(content);
mapper.insert(bean);
session.commit();
} finally {
session.close();
}
}
// Select to verify
{
SqlSession session = sqlSessionFactory.openSession();
try {
Mapper mapper = session.getMapper(Mapper.class);
XmlBean bean = mapper.select(id);
assertEquals(content, bean.getContent());
} finally {
session.close();
}
}
}

interface Mapper {
@Select("select id, content from mbtest.test_sqlxml where id = #{id}")
XmlBean select(Integer id);

@Insert("insert into mbtest.test_sqlxml (id, content) values (#{id}, #{content,jdbcType=SQLXML})")
void insert(XmlBean bean);
}

public static class XmlBean {
private Integer id;

private String content;

public Integer getId() {
return id;
}

public void setId(Integer id) {
this.id = id;
}

public String getContent() {
return content;
}

public void setContent(String content) {
this.content = content;
}
}
}
28 changes: 28 additions & 0 deletions src/test/java/org/apache/ibatis/type/SqlxmlTypeHandlerTest.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
--
-- Copyright 2009-2018 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.
--

CREATE SCHEMA mbtest;

CREATE TABLE mbtest.test_sqlxml (
id serial PRIMARY KEY,
content XML
);

INSERT INTO mbtest.test_sqlxml (id, content)
VALUES (1, '<title>XML data</title>');

INSERT INTO mbtest.test_sqlxml (id, content)
VALUES (2, NULL);