【MyBatis框架】Mybatis开发dao方法第二部分

简介:
下面来继续讨论mybatis开发Dao的方法

我们前面使用原始的Dao开发方法,发现了许多弊端,我们下面使用mapper代理来写Dao方法。

1.mapper代理方法(程序员只需要mapper接口(相当 于dao接口))

开发人员需要先编写Mapper接口(相当 于dao接口),需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。
package cn.edu.hpu.mybatis.mapper;

import cn.edu.hpu.mybatis.PO.User;

//用户管理的Dao接口
public interface UserMapper {
	
	//根据Id查询用户信息
	public User findUserById(int id) throws Exception;
	
	//添加用户信息
	public void insertUser(User user) throws Exception;
	
	//删除用户信息
	public void deleteUser(int id) throws Exception;
	
	//修改用户信息
	public void updateUser(User user) throws Exception;


	//根据姓名查找用户
	public List<User> findUserByUserName(String username) throws Exception;
}

开发人员还要编写mapper.xml映射文件

我们在src同文件夹下的config文件夹下创建mapper包,在包下创建UserMapper.xml文件,内容同之前写过的User.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进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用,就是对应的mapper接口地址 -->
<mapper namespace="cn.edu.hpu.mybatis.mapper.UserMapper">
	<!-- 在映射文件中配置很多sql语句 -->
	
	<!-- 需求:通过id查询用户表的记录 -->
	<!-- 通过select执行数据库查询,
	     id:标示映射文件中的sql,成为Statement的id 
	     将sql语句封装到mappedStatement对象中,所以将id称为statement的id,
	     
	     parameterType:指定输入参数的类型,
	     
	     #{}标示一个占位符,
	     
	     #{id}其中id表示接收输入参数的名称,如果输入参数是简单类型,那么#{}中的值可以任意(如value)。
	     
	     resultType:指定sql输出结果的映射的java对象类型,
	     select指定resultType表示将单条记录映射成java对象-->	
	<select id="findUserById" parameterType="int" resultType="cn.edu.hpu.mybatis.PO.User">
	  SELECT * FROM USER WHERE id=#{id}
	</select>
	
	<!-- ${}:表示拼接sql串,将接收到的参数内容不加任何修饰拼接在sql中。
		 使用${}拼接sql,引起sql注入。
		 ${}中只能使用value-->
	<select id="findUserByUserName" parameterType="java.lang.String" 
			resultType="cn.edu.hpu.mybatis.PO.User">
	   select * from user where username like '%${value}%' 
	</select>
	
	<!-- 添加用户
	parameterType:指定输入参数类型是pojo(包括用户信息) 
	#{}中指定POJO的属性名,接收到POJO对象的属性值,mybatis通过OGNL获取对象的属性
	-->
	<insert id="insertUser" parameterType="cn.edu.hpu.mybatis.PO.User">
		<!-- 将插入数据的主键返回,返回到user对象中。
		SELECT_INSERT_ID():得到刚insert进去的主键值,只适用于自增主键 
		KeyProperty:将查询到主键值设置到parameterType指定对象的哪个属性。
		order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
		-->
		<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
			SELECT LAST_INSERT_ID()
		</selectKey>
		
		<!-- 使用MySql的UUID来生成主键
		执行过程:
		首先通过uuid()得到主键,将主键设置到user对象的id属性中
		其次在insert执行时,从user对象中取出id属性值 
		<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
			SELECT uuid()
		</selectKey>
		insert into user(id,birthday,sex,address) value(#{id},#{birthday,jdbcType=DATE},#{sex},#{address})-->
		
		insert into user(username,birthday,sex,address) value(#{username},#{birthday,jdbcType=DATE},#{sex},#{address})
	</insert>
	
	<!-- 删除用户 -->
	<delete id="deleteUser" parameterType="java.lang.Integer">
		delete from user where id=#{id}
	</delete>
	
	<!-- 更新用户 
	分析:
	需要传入用户的id,需要传入用户的更新信息.
	parameterType指定user对象,包括id和更新信息(注意:id必须存在)
	#{id}:从输入user对象中获取id属性值-->
	<update id="updateUser" parameterType="cn.edu.hpu.mybatis.PO.User">
		update user set username=#{username},birthday=#{birthday,jdbcType=DATE},sex=#{sex},address=#{address} 
		where id=#{id}
	</update>
</mapper>

别忘记在SqlMapConfig.xml中加载映射文件
<!-- 加载映射文件 -->
<mappers>
	<mapper resource="mapper/UserMapper.xml"/>
</mappers>

开发规范:
A、在mapper.xml中namespace等于mapper接口地址
!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用,就是对应的mapper接口地址 -->
<mapper namespace="cn.edu.hpu.mybatis.mapper.UserMapper">
......
</mapper>

B、mapper.java接口中的方法名和mapper.xml中statement的id一致
public findUserById()
对应
<select id="findUserByUsername" ...

C、mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。
public findUserById(int id)
对应
<select id="findUserById" parameterType="int" 

D、mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。
public User findUserById(int id)
对应
<select id="findUserById" parameterType="int" resultType="cn.edu.hpu.mybatis.PO.User">

遵循这些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

总结:
以上开发规范主要是对下边的代码进行统一生成:
User user=sqlSession.selectOne("test.findUserById",id);
sqlSession.insert("test.insertUser",user);

mapper.java与mapper.xml互联互助

接下来我们直接根据接口来测试:
package cn.edu.hpu.mybatis.test;

import java.io.InputStream;

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.Before;
import org.junit.Test;


import cn.edu.hpu.mybatis.PO.User;
import cn.edu.hpu.mybatis.mapper.UserMapper;


public class UserMapperTest {


	private SqlSessionFactory sqlSessionFactory;
	
	//注解Before是在执行本类所有测试方法之前先调用这个方法
	@Before
	public void setup() throws Exception{
		//创建SqlSessionFactory
		String resource="SqlMapConfig.xml";
		
		//将配置文件加载成流
		InputStream inputStream = Resources.getResourceAsStream(resource);
		//创建会话工厂,传入mybatis配置文件的信息
		sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
	}
	
	@Test
	public void testFindUserById() throws Exception{
		
		SqlSession sqlSession=sqlSessionFactory.openSession();
		
		//创建UserMapper代理对象
		UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
		
		//调用userMapper的方法
		User user=userMapper.findUserById(1);
		
		System.out.println(user.getUsername());
	}
}

测试testFindUserById()方法,结果:张三

输出日志信息:
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 14069849.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@d6b059]
DEBUG [main] - ==>  Preparing: SELECT * FROM USER WHERE id=? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1

这里我们使用mapper代理的方法,不需要方法的实现体就完成了查找方法,是不是很轻松?

其他增删改写的方法与上面差不多,但是,当我们实现利用姓名模糊查询的时候,返回的是List集合的数据,我们要注意:
2.一些问题总结
2.1代理对象内部调用selectOne或selectList

如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库。

如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库。

这些是MyBatis内部自动执行的,是不是很方便?我们可以测试一下是不是这样:
测试方法:
@Test
	public void testFindUserByUserName() throws Exception{
		
		SqlSession sqlSession=sqlSessionFactory.openSession();
		
		//创建UserMapper代理对象
		UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
		
		//调用userMapper的方法
		List<User> users=userMapper.findUserByName("张三");
		
		for (int i = 0; i < users.size(); i++) {
			User user=(User)users.get(i);
			System.out.println(user.getId()+":"+user.getUsername());
		}
	}
测试结果:
1:张三
4:张三丰

输出日志:
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 1668655.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.Connection@19762f]
DEBUG [main] - ==>  Preparing: select * from user where username like '%张三%' 
DEBUG [main] - ==> Parameters: 
DEBUG [main] - <==      Total: 2

