mybatis動態SQL
簡化SQL
Sql 中可將重復的 sql 提取出來,使用時用include 引用即可,最終達到 sql 重用的目的。
<!-- 抽取重復片段-->
<sql id="selectAll" >
select * from user
</sql>
<!--使用重復片段-->
<select id="findUserAll" resultType="user">
-- select * from user
<include refid="selectAll"></include>
</select>
mybatis多表查詢
一對一查詢
示例:一個gameAccount(游戲賬號)與player(玩家)為一對一關系
實現:
- 數據庫中game_account(賬號表)包含player(玩家表)的主鍵作為外鍵。
- 一的一方的主鍵作為一的一方的外鍵。
- 實體類中GameAccount(賬號實體類)包含Player(玩家實體類)的引用。
- 主表(直接查詢的表)包含從表(關聯查詢的表)實體類的引用。
需求:查詢賬號,並且關聯查詢用戶。
玩家表:
create table player(
pid int primary key auto_increment,
pname varchar(20),
psex varchar(20)
);
賬號表:
create table game_account(
gid int primary key auto_increment,
gusername varchar(20),
gpassword varchar(20),
gpid int,
foreign key (gpid) references player(pid)
);
玩家實體類:
package com.mybatis_xml.pojo;
import java.io.Serializable;
public class Player implements Serializable {
private Integer pid;
private String pname;
private String psex;
//getter,setter,toString
}
賬號實體類:
package com.mybatis_xml.pojo;
import java.io.Serializable;
public class GameAccount implements Serializable {
private Integer gid;
private String gusername;
private String gpassword;
private Integer gpid;//player表的主鍵
//一對一關系:主表(直接查詢的表)包含從表(關聯查詢的表)實體類的引用
private Player player;
//getter,setter,toString
}
IGameAccountMapper接口:
package com.mybatis_xml.mapper;
import com.mybatis_xml.pojo.GameAccount;
import java.util.List;
public interface IGameAccountMapper {
//賬號和玩家為一對一關系;查詢賬號,關聯查詢玩家
List<GameAccount> findAll();
}
IGameAccountMapper.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="com.mybatis_xml.mapper.IGameAccountMapper">
<!-- resultMap標簽用於指定數據庫表與實體的一一映射關系
id屬性:給定一個唯一標識,是給select標簽resultMap屬性引用的。
type屬性:接口對應的實體類的全限定類名或者配置了別名后的別名
-->
<resultMap id="gameAccountMap" type="gameAccount">
<!--id標簽用於指定主鍵對應
property屬性:用於指定實體類屬性名稱
column屬性:用於指定數據庫列名
-->
<id property="gid" column="gid"></id>
<!--result標簽指定非主鍵對應-->
<result column="gusername" property="gusername"></result>
<result column="gpassword" property="gpassword"></result>
<result column="gpid" property="gpid"></result>
<!--association標簽配置GameAccount對象中player對象引用的映射關系:一般為一對一配置
property屬性:用於指定被引用實體類屬性名稱
javaType屬性:用於指定被引用實體的Java類全限定類名
-->
<association property="player" javaType="player">
<id property="pid" column="pid"></id>
<result property="pname" column="pname"></result>
<result property="psex" column="psex"></result>
</association>
</resultMap>
<!--
SELECT
p.*,g.gid,g.gpid,g.gpassword,g.gusername
FROM
game_account g,
player p
WHERE
g.gpid = p.pid
-->
<!--
SELECT 查詢的字段
FROM 表 表別名
-->
<select id="findAll" resultMap="gameAccountMap">
SELECT
p.*,g.gid,g.gpid,g.gpassword,g.gusername
FROM
game_account g,
player p
WHERE
g.gpid = p.pid
</select>
</mapper>
OneToOne.class測試類:
import com.mybatis_xml.mapper.IGameAccountMapper;
import com.mybatis_xml.pojo.GameAccount;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class OneToOne {
private InputStream is;
private SqlSession session;
private SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
private SqlSessionFactory factory;
private IGameAccountMapper gameAccountMapper;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
// 讀取mybatis配置文件
is = Resources.getResourceAsStream(resource);
// 創建構造者對象
sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 創建工廠對象
factory = sqlSessionFactoryBuilder.build(is);
// 創建SqlSession對象
session = factory.openSession();
// 創建IUserMapper對象
gameAccountMapper = session.getMapper(IGameAccountMapper.class);
}
@After
public void destory() throws IOException {
session.close();
is.close();
}
//測試查詢所有
@Test
public void testFindAll() throws IOException {
List<GameAccount> pgs = gameAccountMapper.findAll();
System.out.println(pgs);
}
}
多對一查詢
示例:一個Book(書籍)與Own(所有者)為多對一關系。
實現:
- 數據庫中book(書籍表)包含own(所有者表)的主鍵作為外鍵。
- 把一的一方的主鍵作為多的一方的外鍵。
- 實體類中Own(所有者實體類)包含Book(書籍實體類)的集合引用。
- 主表(直接查詢的表)實體類包含從表(關聯查詢的表)實體類集合的引用。
需求:查尋所有者,並且關聯查詢書籍。
所有者表:
create table own(
oid int primary key auto_increment,
oname varchar(20)
);
書籍表:
create table book(
bid int primary key auto_increment,
bname varchar(20),
boid int,
foreign key(boid) references own(oid)
);
書籍實體類:
package com.mybatis_xml.pojo;
import java.io.Serializable;
public class Book implements Serializable {
private Integer bid;
private String bname;
private Integer boid;
//getter,setter,toString省略
}
所有者實體類:
package com.mybatis_xml.pojo;
import java.io.Serializable;
import java.util.List;
public class Own implements Serializable {
private Integer oid;
private String oname;
//多對一:主表包含從表的集合引用
private List<Book> books;
//getter,setter,toString省略
}
IOwnMapper接口:
package com.mybatis_xml.mapper;
import com.mybatis_xml.pojo.Own;
import java.util.List;
public interface IOwnMapper {
//所有者與書籍為一對多關系:查詢所有者,關聯查詢書籍
List<Own> findAll();
}
IOwnMapper.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="com.mybatis_xml.mapper.IOwnMapper">
<resultMap id="ownMap" type="own">
<id column="oid" property="oid"></id>
<result column="oname" property="oname"></result>
<!--collection標簽配置own對象中Book集合的映射關系:一般為一對多配置
property屬性:指定集合變量名稱
ofType屬性:指定集合元素類型,全限定類名
-->
<collection property="books" ofType="book">
<id property="bid" column="bid"></id>
<result property="bname" column="bname"></result>
<result property="boid" column="boid"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="ownMap">
select
o.*,b.bid,b.boid,b.bname
from own o
left outer
join book b
on b.boid = o.oid;
</select>
</mapper>
ManyToOne.class測試類:
import com.mybatis_xml.mapper.IOwnMapper;
import com.mybatis_xml.pojo.Own;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class ManyToOne {
private InputStream is;
private SqlSession session;
private SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
private SqlSessionFactory factory;
private IOwnMapper ownMapper;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
// 讀取mybatis配置文件
is = Resources.getResourceAsStream(resource);
// 創建構造者對象
sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 創建工廠對象
factory = sqlSessionFactoryBuilder.build(is);
// 創建SqlSession對象
session = factory.openSession();
// 創建IUserMapper對象
ownMapper = session.getMapper(IOwnMapper.class);
}
@After
public void destory() throws IOException {
session.close();
is.close();
}
//測試查詢所有
@Test
public void testFindAll() throws IOException {
List<Own> pgs = ownMapper.findAll();
System.out.println(pgs);
}
}
多對多查詢
示例:一個Student(學生)對應多個(Teacher)老師,一個 、Teacher(老師)對應多個Student(學生),所以學生和老師是多對多關系。
實現:
- 數據庫中student(學生表)的主鍵,teacher(老師表)的主鍵,作為s_t(學生_老師表)的外鍵。
- 抽取兩個主鍵,作為新的表的外鍵
- 實體類中Student(學生實體類)引用Teacher(老師實體類)的集合,Teacher(老師實體類)引用Student(學生實體類)的集合。
- 主從表各包含對對方實體集合的引用
student表:
create table student(
sid int primary key auto_increment,
sname varchar(20)
);
teacher表:
create table teacher(
tid int primary key auto_increment,
tname varchar(20)
);
中間表:
-- 注意:st_sid需要添加括號
create table st(
st_sid int,
st_tid int,
foreign key (st_sid) references student(sid),
foreign key (st_tid) references teacher(tid)
);
Teacher實體類:
package com.mybatis_xml.pojo;
import java.io.Serializable;
import java.util.List;
public class Teacher implements Serializable {
private Integer tid;
private String tname;
//多對多:主表和從表各包含對方集合的引用
private List<Student> students;
//setter,getter,toString省略
}
Student實體類:
package com.mybatis_xml.pojo;
import java.io.Serializable;
import java.util.List;
public class Student implements Serializable {
private Integer sid;
private String sname;
//多對多:主表和從表各包含對方集合的引用
private List<Teacher> teachers;
//setter,getter,toString省略
}
IStudentMapper接口:
package com.mybatis_xml.mapper;
import com.mybatis_xml.pojo.Student;
import java.util.List;
public interface IStudentMapper {
//多對多:查詢學生,關聯查詢老師
List<Student> findAll();
}
ITeacherMappper接口:
package com.mybatis_xml.mapper;
import com.mybatis_xml.pojo.Teacher;
import java.util.List;
public interface ITeacherMapper {
//多對多:查詢老師,關聯查詢學生
List<Teacher> findAll();
}
IStudentMapper.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="com.mybatis_xml.mapper.IStudentMapper">
<resultMap id="studentMap" type="student">
<id property="sid" column="sid"></id>
<result property="sname" column="sname"></result>
<collection property="teachers" ofType="teacher">
<id property="tid" column="tid"></id>
<result property="tname" column="tname"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="studentMap">
select s.*,t.*
from student s
left outer join st on s.sid=st.st_sid
left outer join teacher t on t.tid=st.st_tid
</select>
</mapper>
ITeacherMapper.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="com.mybatis_xml.mapper.ITeacherMapper">
<resultMap id="teacherMap" type="teacher">
<id property="tid" column="tid"></id>
<result property="tname" column="tname"></result>
<collection property="students" ofType="student">
<id property="sid" column="sid"></id>
<result property="sname" column="sname"></result>
</collection>
</resultMap>
<select id="findAll" resultMap="teacherMap">
select t.*,s.*
from student s
left outer join st on s.sid=st.st_sid
left outer join teacher t on t.tid=st.st_tid
</select>
</mapper>
ManyToMany.class測試類:
import com.mybatis_xml.mapper.IOwnMapper;
import com.mybatis_xml.mapper.IStudentMapper;
import com.mybatis_xml.mapper.ITeacherMapper;
import com.mybatis_xml.pojo.Student;
import com.mybatis_xml.pojo.Teacher;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class ManyToMany {
private InputStream is;
private SqlSession session;
private SqlSessionFactoryBuilder sqlSessionFactoryBuilder;
private SqlSessionFactory factory;
private IStudentMapper studentMapper;
private ITeacherMapper teacherMapper;
@Before
public void init() throws IOException {
String resource = "mybatis-config.xml";
// 讀取mybatis配置文件
is = Resources.getResourceAsStream(resource);
// 創建構造者對象
sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
// 創建工廠對象
factory = sqlSessionFactoryBuilder.build(is);
// 創建SqlSession對象
session = factory.openSession();
// 創建IUserMapper對象
studentMapper = session.getMapper(IStudentMapper.class);
teacherMapper = session.getMapper(ITeacherMapper.class);
}
@After
public void destory() throws IOException {
session.close();
is.close();
}
@Test
public void testFindAllStudent(){
List<Student> students = studentMapper.findAll();
System.out.println(students);
}
@Test
public void testFindAllTeacher(){
List<Teacher> teachers = teacherMapper.findAll();
System.out.println(teachers);
}
}
