※事前規劃
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); } } }
沒有留言:
張貼留言