1. 程式人生 > >mybatis教程--原始方式和mapper方式開發dao詳解

mybatis教程--原始方式和mapper方式開發dao詳解

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.xmlnamespacemapper介面的全限定名