个人电脑操做系统版本为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