测试成功,说明MyBatis内部确实是这么做的

我们发现,mapper接口中的参数好像只有一个,Mybatis内部好像也只能自动处理一个参数的mapper方法,那么mapper接口方法参数只能有一个是否影响系统开发?

问:mapper接口方法参数只能有一个,系统是否不利于扩展维护。

答:
系统 框架中,dao层的代码是被业务层公用的。
即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

注意:持久层方法的参数可以包装类型、map。。。,service方法中建议不要使用包装类型(不利于业务层的可扩展)。


转载请注明出处:http://blog.csdn.net/acmman/article/details/46488843

相关文章
|
10天前
|
Java 数据库连接 Spring
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
文章是关于Spring、SpringMVC、Mybatis三个后端框架的超详细入门教程,包括基础知识讲解、代码案例及SSM框架整合的实战应用,旨在帮助读者全面理解并掌握这些框架的使用。
后端框架入门超详细 三部曲 Spring 、SpringMVC、Mybatis、SSM框架整合案例 【爆肝整理五万字】
|
2天前
|
SQL Java 数据库连接
Spring Boot联手MyBatis,打造开发利器:从入门到精通,实战教程带你飞越编程高峰!
【8月更文挑战第29天】Spring Boot与MyBatis分别是Java快速开发和持久层框架的优秀代表。本文通过整合Spring Boot与MyBatis,展示了如何在项目中添加相关依赖、配置数据源及MyBatis,并通过实战示例介绍了实体类、Mapper接口及Controller的创建过程。通过本文,你将学会如何利用这两款工具提高开发效率,实现数据的增删查改等复杂操作,为实际项目开发提供有力支持。
28 0
|
10天前
|
SQL Java 数据库连接
【Java 第十三篇章】MyBatis 框架介绍
MyBatis 原名 iBATIS,2001 年由 Clinton Begin 创建,以其简易灵活著称。2010 年更名以重塑品牌形象。MyBatis 通过 SQL 映射文件将 SQL 语句与 Java 代码分离,支持编写原生 SQL 并与方法映射。具备对象关系映射功能,简化数据库记录处理。支持动态 SQL 构建,灵活应对不同查询条件。内置缓存机制,提升查询效率。相比全功能 ORM,MyBatis 提供更高 SQL 控制度和更好的维护性,并易于与 Spring 等框架集成,广泛应用于 Java 数据访问层。
9 0
|
16天前
|
druid Java 数据库连接
SpringBoot项目整合MybatisPlus持久层框架+Druid数据库连接池,以及实现增删改查功能
SpringBoot项目整合MybatisPlus和Druid数据库连接池,实现基本的增删改查功能。
82 0
|
16天前
|
SQL Java 数据库连接
后端框架的学习----mybatis框架(5、分页)
这篇文章介绍了如何在MyBatis框架中实现分页功能,包括使用SQL的`limit`语句进行分页和利用MyBatis的`RowBounds`对象进行分页的方法。
|
16天前
|
SQL Java 数据库连接
后端框架的学习----mybatis框架(7、使用注解开发)
这篇文章讲述了如何使用MyBatis框架的注解方式进行开发,包括在接口上使用注解定义SQL语句,并通过动态代理实现对数据库的增删改查操作,同时强调了接口需要在核心配置文件中注册绑定。
|
1天前
|
Java 数据库连接 测试技术
SpringBoot 3.3.2 + ShardingSphere 5.5 + Mybatis-plus:轻松搞定数据加解密,支持字段级!
【8月更文挑战第30天】在数据驱动的时代,数据的安全性显得尤为重要。特别是在涉及用户隐私或敏感信息的应用中,如何确保数据在存储和传输过程中的安全性成为了开发者必须面对的问题。今天,我们将围绕SpringBoot 3.3.2、ShardingSphere 5.5以及Mybatis-plus的组合,探讨如何轻松实现数据的字段级加解密,为数据安全保驾护航。
12 1
|
10天前
|
Web App开发 前端开发 关系型数据库
基于SpringBoot+Vue+Redis+Mybatis的商城购物系统 【系统实现+系统源码+答辩PPT】
这篇文章介绍了一个基于SpringBoot+Vue+Redis+Mybatis技术栈开发的商城购物系统,包括系统功能、页面展示、前后端项目结构和核心代码,以及如何获取系统源码和答辩PPT的方法。
|
15天前
|
Java 关系型数据库 MySQL
1、Mybatis-Plus 创建SpringBoot项目
这篇文章是关于如何创建一个SpringBoot项目,包括在`pom.xml`文件中引入依赖、在`application.yml`文件中配置数据库连接,以及加入日志功能的详细步骤和示例代码。
|
16天前
|
数据库
elementUi使用dialog的进行信息的添加、删除表格数据时进行信息提示。删除或者添加成功的信息提示(SpringBoot+Vue+MybatisPlus)
这篇文章介绍了如何在基于SpringBoot+Vue+MybatisPlus的项目中使用elementUI的dialog组件进行用户信息的添加和删除操作,包括弹窗表单的设置、信息提交、数据库操作以及删除前的信息提示和确认。
elementUi使用dialog的进行信息的添加、删除表格数据时进行信息提示。删除或者添加成功的信息提示(SpringBoot+Vue+MybatisPlus)