MyBatis練習:查詢表中單個數據列中用分隔符隔開的數據

個人電腦操做系統版本爲Win7旗艦版(ServicePack1),Oracle版本爲Oracle11g,PL/SQL版本爲7.0.1.1066java

程序使用的jar包有:mybatis-3.2.2.jar、ojdbc14-10.2.0.2.0.jarsql

本例中使用的配置文件mybatis-config.xml,能夠參見個人另外一篇Blog《一個簡單的MyBatis鏈接Oracle數據庫的例子》(http://my.oschina.net/Tsybius2014/blog/626206數據庫


最近在工做中遇到一個場景,即一張表的一個數據列(設爲字段A)存儲了多個數據項,每一個數據項都用逗號隔開。現給出一個存放了一或多個數據項的List,若是某一行數據的字段A中有任一單個數據項也在於List中。若是給出的List爲空或長度爲0,則查出全部數據。apache

以下圖所示,表AUTHORITY_LIST下的列USER_AUTH,其中有1-5共計5項,分隔符爲逗號(,),使用PL/SQL看到的內容以下:session

該表的建表腳本爲:mybatis

CREATE TABLE AUTHORITY_LIST
(
    ID NUMBER(12, 0) PRIMARY KEY,
    USER_NAME VARCHAR(100),
    USER_AUTH VARCHAR(100)
);

INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (1, 'Jupiter',     ',1,2,3,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (2, 'Juno',        ',2,3,4,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (3, 'Neptune',     ',3,4,5,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (4, 'Ceres',       ',5,4,3,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (5, 'Minerva',     ',4,3,2,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (6, 'Apollo',      ',3,2,1,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (7, 'Diana',       ',1,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (8, 'Mars',        ',2,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (9, 'Venus',       ',3,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (10, 'Vulcan',     ',4,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (11, 'Mercury',    ',5,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (12, 'Vesta',      ',1,3,5,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (13, 'Bacchus',    ',5,3,1,');

INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (14, 'Orcus',      ',1,3,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (15, 'Hercules',   ',2,3,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (16, 'Proserpina', ',2,5,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (17, 'Vejovis',    ',4,2,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (18, 'Cupid',      ',3,1,');
INSERT INTO AUTHORITY_LIST (ID, USER_NAME, USER_AUTH) VALUES (19, 'Juventas',   ',5,1,');

COMMIT;
/

如今我要作的是,給定0項、1項或多項,查詢符合條件條目的USER_NAME並返回。app

如我要查詢具有條件1或5的條目,傳入的List中帶有一、5兩項,則在USER_AUTH中具備1或4的條目都應被查出。如Diana的USER_AUTH爲「,1,」,Mercury的USER_AUTH爲「,5,」,Apollo的 USER_AUTH爲「3,2,1」,他們均可被查出,但Vejovis的USER_AUTH爲「,4,2,」,由於其中沒有1也沒有5,就不能被查出了。函數

爲此我先寫了一個SQL語句,用於查詢USER_AUTH中包含1或5的條目:測試

SELECT *
FROM   AUTHORITY_LIST
WHERE  USER_AUTH LIKE '%,1,%' OR
       USER_AUTH LIKE '%,5,%';

查詢結果以下:ui

如今將這個SQL語句移植到MyBatis中,main函數調用代碼以下:

import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

/**
 * MyBatis使用測試
 * @author Tsybius2014
 * @date 2016年5月21日
 * @time 下午3:45:08
 * @remark
 */
public class MyBatisTest {
    public static void main(String[] args) {
        try {
            String resource = "mybatis-config.xml";
            InputStream inputStream = Resources.getResourceAsStream(resource);
            SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
            SqlSession session = sqlSessionFactory.openSession();
            try {
                AuthorityListMapper mapper = session.getMapper(AuthorityListMapper.class);
                List<String> authList = new ArrayList<String>();
                authList.add("1");
                authList.add("5");
                List<String> userList = mapper.getUsersByAuth(authList);
                System.out.println(String.join(",\n", userList));
            } finally {
                session.close();
            }
        } catch (Exception ex) {
            StringWriter stringWriter = new StringWriter();
            PrintWriter printWriter = new PrintWriter(stringWriter);
            ex.printStackTrace(printWriter);
            System.out.println(stringWriter.toString());
        }
    }
}

AuthorityListMapper.java代碼以下:

import java.util.List;

public interface AuthorityListMapper {
    List<String> getUsersByAuth(List<String> authList);
}

AuthorityListMapper.xml代碼以下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" 
    "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="AuthorityListMapper"> 
  <select id="getUsersByAuth" parameterType="java.util.List" resultType="java.lang.String" >
    SELECT USER_NAME FROM AUTHORITY_LIST 
    <if test="list != null and list.size() > 0">
      WHERE 
      <foreach item="item" index="index" collection="list" separator="OR" >
          USER_AUTH LIKE '%'||#{item}||'%'
      </foreach>
    </if>
  </select>
</mapper>

程序運行結果以下:

Jupiter,
Neptune,
Ceres,
Apollo,
Diana,
Mercury,
Vesta,
Bacchus,
Orcus,
Proserpina,
Cupid,
Juventas

PS:其實這張表的表結構設計得並很差,這種一對多的關係若是採用兩張表存儲,在查詢的時候使用關聯查詢,會方便得多。本文中的辦法只是一個思路,當老的數據表中已經存有一些數據,且沒法輕易更改老數據表的表結構時,可參考本文的方法。

END

相關文章
相關標籤/搜索