现在在数据库增加两张表blog与comment ,即博客与评论表。
CREATE TABLE `blog` (
`id` int(11) NOT NULL default '0',
`title` varchar(255) default NULL,
`content` text,
`pub_time` datetime default NULL,
`user_id` int(11) default NULL,
PRIMARY KEY (`id`),
KEY `title` (`title`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `comment` (
`id` int(11) NOT NULL default '0',
`content` text,
`pub_time` datetime default NULL,
`blog_id` int(11) default NULL,
`user_id` int(11) default NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
增加pojo对象
package com.zf.mybatis.pojo;
import java.util.Date;
import java.util.List;
public class Blog {
private int id ;
private String title ;
private String content ;
private Date pubTime ;
private User author ;
private List comments ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getPubTime() {
return pubTime;
}
public void setPubTime(Date pubTime) {
this.pubTime = pubTime;
}
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
public List getComments() {
return comments;
}
public void setComments(List comments) {
this.comments = comments;
}
}
package com.zf.mybatis.pojo;
import java.util.Date;
public class Comment {
private int id ;
private String content ;
private Date pubTime;
private Blog blog ;
private User author ;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
public Date getPubTime() {
return pubTime;
}
public void setPubTime(Date pubTime) {
this.pubTime = pubTime;
}
public Blog getBlog() {
return blog;
}
public void setBlog(Blog blog) {
this.blog = blog;
}
public User getAuthor() {
return author;
}
public void setAuthor(User author) {
this.author = author;
}
}
编写映射文件
Blog.xml
id , title , content , pub_time as pubTime , user_id as User
按照上面的配置,会将blog的所有字段全部查询出来 ,author的所有字段查询出来,comment的id与content字段查询出来。 如果要查询出其他的字段,可以在resutMap中进行配置,并在sql中加入要查询的字段。
然后在mybatis-config.xml文件中加入pojo的别名,并将Blog.xml映射文件注册到mybatis-config.xml文件中。
之后就可以进行测试了。 看能否查询出想要的数据。
注意:可以通过配置log4j来打印sql的输出。 首先在pom.xml中加入log4j的依赖,然后加入log4j的配置文件,如下:
log4j.rootCategory=DEBUG, stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%m%n
log4j.logger.java.sql.ResultSet=INFO
log4j.logger.org.apache=INFO
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
现在编写测试类来测试:
package com.zf.mybatis;
import java.io.IOException;
import java.io.Reader;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.junit.Before;
import org.junit.Test;
import com.zf.mybatis.pojo.Blog;
public class TestMyBatis02 {
private SqlSessionFactory sqlSessionFactory;
private Reader reader;
@Before
public void init(){
try {
reader = Resources.getResourceAsReader("mybatis-config.xml");
sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
} catch (IOException e) {
e.printStackTrace();
}
}
@Test
public void testQueryBlog(){
SqlSession session = sqlSessionFactory.openSession();
try {
Blog blog = (Blog) session.selectOne("com.zf.mybatis.pojo.BlogMapper.selectByID" ,1);
if(blog != null)
System.out.printf(
"title:%s , content:%s , pubTime:%tT , authorName:%s ,authorAge:%d , authorPass:%s , authorAddress:%s" ,
blog.getTitle(),
blog.getContent() ,
blog.getPubTime() ,
blog.getAuthor().getUserName(),
blog.getAuthor().getUserAge() ,
blog.getAuthor().getPassword() ,
blog.getAuthor().getUserAddress()
);
else
System.out.println("没有查询到数据");
} finally {
session.close();
}
}
}
ooo Using Connection [com.mysql.jdbc.JDBC4Connection@1f66cff]
==> Preparing: select B.id as blog_id , B.title as blog_title , B.content as blog_content , B.pub_time as blog_pub_time , B.user_id as blog_user_id , U.id as user_id, U.password as user_password, U.user_name as user_user_name , U.user_age as user_user_age , U.user_address as user_user_address from `blog` B left outer join `user` U on B.user_id = U.id where B.id = ?
==> Parameters: 1(Integer)
<== Total: 1
title:testtitle , content:test content , pubTime:23:14:31 , authorName:summer ,authorAge:100 , authorPass:123131 , authorAddress:shanghai,pudong
可以看到 , 正确的查询除了数据。 (在执行方法之前首先在数据库blog表中插入一条测试数据),上面的方法同时会将该blog的所有comment也查询出来,但是要实现在comment表中插入一些测试数据。
上面的resultMap写起来相当的庞大,且不利于复用。 所以还有另外一种方式来配置resultMap ,如下:
注意 association节点中的select属性,他的值指向了User.xml中的selectByID方法,所以他会使用该方法进行查询, 这样做的好处是提高了代码的复用率 ,也减小了resultMap的复杂性。 但是这样会存在一个N+1的问题。
注意collection中的select指向的是Comment.xml中的selectByBlogID方法,它会将sql中查询出来列名为blog_id的值传递给该方法作为参数。
Comment.xml配置如下:
id , content , pub_time , blog_id , user_id
另外一种提高代码复用率的方法是将resultMap提取出来, 同时也减小了resultMap的复杂度。 代码如下: