Mybatis动态代理和非动态代理的理解

  1. Mybatis动态代理的好处
    传统分层模式,我们在处理业务的时候需要些 dao 层,然后再 写 dao层的实现类
    具体处理业务在 dao 层的实现类中进行处理, 而 mybatis 在配置 实体类的 Mapper文件之后, 只需要写 相当于 dao(Maper接口) 层接口 , mybatis 就会自动生成 dao (Mapper接口) 的实现类,就可以 调用 dao(Mapper实现类) 的接口了

  2. 先来温习一下非动态代理的Mybatis操作:如果有疑问,请看上一篇mybatis的基本入门

  • 数据库的实体bean类,`
package com.puya.mybatis.pojo;

import java.io.Serializable;

public class User implements Serializable {
	private Integer id;
	private String name;
	private String station;
	private String telephone;
	private String address;
	private String decidedzone_id;
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public String getStation() {
		return station;
	}
	public void setStation(String station) {
		this.station = station;
	}
	public String getTelephone() {
		return telephone;
	}
	public void setTelephone(String telephone) {
		this.telephone = telephone;
	}
	public String getAddress() {
		return address;
	}
	public void setAddress(String address) {
		this.address = address;
	}
	public String getDecidedzone_id() {
		return decidedzone_id;
	}
	public void setDecidedzone_id(String decidedzone_id) {
		this.decidedzone_id = decidedzone_id;
	}
	@Override
	public String toString() {
		return "User [id=" + id + ", name=" + name + ", station=" + station + ", telephone=" + telephone + ", address="
				+ address + ", decidedzone_id=" + decidedzone_id + "]";
	}
	

	
}

  • [ ]对应的 Mapper文件 ,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">

<!-- 写sql语句的地方 -->
<mapper namespace="user">
	<!--
		mapper参数详解:
			namespace:命名空间,区分不同的sql,调用的时候使用 user.findUserById
		select 参数详解
			parameterType  : 传入参数的类型,mybatis封装了基本类,只需要写
			resultType     : 返回的数据类型,一般是全类名
	
	  -->

	<select id="findUserById" parameterType="Integer" resultType="com.puya.mybatis.pojo.User">
		select * from t_customer where id = #{v}
	
	</select>
	<!-- 
	#{v}            表示占位符v可以是任何字符           select * from t_customer where id = ?
	${value}        表示字符拼接,只能是value  select * from t_customer where name like '%张三%'  ,有单引号的
					为了防止sql注入  ${value}  可以这样写   select * from t_customer where name like "%"#{value}"%"
	 -->
	<select id="findUserByUserName" parameterType="String" resultType="com.puya.mybatis.pojo.User">
		<!-- select * from t_customer where username like '%${value}%' -->
		select * from t_customer where name like "%"#{value}"%"     <!-- 这个可以防止sql注入  -->
	</select>
	
	<insert id="insertUser" parameterType="com.puya.mybatis.pojo.User">
		<!--private Integer id;
		private String name;
		private String station;
		private String telephone;
		private String address;
		private String decidedzone_id;  -->
		<selectKey keyProperty="id" resultType="Integer" order="AFTER">
			select LAST_INSERT_ID()    <!-- 这个表示执行最新的id 服装到User的id中去-->
		</selectKey>
		insert into t_customer (name,station,telephone,address,decidedzone_id) value(#{name},#{station},#{telephone},#{address},#{decidedzone_id})
	
	</insert>
	
	<update id="updateUserById" parameterType="com.puya.mybatis.pojo.User">
		update t_customer 
		set name=#{name},station=#{station},telephone=#{telephone},address=#{address},decidedzone_id=#{decidedzone_id}
		where id=#{id}
	</update>
	
	<delete id="deleteUserById" parameterType="Integer">
		delete from t_customer where id =#{value}
		
	</delete>



</mapper>

//这次测试只用到了一条sql  ----- findUserById

.

  • 非动态代理的代码逻辑
@Test
	public void testMybatis() throws Exception {
		//加载核心的配置文件
		String path ="sqlMapConfig.xml";
		//读取配置文件获取流
		InputStream in = Resources.getResourceAsStream(path);
		//创建sqlSessionFactory
		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建session
		SqlSession session = sessionFactory.openSession();
		//执行sql语句
		User user = session.selectOne("user.findUserById", 1);
		
		System.out.println(user); 
	}

这个就是非动态代理的主要步骤: 注意键User.xml文件配置在sqlMapConfig,xml文件中去,为了查看方便,贴出sqlMapConfig,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>
	
	<!-- 和spring整合后 environments配置将废除    -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="com.mysql.jdbc.Driver" />
				<property name="url"
					value="jdbc:mysql://localhost:3306/bos_puya32?characterEncoding=utf-8" />
				<property name="username" value="root" />
				<property name="password" value="123456" />
			</dataSource>
		</environment>
	</environments>
	
	<!-- Mapper的位置  Mapper.xml 写Sql语句的文件的位置 -->
	<mappers>
		<mapper resource="com/puya/mybatis/sqlmap/User.xml"/>
		<mapper resource="com/puya/mybatis/sqlmap/UserMapper.xml"/>
	</mappers>
</configuration>

调用 testMybatis() 方法后,就查到了响应的 User 对象,这就是 非动态代理的配置以及全部流程,看上去也不复杂

  1. 接下来讲一下动态代理,动态代理起始就 mybatis 根据接口生成响应的实体类,然后调用方法;所以手下得写一个接口;
    接口书写的四个原则
    |- 接口方法名 == 对应的Mapper.xml 中的id 名字 ,这样就能找到这个sql
    |- 接口中的返回值类型 与 Mapper.xml文件中的返回值一样
    |- 方法的 形参 与Mapper.xml文件中的 形参类型一样
    |- 将Mapper.xml 文件 命名空间 和 接口 捆绑(就是maper.xml文件对应的 名称空间 为 接口的全类名)

  2. 接下来写一个Mapper接口


/**动态代理接口
. */
public interface UserMapper {
	//遵循四个原则
	//接口方法名  == User.xml 中的id 名字
	//接口中的返回值类型   与  Mapper.xml文件中的返回值一样
	//方法的 形参  与Mapper.xml文件中的   形参一样
	//将Mapper.xml 文件  命名空间   和    接口  捆绑
	public User findUserById(Integer id);
	
}
  1. 写一个Mappe.xml文件(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">

<!-- 写sql语句的地方 -->
<mapper namespace="com.puya.mybatis.mapper.UserMapper">
	<!--
		mapper参数详解:
			namespace:命名空间,区分不同的sql,调用的时候使用 user.findUserById
		select 参数详解
			parameterType  : 传入参数的类型,mybatis封装了基本类,只需要写
			resultType     : 返回的数据类型,一般是全类名
	
	  -->

	<select id="findUserById" parameterType="Integer" resultType="com.puya.mybatis.pojo.User">
		select * from t_customer where id = #{v}
	
	</select>
</mapper>

将mapper.xml文件配置到 sqlMapConfig.xml文件中去

<mapper resource="com/puya/mybatis/sqlmap/UserMapper.xml"/>

在 UserMapper文件配置 全类名 的别名

<mapper namespace="com.puya.mybatis.mapper.UserMapper">
  1. 使用方法
	@Test
	public void testMapper() throws Exception {
		String path ="sqlMapConfig.xml";
		//读取配置文件获取流
		InputStream in = Resources.getResourceAsStream(path);
		//创建sqlSessionFactory
		SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(in);
		//创建session
		SqlSession session = sessionFactory.openSession();
		
		//获取动态代理对象
		UserMapper mapper = session.getMapper(UserMapper.class);
		//更加动态代理对象执行sql
		User user = mapper.findUserById(1);
		
		System.out.println(user);
		
	}

以上两种 动态代理 和 非动态代理 获取到的User结果是一样的 ,上面就是 两者的区别,

谢谢

猜你喜欢

转载自blog.csdn.net/puyaCheer_xu/article/details/84999029