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 + "]";
	}
	
	
}
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>

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;

}
 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();
		
	}

}
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;
	
	

}
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接口的全限定名

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello-java-maker

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值