mybatis教程--原始方式和mapper方式開發dao詳解
阿新 • • 發佈:2019-02-05
mybatis開發dao的兩種方式
一、原始的dao開發方式
所謂的原始的dao的開發方式,其實就是和hibernate的開發方式類似的,需要dao的介面和dao的實現類,這個就是原始的開發方式,而mybatis的開發方式在後面將介紹。
1.1、建立po類user.java
package com.sihai.mybatis.po; import java.util.Date; /** * @author sihai */ public class User { private int id; private String username;// 使用者姓名 private String sex;// 性別 private Date birthday;// 生日 private String address;// 地址 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; } @Override public String toString() { return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address=" + address + "]"; } }
1.2、建立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">
<!-- namespace名稱空間,為了對sql語句進行隔離,方便管理 ,mapper開發dao方式,使用namespace有特殊作用
mapper代理開發時將namespace指定為mapper介面的全限定名
-->
<mapper namespace="com.sihai .mybatis.mapper.UserMapper">
<!-- 在mapper.xml檔案中配置很多的sql語句,執行每個sql語句時,封裝為MappedStatement物件
mapper.xml以statement為單位管理sql語句
-->
<!-- 將使用者查詢條件定義為sql片段
建議對單表的查詢條件單獨抽取sql片段,提高公用性
注意:不要將where標籤放在sql片段
-->
<sql id="query_user_where">
<!-- 如果 userQueryVo中傳入查詢條件,再進行sql拼接-->
<!-- test中userCustom.username表示從userQueryVo讀取屬性值-->
<if test="userCustom!=null">
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
<if test="userCustom.sex!=null and userCustom.sex!=''">
and sex = #{userCustom.sex}
</if>
<!-- 根據id集合查詢使用者資訊 -->
<!-- 最終拼接的效果:
SELECT id ,username ,birthday FROM USER WHERE username LIKE '%小明%' AND id IN (16,22,25)
collection:集合的屬性
open:開始迴圈拼接的串
close:結束迴圈拼接的串
item:每次迴圈取到的物件
separator:每兩次迴圈中間拼接的串
-->
<foreach collection="ids" open=" AND id IN ( " close=")" item="id" separator=",">
#{id}
</foreach>
<!--
SELECT id ,username ,birthday FROM USER WHERE username LIKE '%小明%' AND (id = 16 OR id = 22 OR id = 25)
<foreach collection="ids" open=" AND ( " close=")" item="id" separator="OR">
id = #{id}
</foreach>
-->
<!-- 還有很的查詢條件 -->
</if>
</sql>
<!-- 定義resultMap,列名和屬性名對映配置
id:mapper.xml中的唯一標識
type:最終要對映的pojo型別
-->
<resultMap id="userListResultMap" type="user" >
<!-- 列名
id_,username_,birthday_
id:要對映結果集的唯 一標識 ,稱為主鍵
column:結果集的列名
property:type指定的哪個屬性中
-->
<id column="id_" property="id"/>
<!-- result就是普通列的對映配置 -->
<result column="username_" property="username"/>
<result column="birthday_" property="birthday"/>
</resultMap>
<!-- 根據id查詢使用者資訊 -->
<!--
id:唯一標識 一個statement
#{}:表示 一個佔位符,如果#{}中傳入簡單型別的引數,#{}中的名稱隨意
parameterType:輸入 引數的型別,通過#{}接收parameterType輸入 的引數
resultType:輸出結果 型別,不管返回是多條還是單條,指定單條記錄對映的pojo型別
-->
<select id="findUserById" parameterType="int" resultType="user">
SELECT * FROM USER WHERE id= #{id}
</select>
<!-- 根據使用者名稱稱查詢使用者資訊,可能返回多條
${}:表示sql的拼接,通過${}接收引數,將引數的內容不加任何修飾拼接在sql中。
-->
<select id="findUserByName" parameterType="java.lang.String" resultType="com.sihai .mybatis.po.User">
select * from user where username like '%${value}%'
</select>
<!-- 自定義查詢條件查詢使用者的資訊
parameterType:指定包裝型別
%${userCustom.username}%:userCustom是userQueryVo中的屬性,通過OGNL獲取屬性的值
-->
<select id="findUserList" parameterType="userQueryVo" resultType="user">
select id,username,birthday from user
<!-- where標籤相當 於where關鍵字,可以自動去除第一個and -->
<where>
<!-- 引用sql片段,如果sql片段和引用處不在同一個mapper必須前邊加namespace -->
<include refid="query_user_where"></include>
<!-- 下邊還有很其它的條件 -->
<!-- <include refid="其它的sql片段"></include> -->
</where>
</select>
<!-- 使用resultMap作結果對映
resultMap:如果引用resultMap的位置和resultMap的定義在同一個mapper.xml,
直接使用resultMap的id,如果不在同一個mapper.xml要在resultMap的id前邊加namespace
-->
<select id="findUserListResultMap" parameterType="userQueryVo" resultMap="userListResultMap">
select id id_,username username_,birthday birthday_ from user where username like '%${userCustom.username}%'
</select>
<!-- 輸出簡單型別
功能:自定義查詢條件,返回查詢記錄個數,通常用於實現 查詢分頁
-->
<select id="findUserCount" parameterType="userQueryVo" resultType="int">
select count(*) from user
<!-- where標籤相當 於where關鍵字,可以自動去除第一個and -->
<where>
<!-- 引用sql片段,如果sql片段和引用處不在同一個mapper必須前邊加namespace -->
<include refid="query_user_where"></include>
<!-- 下邊還有很其它的條件 -->
<!-- <include refid="其它的sql片段"></include> -->
</where>
</select>
<!-- 新增使用者
parameterType:輸入 引數的型別,User物件 包括 username,birthday,sex,address
#{}接收pojo資料,可以使用OGNL解析出pojo的屬性值
#{username}表示從parameterType中獲取pojo的屬性值
selectKey:用於進行主鍵返回,定義了獲取主鍵值的sql
order:設定selectKey中sql執行的順序,相對於insert語句來說
keyProperty:將主鍵值設定到哪個屬性
resultType:select LAST_INSERT_ID()的結果 型別
-->
<insert id="insertUser" parameterType="com.sihai.mybatis.po.User">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select LAST_INSERT_ID()
</selectKey>
INSERT INTO USER(username,birthday,sex,address) VALUES(#{username},#{birthday},#{sex},#{address})
</insert>
<!-- mysql的uuid生成主鍵 -->
<!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User">
<selectKey keyProperty="id" order="BEFORE" resultType="string">
select uuid()
</selectKey>
INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert> -->
<!-- oracle
在執行insert之前執行select 序列.nextval() from dual取出序列最大值,將值設定到user物件 的id屬性
-->
<!-- <insert id="insertUser" parameterType="com.sihai.mybatis.po.User">
<selectKey keyProperty="id" order="BEFORE" resultType="int">
select 序列.nextval() from dual
</selectKey>
INSERT INTO USER(id,username,birthday,sex,address) VALUES(#{id},#{username},#{birthday},#{sex},#{address})
</insert> -->
<!-- 使用者刪除 -->
<delete id="deleteUser" parameterType="int">
delete from user where id=#{id}
</delete>
<!-- 使用者更新
要求:傳入的user物件中包括 id屬性值
-->
<update id="updateUser" parameterType="com.sihai.mybatis.po.User">
update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
</update>
</mapper>
接下來,我們需要建立dao了,因為我們使用的是原始的方式,所以需要有dao和dao的實現類
1.3、建立userDao.java
package com.sihai.mybatis.dao;
import java.util.List;
import com.sihai.mybatis.po.User;
/**
* @author sihai
*/
public interface UserDao {
//根據id查詢使用者資訊
public User findUserById(int id) throws Exception;
//根據使用者名稱稱模糊查詢使用者列表
public List<User> findUserByUsername(String username) throws Exception;
//插入使用者
public void insertUser(User user) throws Exception;
}
1.4、建立userDaoImpl.java
package com.sihai.mybatis.dao;
import java.util.List;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import com.sihai.mybatis.po.User;
public class UserDaoImpl implements UserDao {
private SqlSessionFactory sqlSessionFactory;
// 將SqlSessionFactory注入
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(int id) throws Exception {
// 建立SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
// 根據id查詢使用者資訊
User user = sqlSession.selectOne("test.findUserById", id);
sqlSession.close();
return user;
}
@Override
public List<User> findUserByUsername(String username) throws Exception {
// 建立SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
List<User> list = sqlSession.selectList("test.findUserByName", username);
sqlSession.close();
return list;
}
@Override
public void insertUser(User user) throws Exception {
// 建立SqlSession
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
sqlSession.commit();
sqlSession.close();
}
}
至此,我們就已經實現了原始的dao的開發的方式,看看是不是和hibernate十分的相似呢,都是需要一個配置檔案來對映資料庫的。接下來,我將介紹一下
mapper代理方式來實現dao的編寫。
二、mapper代理方式
mapper代理方式這是在mybatis中特有的一種方式,就是隻要符合他的編碼規範,這樣你就可以你需要按照他的編碼規範編寫dao介面就行,不需要編寫dao的實現類,這樣是不是很爽。
說明一點,我們還是使用上面的user.java和userMapper.xml來講解。
我們還是先把程式碼亮出來把,然後再來介紹需要符合的編碼規範。
2.1、建立UserMapper.java
mapper類的命名一般是用 po類名+Mapper 命名。
package com.sihai.mybatis.mapper;
import java.util.List;
import com.sihai.mybatis.po.User;
import com.sihai.mybatis.po.UserQueryVo;
/**
* @author sihai
*/
public interface UserMapper {
//根據使用者id查詢使用者資訊
public User findUserById(int id) throws Exception;
//根據使用者名稱稱 查詢使用者資訊
public List<User> findUserByName(String username) throws Exception;
//自定義查詢條件查詢使用者資訊
public List<User> findUserList(UserQueryVo userQueryVo) throws Exception;
//查詢使用者,使用resultMap進行對映
public List<User> findUserListResultMap(UserQueryVo userQueryVo)throws Exception;
//查詢使用者,返回記錄個數
public int findUserCount(UserQueryVo userQueryVo) throws Exception;
//插入使用者
public void insertUser(User user)throws Exception;
//刪除使用者
public void deleteUser(int id) throws Exception;
//修改使用者
public void updateUser(User user) throws Exception;
}
對比上面的UserMapper.xml和UserMapper.java不難發現,我們需要符合以下的一些規範。
2.2、mapper代理方式的編碼規範
1、dao中的方法的返回值和mapper配置檔案中的resultType保持一致
2、dao中的方法的方法名和mapper配置檔案中的id保持一致
3、dao中的方法的引數和mapper配置檔案中的parameterType保持一致
4、mapper.xml中namespace是mapper介面的全限定名