※事前規劃
CREATE TABLE TEST_BOOLEAN( ID NUMBER, NAME VARCHAR(10), BOO NUMBER, CONSTRAINT TEST_BOOLEAN_PK PRIMARY KEY(ID) ); COMMENT ON TABLE TEST_BOOLEAN IS '測試布林表'; COMMENT ON COLUMN TEST_BOOLEAN.ID IS 'id'; COMMENT ON COLUMN TEST_BOOLEAN.NAME IS '名字'; COMMENT ON COLUMN TEST_BOOLEAN.BOO IS '0表示false'; INSERT INTO TEST_BOOLEAN(ID, NAME, BOO)VALUES(11, 'tom', 0); INSERT INTO TEST_BOOLEAN(ID, NAME, BOO)VALUES(22, 'jerry', 1); INSERT INTO TEST_BOOLEAN(ID, NAME, BOO)VALUES(33, 'apple', 2); INSERT INTO TEST_BOOLEAN(ID, NAME, BOO)VALUES(44, 'banana', 1); INSERT INTO TEST_BOOLEAN(ID, NAME, BOO)VALUES(55, 'guava', 0);
尤於資料庫沒有布林值,所以用1和0代表true和false
官方的說法有兩種方法,實作TypeHandler介面和繼承BaseTypeHandler
※TypeHandler
先寫一隻實作這介面並覆寫方法getResult:將資料庫的數字轉成java的boolean
setParameter:將java的boolean轉成資料庫的數字
@MappedTypes({Boolean.class})
@MappedJdbcTypes({JdbcType.INTEGER})
public class BooleanIntegerTransfor implements TypeHandler<Boolean> {
@Override
public Boolean getResult(ResultSet rs, String columnName)
throws SQLException {
System.out.println("columnName=" + columnName);
System.out.println(rs.getString(columnName));
return rs.getShort(columnName) != 0;
}
@Override
public Boolean getResult(ResultSet rs, int columnIndex) throws SQLException {
System.out.println("rs columnIndex=" + columnIndex);
System.out.println(rs.getString(columnIndex));
return rs.getInt(columnIndex) != 0;
}
@Override
public Boolean getResult(CallableStatement cs, int columnIndex)
throws SQLException {
System.out.println("cs columnIndex=" + columnIndex);
System.out.println(cs.getString(columnIndex));
return cs.getInt(columnIndex) != 0;
}
@Override
public void setParameter(PreparedStatement ps, int i, Boolean parameter,
JdbcType jdbcType) throws SQLException {
System.out.println("i=" + i);
System.out.println("parameter=" + parameter);
if (parameter == null) {
ps.setNull(i, java.sql.Types.NULL);
} else {
if (parameter) {
ps.setInt(i, 1);
} else {
ps.setInt(i, 0);
}
}
}
}
vo只要注意boo是要轉換的類型,所以雖然資料庫是number,但在java還是寫boolean,然後setter/getter
設定檔的部分,看要偵對整個package或剛剛實作的java,javaType和jdbcType可用註解的方式,如實作的類上面那兩行,取其一種方式:
<typeHandlers> <!-- <package name="org.mybatis.model" /> --> <typeHandler handler="org.mybatis.model.BooleanIntegerTransfor" javaType="java.lang.Boolean" jdbcType="INTEGER" /> </typeHandlers>
vo的xml要注意resultMap的javaType和jdbcType要打才會執行實作的類,而insert也要打,才能呼叫到setParameter方法:
<mapper namespace="a.b.c">
<sql id="column">
ID, NAME, BOO
</sql>
<resultMap type="TestBoolean" id="TestBooleanInterface">
<id property="id" column="ID" />
<result property="name" column="NAME" />
<result property="boo" column="BOO" javaType="java.lang.Boolean" jdbcType="INTEGER" />
</resultMap>
<insert id="insert" parameterType="TestBoolean">
INSERT INTO TEST_BOOLEAN (
<include refid="column" />
) VALUES (
#{id}, #{name}, #{boo, javaType=java.lang.Boolean, jdbcType=INTEGER}
)
</insert>
<select id="findAll" resultMap="TestBooleanInterface">
SELECT <include refid="column" /> FROM TEST_BOOLEAN
</select>
</mapper>
測試類:
SqlSession sqlSession = MyBatisSessionFactory.getSession();
List<TestBoolean> all = sqlSession.selectList("a.b.c.findAll");
for (TestBoolean tb : all) {
System.out.println("a=" + tb.getId());
System.out.println("b=" + tb.getName());
System.out.println("c=" + tb.getBoo());
}
TestBoolean tb = new TestBoolean();
tb.setId(78);
tb.setName("brush");
tb.setBoo(true);
System.out.println(sqlSession.insert("a.b.c.insert", tb));
sqlSession.commit();
MyBatisSessionFactory.closeSession();
心得:
.還有兩個getResult方法,不知怎麼呼叫
.javaType、jdbcType和@MappedTypes、@MappedJdbcTypes這兩組不打或兩組都打,我試也是ok的,可能有它的原理,但我覺得這樣不直覺
.只要打一組,大家都看得懂,好維護。 不打或全打嘛!搞不好哪天mybatis新版就不能使用了也說不定。
.我的這篇文章,講Annotation的,裡面有個@Target,1.8有新增一個叫TYPE_USE,理論上應該哪裡都能使用才對,但我測出來的不是這樣,所以才有那一張表; 但我覺得哪一天版本更新就都可以了也說不定,所以不用太過研究這種不好的設計
※BaseTypeHandler
@MappedTypes({ Boolean.class })
@MappedJdbcTypes({ JdbcType.INTEGER })
public class BooleanIntegerTransfor extends BaseTypeHandler<Boolean> {
@Override
public Boolean getNullableResult(ResultSet rs, String columnName)
throws SQLException {
return rs.getInt(columnName) != 0;
}
@Override
public Boolean getNullableResult(ResultSet rs, int columnIndex)
throws SQLException {
return rs.getInt(columnIndex) != 0;
}
@Override
public Boolean getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
return cs.getInt(columnIndex) != 0;
}
@Override
public void setNonNullParameter(PreparedStatement ps, int i,
Boolean parameter, JdbcType jdbcType) throws SQLException {
System.out.println(parameter);
if (parameter == true) {
ps.setInt(i, 1);
} else {
ps.setInt(i, 0);
}
}
}
沒有留言:
張貼留言