1. 開發(fā)規(guī)范
Mapper接口開發(fā)方法只需要程序員編寫Mapper接口(相當(dāng)于Dao接口)霉晕,由Mybatis框架根據(jù)接口定義創(chuàng)建接口的動(dòng)態(tài)代理對(duì)象,代理對(duì)象的方法體同上邊Dao接口實(shí)現(xiàn)類方法。
Mapper接口開發(fā)需要遵循以下規(guī)范:
- Mapper.xml文件中的namespace與mapper接口的類路徑相同,即namespace必須是接口的全限定名。
- Mapper接口方法名和Mapper.xml中定義的每個(gè)statement的id相同。
- Mapper接口方法的輸入?yún)?shù)類型和mapper.xml中定義的每個(gè)sql的parameterType的類型相同橄镜。
- Mapper接口方法的輸出參數(shù)類型和mapper.xml中定義的每個(gè)sql的resultType的類型相同。
2. 簡單使用Mapper
本項(xiàng)目數(shù)據(jù)庫基于JavaEE Mybatis使用文章
1). 編寫Mapper接口
在工程的src目錄下新建一個(gè)com.mazaiting.mapper包冯乘,并在該包下創(chuàng)建一個(gè)Mapper接口——UserMapper.java
public interface UserMapper {
User getUserById(int id);
List<User> getUserByName(String username);
void addUser(User user);
}
接口定義有如下特點(diǎn):
- mapper接口方法名和mapper.xml中定義的statement的id相同洽胶。
- mapper接口方法的輸入?yún)?shù)類型和mapper.xml中定義的statement的parameterType的類型相同。
- mapper接口方法的輸出參數(shù)類型和mapper.xml中定義的statement的resultType的類型相同裆馒。
2). 編寫Mapper.xml(映射文件)
在config源碼目錄下新建一個(gè)mapper的普通文件夾姊氓,該文件夾專門用于存放映射文件。然后在該文件夾下創(chuàng)建一個(gè)名為mapper.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.mazaiting.mapper.UserMapper">
<select id="getUserById" parameterType="int" resultType="com.mazaiting.po.User">
select * from user where id = #{id}
</select>
<select id="getUserByName" parameterType="string" resultType="com.mazaiting.po.User">
select * from user where username like '%${value}%'
</select>
<insert id="addUser" parameterType="com.mazaiting.po.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
3). 加載mapper.xml映射文件
在SqlMapConfig.xml文件添加如下配置:
<mapper resource="mapper/mapper.xml"/>
SqlMapConfig.xml內(nèi)容如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 和spring整合后environments配置將廢除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事務(wù)管理 -->
<transactionManager type="JDBC" />
<!-- 數(shù)據(jù)庫連接池 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 添加的內(nèi)容 -->
<mappers>
<!-- resource是基于classpath來查找的 -->
<mapper resource="sqlmap/user.xml"/>
<mapper resource="mapper/mapper.xml"/>
</mappers>
</configuration>
4). 編寫測試程序
public class UserMapperTest {
// 單例工廠
private SqlSessionFactory factory;
@Before
public void init() throws IOException {
// 1. 創(chuàng)建SqlSessionFactoryBuilder對(duì)象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 2. 加載配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 創(chuàng)建SqlSessionFactory對(duì)象
factory = builder.build(inputStream);
}
@Test
public void testGetUserById() {
// 和Spring整合后就省略了
SqlSession session = factory.openSession();
// 獲得代理對(duì)象(和Spring整合后只需要通過Spring容器拿到Usermapper接口的搭理對(duì)象就可以了)
UserMapper userMapper = session.getMapper(UserMapper.class);
User user = userMapper.getUserById(10);
System.out.println(user);
// 和Spring整合后就省略了
session.close();
}
@Test
public void testGetUserByName() {
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list = mapper.getUserByName("張");
for(User user : list) {
System.out.println(user);
}
session.close();
}
@Test
public void testAddUser(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setUsername("凌浩雨");
user.setSex("男");
user.setBirthday(new Date());
user.setAddress("理化所");
mapper.addUser(user);
System.out.println(user.getId());
session.commit();
session.close();
}
}
5). 打印結(jié)果:
testGetUserById
testGetUserByName
testAddUser
6). 總結(jié)
- selectOne和selectList
動(dòng)態(tài)代理對(duì)象調(diào)用sqlSession.selectOne()和sqlSession.selectList()是根據(jù)mapper接口方法的返回值決定喷好,如果返回list則調(diào)用selectList方法翔横,如果返回單個(gè)對(duì)象則調(diào)用selectOne方法。 - namespace
mybatis官方推薦使用mapper代理方法開發(fā)mapper接口梗搅,程序員不用編寫mapper接口實(shí)現(xiàn)類禾唁,使用mapper代理方法時(shí)效览,輸入?yún)?shù)可以使用pojo包裝對(duì)象或map對(duì)象,保證dao的通用性荡短。
3. SqlMapConfig.xml配置文件
1). 配置內(nèi)容
SqlMapConfig.xml文件中配置的內(nèi)容和順序如下:
1>. properties(屬性)
2>. settings(全局配置參數(shù))
3>. typeAliases(類型別名)
4>. typeHandlers(類型處理器)
5>. objectFactory(對(duì)象工廠)
6>. plugins(插件)
7>. environments(環(huán)境集合屬性對(duì)象)
I.environment(環(huán)境子屬性對(duì)象)
1>>.transactionManager(事務(wù)管理)
2>>.dataSource(數(shù)據(jù)源)
8>. mappers(映射器)
2). properties(屬性)
在SqlMapConfig.xml配置文件中丐枉,我們可把數(shù)據(jù)庫連接信息配置到properties標(biāo)簽當(dāng)中
<!-- 配置屬性 -->
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
</properties>
SqlMapConfig.xml文件內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置屬性 -->
<properties>
<property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/>
</properties>
<!-- 和spring整合后environments配置將廢除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事務(wù)管理 -->
<transactionManager type="JDBC" />
<!-- 數(shù)據(jù)庫連接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="root" />
<property name="password" value="root" />
</dataSource>
</environment>
</environments>
<!-- 添加的內(nèi)容 -->
<mappers>
<!-- resource是基于classpath來查找的 -->
<mapper resource="sqlmap/user.xml"/>
<mapper resource="mapper/mapper.xml"/>
</mappers>
</configuration>
將數(shù)據(jù)庫連接信息配置到一個(gè)java屬性文件中,然后再來引用其中的配置信息肢预。我按照這種指導(dǎo)思想在classpath下定義一個(gè)db.properties文件.
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
SqlMapConfig.xml文件內(nèi)容:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!-- 配置屬性 -->
<properties resource="db.properties">
<!-- <property name="jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="jdbc.url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8"/> -->
<property name="jdbc.driver" value="${jdbc.driver}"/>
<property name="jdbc.url" value="${jdbc.url}"/>
</properties>
<!-- 和spring整合后environments配置將廢除 -->
<environments default="development">
<environment id="development">
<!-- 使用jdbc事務(wù)管理 -->
<transactionManager type="JDBC" />
<!-- 數(shù)據(jù)庫連接池 -->
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}" />
<property name="url" value="${jdbc.url}" />
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
</dataSource>
</environment>
</environments>
<!-- 添加的內(nèi)容 -->
<mappers>
<!-- resource是基于classpath來查找的 -->
<mapper resource="sqlmap/user.xml"/>
<mapper resource="mapper/mapper.xml"/>
</mappers>
</configuration>
3). typeAliases(類型別名)
- mybatis支持別名
別名 | 映射的類型 |
---|---|
_byte | byte |
_long | long |
_short | short |
_int | int |
_integer | int |
_double | double |
_float | float |
_boolean | boolean |
string | String |
byte | Byte |
long | Long |
short | Short |
int | Integer |
integer | Integer |
double | Double |
float | Float |
boolean | Boolean |
date | Date |
decimal | BigDecimal |
bigdecimal | BigDecimal |
map | Map |
- 自定義別名
在SqlMapConfig.xml文件中添加:
<!-- 配置pojo的別名 -->
<typeAliases>
<!-- 單個(gè)定義別名,別名不區(qū)分大小寫 -->
<typeAlias type="com.mazaiting.po.User" alias="User"/>
</typeAliases>
則mapper.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.mazaiting.mapper.UserMapper">
<!-- 應(yīng)用別名 -->
<select id="getUserById" parameterType="int" resultType="User">
select * from user where id = #{id}
</select>
<select id="getUserByName" parameterType="string" resultType="com.mazaiting.po.User">
select * from user where username like '%${value}%'
</select>
<insert id="addUser" parameterType="com.mazaiting.po.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
</mapper>
注意:resultType屬性的值就是User類的別名洼哎,且別名是不區(qū)分大小寫的.
- 批量定義別名
<!-- 配置pojo的別名 -->
<typeAliases>
<!-- 批量別名定義烫映,掃描包的形式創(chuàng)建別名,別名就是類名噩峦,且不區(qū)分大小寫 -->
<package name="com.mazaiting.po"/>
</typeAliases>
4). SqlMapConfig.xml文件加載mapper.xml文件
- <mapper resource=" " />
使用相對(duì)于類路徑的資源锭沟,如
<mapper resource="sqlmap/user.xml"/>
- <mapper class=" " />
使用mapper接口類路徑,如:
<mapper class="com.mazaiting.mapper.UserMapper"/>
注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同识补,且放在同一個(gè)目錄中族淮。
- <package name=""/>
注冊(cè)指定包下的所有mapper接口,如:
<package name="com.mazaiting.mapper"/>
注意:此種方法要求mapper接口名稱和mapper映射文件名稱相同凭涂,且放在同一個(gè)目錄中祝辣。
4. 輸入映射--parameterType(輸入類型)
1). 傳遞簡單類型
<select id="getUserById" parameterType="int" resultType="com.mazaiting.po.User">
select * from user where id = #{id};
</select>
2). 傳遞pojo對(duì)象
MyBatis使用ognl表達(dá)式解析對(duì)象字段的值鞋怀,#{}或者${}括號(hào)中的值為pojo屬性名稱脊串。
<insert id="addUser" parameterType="com.mazaiting.po.User">
insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
3). 傳遞pojo包裝對(duì)象
I. 在com.mazaiting.po包下新建QueryVo類
public class QueryVo {
private User user;
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
}
II. 在UserMapper.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.mazaiting.mapper.UserMapper">
<select id="getUserByQueryVo" parameterType="queryvo" resultType="user">
select * from user where id = #{user.id}
</select>
</mapper>
III. 在UserMapper接口中添加方法
public interface UserMapper {
User getUserByQueryVo(QueryVo queryVo);
}
IV. 編寫測試代碼
public class UserMapperTest {
// 單例工廠
private SqlSessionFactory factory;
@Before
public void init() throws IOException {
// 1. 創(chuàng)建SqlSessionFactoryBuilder對(duì)象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 2. 加載配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 創(chuàng)建SqlSessionFactory對(duì)象
factory = builder.build(inputStream);
}
@Test
public void testGetUserByQueryVo(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo();
User user = new User();
user.setId(10);
queryVo.setUser(user);
User queryUser = mapper.getUserByQueryVo(queryVo);
System.out.println(queryUser);
session.close();
}
}
V. 打印結(jié)果:
4). 傳遞HashMap(傳遞HashMap在實(shí)際開發(fā)中用的很少)
I. 在UserMapper中添加查詢方法
<?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.mazaiting.mapper.UserMapper">
<!-- 傳遞HashMap綜合查詢用戶信息 -->
<select id="findUserByHashMap" parameterType="hashmap" resultType="user">
select * from user where id = #{id} and username like '%${username}%'
</select>
</mapper>
注:id和username是HashMap的key匆光。
II. 在UserMapper中添加接口方法
public interface UserMapper {
User findUserByHashMap(HashMap<String, Object> map);
}
III. 編寫測試方法
public class UserMapperTest {
// 單例工廠
private SqlSessionFactory factory;
@Before
public void init() throws IOException {
// 1. 創(chuàng)建SqlSessionFactoryBuilder對(duì)象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 2. 加載配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 創(chuàng)建SqlSessionFactory對(duì)象
factory = builder.build(inputStream);
}
@Test
public void testFindUserByHashMap(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
HashMap<String, Object> map = new HashMap<>();
map.put("id", 10);
map.put("username", "張");
User user = mapper.findUserByHashMap(map);
System.out.println(user);
session.close();
}
}
IV. 打印結(jié)果
5. 輸出映射--resultType(輸出類型)
1). 輸出簡單類型
I. 在UserMapper.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.mazaiting.mapper.UserMapper">
<!-- 查詢表中的記錄數(shù) -->
<select id="getUserCount" resultType="int">
select COUNT(*) from user
</select>
</mapper>
II. 在UserMapper接口中添加方法
public interface UserMapper {
Integer getUserCount();
}
III. 編寫測試方法
public class UserMapperTest {
// 單例工廠
private SqlSessionFactory factory;
@Before
public void init() throws IOException {
// 1. 創(chuàng)建SqlSessionFactoryBuilder對(duì)象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 2. 加載配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 創(chuàng)建SqlSessionFactory對(duì)象
factory = builder.build(inputStream);
}
@Test
public void testGetUserCount(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
int count = mapper.getUserCount();
System.out.println("共有 " + count + "條記錄");
session.close();
}
}
IV. 打印結(jié)果:
2). 輸出pojo對(duì)象
<insert id="addUser" parameterType="com.mazaiting.po.User">
<selectKey keyProperty="id" resultType="int" order="AFTER">
select LAST_INSERT_ID()
</selectKey>
insert into user (username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
</insert>
3). 輸出pojo列表
<select id="getUserByName" parameterType="string" resultType="com.mazaiting.po.User">
select * from user where username like '%${value}%'
</select>
4). 當(dāng)pojo中屬性名和數(shù)據(jù)庫中字段名不相同時(shí)
I. 在com.mazaiting.po包下創(chuàng)建Order.java
public class Order {
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
@Override
public String toString() {
return "Order [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
+ ", note=" + note + "]";
}
}
II. 在com.mazaiting.mapper包下創(chuàng)建接口OrderMapper
public interface OrderMapper {
}
III. 在com.mazaiting.mapper包下創(chuàng)建OrderMapper.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.mazaiting.mapper.OrderMapper">
<select id="getOrderList" resultType="order">
select * from order
</select>
</mapper>
IV. 在OrderMapper接口中添加方法
public interface OrderMapper {
List<Order> getOrderList();
}
V. 編寫測試方法
public class OrderMapperTest {
SqlSessionFactory factory;
@Before
public void init() throws IOException {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = builder.build(inputStream);
}
@Test
public void testGetOrderList() {
SqlSession session = factory.openSession();
OrderMapper mapper = session.getMapper(OrderMapper.class);
List<Order> list = mapper.getOrderList();
for (Order order : list) {
System.out.println(order);
}
session.close();
}
}
VI. 打印結(jié)果
可以看到userId讀取出來為null,原因 數(shù)據(jù)庫表中的字段名為user_id.
5). 獲取userId解決辦法1
將OrderMapper.xml文件中的
<select id="getOrderList" resultType="order">
select * from order
</select>
修改為
<select id="getOrderList" resultType="order">
select id,user_id userId,number,createtime,note from orders
</select>
執(zhí)行測試方法瓢宦,打印結(jié)果:
6). 獲取userId解決辦法2-- resultMap
resultMap可以指定pojo將查詢結(jié)果映射為pojo蟆盹,但需要pojo的屬性名和sql查詢的列名一致方可映射成功垦垂。如果sql查詢字段名和pojo的屬性名不一致痹升,可以通過resultMap將字段名和屬性名作一個(gè)對(duì)應(yīng)關(guān)系 阿迈,resultMap實(shí)質(zhì)上還需要將查詢結(jié)果映射到pojo對(duì)象中攻谁。
resultMap可以實(shí)現(xiàn)將查詢結(jié)果映射為復(fù)雜類型的pojo稚伍,比如在查詢結(jié)果映射對(duì)象中包括pojo和list實(shí)現(xiàn)一對(duì)一查詢和一對(duì)多查詢。
- type:指resultMap要映射成的數(shù)據(jù)類型(返回結(jié)果映射的pojo戚宦,可以使用別名)个曙。
- <id />:此屬性表示查詢結(jié)果集的唯一標(biāo)識(shí),非常重要受楼。如果是多個(gè)字段為復(fù)合唯一約束則定義多個(gè)<id />困檩。
- property:表示Orders類的屬性。
- column:表示sql查詢出來的字段名那槽。
column和property放在一塊兒表示將sql查詢出來的字段映射到指定的pojo類屬性上悼沿。 - <result />:普通列使用result標(biāo)簽映射。
解決辦法:
將OrderMapper.xml文件中的
<select id="getOrderList" resultType="order">
select * from order
</select>
修改為
<resultMap type="order" id="order_list_result_map">
<!-- id是主鍵的映射骚灸,其中property是pojo中主鍵的屬性糟趾,column是返回主鍵的列 -->
<id property="id" column="id"/>
<!-- 普通列使用result映射 -->
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</resultMap>
<!-- 使用resultMap方式 -->
<select id="getOrderList" resultMap="order_list_result_map">
select * from orders
</select>
執(zhí)行測試并打印:
6. 動(dòng)態(tài)SQL
1). if標(biāo)簽
I. 在UserMapper.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.mazaiting.mapper.UserMapper">
<select id="findUserList" parameterType="user" resultType="user">
select * from user
where 1=1
<if test="id!=null">
and id = #{id}
</if>
<if test="username!=null and username !=''">
and username like '%${username}%'
</if>
</select>
</mapper>
注意:
- username要做不等于空字符串的校驗(yàn)。
- User類中id屬性的類型要改為Integer包裝類型义郑,因?yàn)閕nt類型的id是不可能為null的蝶柿!
II. 在UserMapper中添加方法
public interface UserMapper {
List<User> findUserList(User user);
}
III. 測試方法
public class UserMapperTest {
// 單例工廠
private SqlSessionFactory factory;
@Before
public void init() throws IOException {
// 1. 創(chuàng)建SqlSessionFactoryBuilder對(duì)象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 2. 加載配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 創(chuàng)建SqlSessionFactory對(duì)象
factory = builder.build(inputStream);
}
@Test
public void testFindUserList(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
User user = new User();
user.setId(10);
List<User> list = mapper.findUserList(user);
for (User nUser : list) {
System.out.println(nUser);
}
session.close();
}
}
IV. 執(zhí)行測試方法,打印結(jié)果:
2). where標(biāo)簽
可將上個(gè)例子中的UserMapper.xml文件中
<select id="findUserList" parameterType="user" resultType="user">
select * from user
where 1=1
<if test="id!=null">
and id = #{id}
</if>
<if test="username!=null and username !=''">
and username like '%${username}%'
</if>
</select>
修改為:
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null">
and id = #{id}
</if>
<if test="username!=null and username !=''">
and username like '%${username}%'
</if>
</where>
</select>
執(zhí)行測試代碼,打印結(jié)果:
3). foreach
I. 在QueryVo類中添加id列表屬性
public class QueryVo {
private User user;
private List<Integer> ids;
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
public void setIds(List<Integer> ids) {
this.ids = ids;
}
public List<Integer> getIds() {
return ids;
}
}
II. 在UserMapper.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.mazaiting.mapper.UserMapper">
<!-- 動(dòng)態(tài)sql foreach測試 -->
<select id="findUserByIds" parameterType="queryvo" resultType="user">
select * from user
<where>
<!-- and id in(1,10,20,21,31)
collection 遍歷的集合
item 條目
open 循環(huán)之前的內(nèi)容
close 循環(huán)之后的內(nèi)容
separator 分隔符
-->
<foreach collection="ids" item="id" open="and id in(" close=")" separator=",">
#{id}
</foreach>
</where>
</select>
</mapper>
III. 在UserMapper接口中添加方法
public interface UserMapper {
List<User> findUserByIds(QueryVo queryVo);
}
IV. 測試方法
public class UserMapperTest {
// 單例工廠
private SqlSessionFactory factory;
@Before
public void init() throws IOException {
// 1. 創(chuàng)建SqlSessionFactoryBuilder對(duì)象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 2. 加載配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 創(chuàng)建SqlSessionFactory對(duì)象
factory = builder.build(inputStream);
}
@Test
public void testFindUserByIds(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
QueryVo queryVo = new QueryVo();
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(10);
list.add(16);
list.add(22);
queryVo.setIds(list);
List<User> userList = mapper.findUserByIds(queryVo);
for (User user : userList) {
System.out.println(user);
}
session.close();
}
}
V. 測試方法打印結(jié)果:
4). sql片段
sql中可將重復(fù)的sql提取出來非驮,使用時(shí)用include引用即可交汤,最終達(dá)到sql重用的目的
將下面的select方法使用sql片段:
<select id="findUserList" parameterType="user" resultType="user">
select * from user
<where>
<if test="id!=null">
and id = #{id}
</if>
<if test="username!=null and username !=''">
and username like '%${username}%'
</if>
</where>
</select>
修改為:
<!-- 查詢字段 -->
<sql id="user_field_list">
id,username,birthday,sex,address
</sql>
<!-- 抽取where條件 -->
<sql id="find_user_list_where">
<where>
<if test="id!=null">
and id = #{id}
</if>
<if test="username!=null and username !=''">
and username like '%${username}%'
</if>
</where>
</sql>
<select id="findUserList" parameterType="user" resultType="user">
select <include refid="user_field_list"/> from user
<include refid="find_user_list_where"/>
</select>
5).注意:如果引用其它mapper.xml映射文件的sql片段,則在引用時(shí)需要加上namespace劫笙,如下:
<include refid="namespace.sql片段id"/>
7. 一對(duì)一關(guān)聯(lián)映射
1). 一對(duì)一查詢--方法一
I. 創(chuàng)建OrderUser類芙扎,并繼承Order類
public class OrderUser extends Order{
private String username;
private String address;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "OrderUser [username=" + username + ", address=" + address + ", getId()=" + getId() + ", getUserId()="
+ getUserId() + ", getNumber()=" + getNumber() + ", getCreatetime()=" + getCreatetime() + ", getNote()="
+ getNote();
}
}
II. 在OrderMapper.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.mazaiting.mapper.OrderMapper">
<select id="getOrderUserList" resultType="orderuser">
select
o.id,
o.user_id userId,
o.number,
o.createtime,
o.note,
u.username,
u.address
from
orders o
left join user u on o.user_id = u.id
</select>
</mapper>
III. 在OrderMapper中添加方法
public interface OrderMapper {
List<OrderUser> getOrderUserList();
}
IV. 測試方法
public class OrderMapperTest {
SqlSessionFactory factory;
@Before
public void init() throws IOException {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = builder.build(inputStream);
}
@Test
public void testGetOrderUserList(){
SqlSession session = factory.openSession();
OrderMapper mapper = session.getMapper(OrderMapper.class);
List<OrderUser> list = mapper.getOrderUserList();
for (OrderUser orderUser : list) {
System.out.println(orderUser.toString());
}
session.close();
}
}
V. 打印結(jié)果:
注意:定義專門的po類作為輸出類型,其中定義了sql查詢結(jié)果集所有的字段填大。此方法較為簡單戒洼,企業(yè)中使用普遍。
2). 一對(duì)一查詢--方法二
使用resultMap允华,定義專門的resultMap用于映射一對(duì)一查詢結(jié)果圈浇。首先在Order類中加入user屬性,user屬性中用于存儲(chǔ)關(guān)聯(lián)查詢的用戶信息靴寂,因?yàn)橛唵侮P(guān)聯(lián)查詢用戶是一對(duì)一關(guān)系磷蜀,所以這里使用單個(gè)User對(duì)象存儲(chǔ)關(guān)聯(lián)查詢的用戶信息。
I. 修改Order類:
public class Order {
private Integer id;
private Integer userId;
private String number;
private Date createtime;
private String note;
private User user;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public Integer getUserId() {
return userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getNumber() {
return number;
}
public void setNumber(String number) {
this.number = number;
}
public Date getCreatetime() {
return createtime;
}
public void setCreatetime(Date createtime) {
this.createtime = createtime;
}
public String getNote() {
return note;
}
public void setNote(String note) {
this.note = note;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Order [id=" + id + ", userId=" + userId + ", number=" + number + ", createtime=" + createtime
+ ", note=" + note + ", user=" + user + "]";
}
}
II. 在OrderMapper.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.mazaiting.mapper.OrderMapper">
<resultMap type="order" id="order_user_resultmap">
<id property="id" column="id"/>
<result property="userId" column="user_id"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
<!-- 配置一對(duì)一關(guān)聯(lián)映射 -->
<association property="user" javaType="com.mazaiting.po.User">
<id property="id" column="user_id"/>
<result property="username" column="username"/>
<result property="address" column="address"/>
</association>
</resultMap>
<select id="getOrderUserResultMap" resultMap="order_user_resultmap">
select
o.id,
o.user_id,
o.number,
o.createtime,
o.note,
u.username,
u.address
from
orders o
left join user u on o.user_id = u.id
</select>
</mapper>
- association:表示進(jìn)行關(guān)聯(lián)查詢單條記錄百炬。
- property:表示關(guān)聯(lián)查詢的結(jié)果存儲(chǔ)在com.mazaiting.po.Order的user屬性中蠕搜。即property對(duì)應(yīng)Orders類里面一對(duì)一關(guān)聯(lián)映射的那個(gè)屬性,即user屬性收壕。
- javaType:表示關(guān)聯(lián)查詢的結(jié)果類型妓灌。即user屬性的數(shù)據(jù)類型,可使用別名蜜宪。
-
<id property="id" column="user_id"/>
:查詢結(jié)果的user_id列對(duì)應(yīng)關(guān)聯(lián)對(duì)象的id屬性虫埂,這里是<id />表示user_id是關(guān)聯(lián)查詢對(duì)象的唯一標(biāo)識(shí)。 -
<result property="username" column="username"/>
:查詢結(jié)果的username列對(duì)應(yīng)關(guān)聯(lián)對(duì)象的username屬性圃验。
III. 在OrderMapper接口中完成方法
public interface OrderMapper {
List<Order> getOrderUserResultMap();
}
IV. 測試方法
public class OrderMapperTest {
SqlSessionFactory factory;
@Before
public void init() throws IOException {
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
factory = builder.build(inputStream);
}
@Test
public void testGetOrderUserResultMap(){
SqlSession session = factory.openSession();
OrderMapper mapper = session.getMapper(OrderMapper.class);
List<Order> list = mapper.getOrderUserResultMap();
for (Order order : list) {
System.out.println(order.toString());
}
session.close();
}
}
V. 打印結(jié)果:
總結(jié):使用association完成關(guān)聯(lián)查詢掉伏,將關(guān)聯(lián)查詢信息映射到pojo對(duì)象中。
3). 一對(duì)多關(guān)聯(lián)映射
I. 在User類中加入List<Orders> orders屬性
public class User {
// id
private int id;
// 用戶名
private String username;
// 性別
private String sex;
// 用戶名
private Date birthday;
// 地址
private String address;
private List<Order> orders;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public List<Order> getOrders() {
return orders;
}
public void setOrders(List<Order> orders) {
this.orders = orders;
}
@Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
+ address + ", orders=" + orders + "]";
}
}
II. 在UserMapper.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.mazaiting.mapper.UserMapper">
<resultMap type="user" id="user_order_resultmap">
<id property="id" column="id"/>
<result property="username" column="username"/>
<result property="birthday" column="birthday"/>
<result property="sex" column="sex"/>
<result property="address" column="address"/>
<!-- 配置一對(duì)多映射 -->
<collection property="orders" ofType="order">
<id property="id" column="oid"/>
<result property="number" column="number"/>
<result property="createtime" column="createtime"/>
<result property="note" column="note"/>
</collection>
</resultMap>
<select id="getUserWithOrders" resultMap="user_order_resultmap">
select
u.id,
u.username,
u.birthday,
u.sex,
u.address,
o.id oid,
o.number,
o.createtime,
o.note
from
user u
left join orders o on u.id = o.user_id
</select>
</mapper>
- collection部分定義了用戶關(guān)聯(lián)的訂單信息澳窑。表示關(guān)聯(lián)查詢結(jié)果集斧散。
- property=”orders”:關(guān)聯(lián)查詢的結(jié)果集存儲(chǔ)在User對(duì)象的哪個(gè)屬性上。即property對(duì)應(yīng)User對(duì)象中的集合屬性摊聋。
- ofType=”order”:指定關(guān)聯(lián)查詢的結(jié)果集中的對(duì)象類型即List中的對(duì)象類型鸡捐。此處可以使用別名,也可以使用全限定名麻裁。
- <id />及<result/>的意義同一對(duì)一查詢箍镜。
III. 在UserMapper接口中添加方法
public interface UserMapper {
List<User> getUserWithOrders();
}
IV. 測試方法
public class UserMapperTest {
// 單例工廠
private SqlSessionFactory factory;
@Before
public void init() throws IOException {
// 1. 創(chuàng)建SqlSessionFactoryBuilder對(duì)象
SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder();
// 2. 加載配置文件
InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
// 3. 創(chuàng)建SqlSessionFactory對(duì)象
factory = builder.build(inputStream);
}
@Test
public void testGetUserWithOrders(){
SqlSession session = factory.openSession();
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> list =mapper.getUserWithOrders();
for (User user : list) {
System.out.println(user.toString());
}
session.close();
}
}
V. 執(zhí)行測試源祈,打印結(jié)果: