Mybatis中@Mapper与@MapperScan配置及注入原理解析

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis中@Mapper与@MapperScan配置及注入原理解析相关的知识,希望对你有一定的参考价值。

参考技术A 问题背景:

执行流程:
1.发现Bean定义:首先根据@MapperScan中的basePackage或者@Mapper所在的package取得需要扫描的包,之后通过ClassPathMapperScaner获取包下所有Mapper接口类的BeanDefinition;
2.注册Bean:设置beanClass为MapperFactoryBean,再设置MapperFactoryBean的构造参数为实际的Mapper接口类,然后通过ClassPathBeanDefinitionScanner父类进行Bean注册
3.调用Bean:自动注入时,通过调用MapperFactoryBean的getObject获取实例

原理解析:

Mybatis框架中Mapper动态代理方式

开发规范:

mapper接口开发方法只需要程序猿编写mapper接口(相当于Dao接口),
由Mybatis框架根据接口定义创建接口的动态代理对象,
代理对象的方法体跟Dao接口实现类方法相同。

Mapper接口开发需要遵循以下规范:
1.Mapper.xml文件中namespace与mapper接口的路径相同。
2.Mapper接口方法和Mapper.xml中定义的每个statement的id相同。
3.Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的parameterType的类型相同。
4.Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同。

一、创建项目并导包:

技术分享图片                                   技术分享图片

二、代码实现:

1.创建工具类:

package com.zsq.Utils;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class Utils {
	
	/*
	 * 原始方法获得数据库连接对象
	 */
	public static Connection getConnection() throws SQLException, ClassNotFoundException{
		
		String driver = "com.mysql.jdbc.Driver";
		
		String url = "jdbc:mysql://localhost:3306/zengsiqi";
		
		String username = "root";
		
		String userpass = "123456";
		
		Class.forName(driver);
		
		Connection  con = DriverManager.getConnection(url, username, userpass);
		
		return con;
	}	
	
	/*
	 * mybatis操作数据库获得session的静态方法
	 */
	public static SqlSession getSqlSession() throws IOException{
		
		String config = "mybatis-config.xml";
		
		InputStream configStream = Resources.getResourceAsStream(config);
		
		SqlSessionFactoryBuilder buider = new SqlSessionFactoryBuilder();
		
		SqlSessionFactory factory = buider.build(configStream);
		
		SqlSession session = factory.openSession();
		
		return session;
	}
}

  2.搭建mybatis-config.xml文件

  复制代码

<?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"/> -->
	<environments default="development">
		<environment id="development">
			<transactionManager type="JDBC"/>
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver"/>
				<property name="url" value="jdbc:mysql://localhost:3306/zengsiqi"/>
				<property name="username" value="root"/>
				<property name="password" value="123456"/>
			</dataSource>
		</environment>
	</environments>
	<mappers>
		<mapper resource="com/zsq/sqlmap/MyInfoMapper.xml"/>
	</mappers>
</configuration>

  3.创建beans类:

package com.zsq.beans;

import java.util.Date;
/*
 * javaBean类:
 */
public class MyInfo {
	
	private int id;
	
	private String myname;
	
	private String sex;
	
	private int age;
	
	private String email;
	
	private String address;
	
	private Date brith;

	public int getId() {
		return id;
	}

	public void setId(int id) {
		this.id = id;
	}

	public String getMyname() {
		return myname;
	}

	public void setMyname(String myname) {
		this.myname = myname;
	}

	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public int getAge() {
		return age;
	}

	public void setAge(int age) {
		this.age = age;
	}

	public String getEmail() {
		return email;
	}

	public void setEmail(String email) {
		this.email = email;
	}

	public String getAddress() {
		return address;
	}

	public void setAddress(String address) {
		this.address = address;
	}

	public Date getBrith() {
		return brith;
	}

	public void setBrith(Date brith) {
		this.brith = brith;
	}

	public MyInfo() {
	}

	public MyInfo(int id, String myname, String sex, int age, String email,
			String address, Date brith) {
		this.id = id;
		this.myname = myname;
		this.sex = sex;
		this.age = age;
		this.email = email;
		this.address = address;
		this.brith = brith;
	}

	@Override
	public String toString() {
		return "MyInfo [id=" + id + ", myname=" + myname + ", sex=" + sex
				+ ", age=" + age + ", email=" + email + ", address=" + address
				+ ", brith=" + brith + "]";
	}
}

  注意:类的属性、属性名与表的字段类型、字段名是一一对应的:

技术分享图片

                                                       技术分享图片

      4.写sql语句的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.zsq.mapper.MyInfoMapper">

	<!-- 插入一行数据 -->
	<insert id="insert1" >
		insert into myinfo (id,myname,sex,age,email,address,brith) values 
		(default,‘杨云飞‘,‘男‘,26,‘[email protected]‘,‘河南‘,‘1992-5-6‘)
	</insert>
	
	<!-- 根据id查询 -->
	<select id="selectById" parameterType="Integer" resultType="com.zsq.beans.MyInfo">
		select * from myinfo where id = #{id}
	</select>
	
	<!-- 全查 -->
	<select id="selectAll" resultType="com.zsq.beans.MyInfo">
		select * from myinfo order by id desc
	</select>
	
	<!-- 模糊查询  根据姓名查 -->
	<select id="findMyName" parameterType="String" resultType="com.zsq.beans.MyInfo">
		select * from MyInfo where myname like "%"#{haha}"%"
	</select>
	
	<!-- 根据id更新部门字段内容 -->
	<update id="updateById" parameterType="int">
		update myinfo set age = 99 where id=#{id}
	</update>
	
	<!-- 根据地址 修改信息 -->
	<update id="updateById2" parameterType="String">
		update myinfo set id = 7,myname = "曾志伟" where address = #{address}
	</update>
	
	<!-- 根据id跟新  参数传 一个对象 -->
	<update id="updayeMyInfoById" parameterType="com.zsq.beans.MyInfo" >
		update myinfo set myname = #{myname},age = #{age}, sex = #{sex},email = #{email},address = #{address},
		brith = #{brith} where id = #{id}
	</update>
	
	<!-- 删除用户  根据id删除 -->
	<delete id="delById" parameterType="int" >
		delete from myinfo where id = #{id}
	</delete>
	
</mapper>

  5.mapper接口:

package com.zsq.mapper;

import java.util.Date;
import java.util.List;

import com.zsq.beans.MyInfo;
//实现动态代理:只写接口  ,实现类由动态代理生成
public interface MyInfoMapper {
	/*
	 *  重点:必须遵循四个原则
	 *  1>方法名 == myInfo.xml 中的 id名
	 *	2> 返回值类型与MyIndoMapper.xml文件中的返回值类型要一致
	 *	3>方法的入参类型要与MyInfoMapper.xml中入参的类型一致
	 *	4>命名空间 绑定此接口
	 */

	//插入一行数据  及内容是写死的
	public int insert1();
	//根据id查询 方法
	public MyInfo selectById(int id);
	//全查 方法
	public List<MyInfo> selectAll();
	//模糊查询  根据myname查的方法
	public MyInfo findMyName(String myname);
	//根据id更新部门字段内容的方法
	public int updateById(int id);
	//根据地址 修改信息的方法
	public int updateById2(String address);
	//根据id跟新  参数传 一个对象的方法
	public int updayeMyInfoById(MyInfo user);
	//删除用户  根据id删除 的方法
	public int delById(int id);
}

  6.test类:

package com.zsq.test;

import java.util.Date;
import java.util.List;
import org.junit.Test;
import com.zsq.Utils.Utils;
import com.zsq.beans.MyInfo;
import com.zsq.mapper.MyInfoMapper;
import org.apache.ibatis.session.SqlSession;

public class MyInfoMapperTest {
	
	@Test
	public void Test1() throws Exception {
		//获得session
		SqlSession session = Utils.getSqlSession();
		/*
		 * 1>session帮我生成一个实现类
		 * 2>返回的还是接口,然后再调方法
		 */
		MyInfoMapper info = session.getMapper(MyInfoMapper.class);
		
		/*	插入一行数据 
	        int i = info.insert1();
		System.out.println(i);*/
		
		/*  根据id查询
		MyInfo selectById = info.selectById(5);
		System.out.println(selectById);*/
		
		/*	全查
	        List<MyInfo> all = info.selectAll();
		for (MyInfo myInfo : all) {
			System.out.println(myInfo);
		}*/
		
		/*  模糊查询  根据姓名查
		MyInfo info2 = info.findMyName("云");
		System.out.println(info2);
		System.out.println(info2.getMyname());*/
		
		/*  根据id更新部门字段内容
		int id = info.updateById(3333);
		System.out.println(id);*/
		
		/*  根据地址 修改信息
		int id2 = info.updateById2("莲花乡");
		System.out.println(id2);*/
		
	        /*  根据id跟新  参数传 一个对象
	        MyInfo user = new MyInfo();
		user.setId(3350);
		user.setMyname("曾志伟 ");
		user.setSex("女");
		user.setAge(2323);
		user.setEmail("[email protected]");
		user.setAddress("西城");
		user.setBrith(new Date());
		int t1 = info.updayeMyInfoById(user);		
		System.out.println(t1);*/
		
		//删除用户  根据id删除
		int t1 = info.delById(3353);
		System.out.println(t1);//id为3353的删除
		
		session.commit();
		session.close();
	}
}

  

  

 







以上是关于Mybatis中@Mapper与@MapperScan配置及注入原理解析的主要内容,如果未能解决你的问题,请参考以下文章

mybatis源码学习与spring整合Mapper接口执行原理

MyBatis mapper文件中的变量引用方式#{}与${}的差别

MyBatis mapper文件中的变量引用方式#{}与${}的差别

Mybatis中@Mapper与@MapperScan配置及注入原理解析

Mybatis框架中Mapper动态代理方式

MyBatis的操作与配置文件