首先在数据库bookstore中建立三张表,分别是BSuser,author,reader
CREATE TABLE `author` ( `id` int(11) NOT NULL AUTO_INCREMENT, `realName` varchar(20) COLLATE utf8_bin DEFAULT NULL, `userID` int(11) DEFAULT NULL, `IDCard` varchar(20) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `BSuser` ( `id` int(11) NOT NULL AUTO_INCREMENT, `userName` varchar(20) COLLATE utf8_bin DEFAULT NULL, `password` varchar(20) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
CREATE TABLE `reader` ( `visitID` int(11) NOT NULL AUTO_INCREMENT, `userID` int(11) DEFAULT NULL, `visitDate` datetime DEFAULT NULL, `visitIP` varchar(100) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`visitID`) ) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
1.联合查询
新建author.xml 添加
<select id="selectAuthorJoin" resultMap="AuthorMap"> select * from author inner join BSuser on BSuser.id=author.userID </select>
上述代码中resultMap="AuthorMap" 所以得在上述代码前添加对resultMap的描述
<resultMap id="AuthorMap" type="Author"> <id property="id" column="author.id" /> <result property="realName" column="realName" /> <result property="IDCard" column="IDCard" /> <--! association 里写了对关联属性的相关描述--> <association property="bsuser" column="userID" <--! bsuser是author类定义的一个属性--> javaType="BSuser"> <id property="id" column="bsuser.id" /> <result property="userName" column="userName" /> <result property="password" column="password" /> </association> </resultMap>
接着新建一个测试类
public static void main(String[] args) { String resource = "kobe/book/map/MyBatisConfig.xml"; Reader reader = null; SqlSession session; try { reader = Resources.getResourceAsReader(resource); } catch (IOException e) { e.printStackTrace(); } SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader); session = sqlMapper.openSession(); try{ List<Author> ap=session.selectList("selectAuthorJoin");//联合查询与构造查询 for(Author temp:ap) { System.out.println("作者真实姓名="+temp.getRealName()+ "对应的用户名="+temp.getbsuser().getUserName()); } } catch(Exception e) { e.printStackTrace(); } finally { session.close(); } }
以上便是MyBatis的联合查询的例子
接着是MyBatis的构造查询,构造查询的sql语句与联合查询相同,不同点在于sql语句中的 resultMap="AuthorMapByCon" 而此resultMap的association有所不同
<association property="bsuser" column="userID" javaType="BSuser"> <constructor> <arg column="userName" javaType="String" /> <arg column="password" javaType="String" /> </constructor> </association>
再次执行测试代码。
最后子查询,子查询的sql语句为
<select id="selectAuthor" resultMap="AuthorSubMap"> select * from author </select>
resultMap为
<resultMap id="AuthorSubMap" type="Author"> <id property="id" column="author.id" /> <result property="realName" column="realName" /> <result property="IDCard" column="IDCard" /> <association property="bsuser" column="userID" javaType="bsuser" select="findById"> </association> </resultMap>
子查询的测试代码把上面测试代码try的代码改为
try{ List<Author> ap=session.selectList("selectAuthor");//子查询 for(Author temp:ap) { System.out.println("作者真实姓名="+temp.getRealName()); System.out.println("用户名="+temp.getbsuser().getUserName()); } }
运行测试代码,发现在控制台打印了两条sql语句,子查询虽然进行了N+1次查询,但是占用资源却可大可小,因为持久化框架MyBatis有懒加载机制,因为懒加载默认是不开启的,所以你需在MyBatis的基本配置文件里把lazyLoadingEnabled的value值改成true而且把aggressiveLazyLoading的value改为false。懒加载机制可以控制查询次数,需要时再查询,不需要时不查询,运用合理的话,子查询能比联合查询效率更高。
以上便是MyBatis的关联查询,欢迎指出不足之处,互相交流,谢谢。