目录
一、简介
1.1、什么是代理模式
代理模式是一种结构型设计模式,它的概念很简单,它通过创建一个代理对象来控制对原始对象的访问。代理模式主要涉及两个角色:代理角色和真实角色。代理类负责代理真实类,为真实类提供控制访问的功能,真实类则完成具体的业务逻辑。这样,当我们不方便或者不能直接访问真实对象时,可以通过代理对象来间接访问。使用代理模式主要有两个目的:一是保护目标对象,二是增强目标对象。
1.2、代理模式的作用
为了保护核心类,扩充功能,利于代码的扩展。
1.3、代理模式的分类
代理模式分为两类:动态代理和静态代理。
1.4、动态代理和静态代理的特点
动态代理:
优点
动态代理中的目标类很多的时候代理类的数量可以很少。
修改接口的方法的时候不会影响到代理类。
代理类可以自动帮助我们生成无需手动。
静态代理:
优点
简单、效率高、容易理解。缺点
当目标类增多,代理类也需要增加。
当接口方法增加或修改的时候,很多类都需要修改,因为目标类和代理类都实现了相同的接口。
1.5、动态代理与静态代理的区别
- 静态代理一定要编写至少一个被代理类与一个代理类,而动态代理可以不编写任何被代理类与代理类
- 静态代理编写麻烦,因为代理类与被代理类需要实现同一个接口,如果接口有100个方法,那么就需要实现100个方法,而动态代理不需要,动态代理底层使用反射极大减少了开发量,将100个方法压缩成一个invoke方法即可。
1.6、动态代理方式
接下来将对动态代理进行详细的介绍。
开发规范:
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的类型相同。
Mapper.xml(映射文件)
定义mapper映射文件UserMapper.xml(内容同Users.xml),需要修改namespace的值为 UserMapper接口路径。将UserMapper.xml放在mapper目录 下。
<?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.org.mapper.UserMapper"> <!--通过id查询用户--> <select id="findUserByID" parameterType="int" resultType="com.org.domain.User"> SELECT * from USER WHERE id = #{id}; </select> <!--查询用户--> <select id="findUserAll" resultType="com.org.domain.User"> SELECT * FROM USER ; </select> <!--通过名字查询用户(模糊查询)--> <select id="findUserLikeName" parameterType="String" resultType="com.org.domain.User"> SELECT * from user where username like "${value}%"; </select> <!--添加用户--> <insert id="addUser" parameterType="com.org.domain.User"> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> SELECT last_insert_id() </selectKey> INSERT INTO USER (username,password,gender,address) VALUES (#{username},#{password},#{gender},#{address}); </insert> <!--统计用户人数--> <select id="findUserCount" resultType="int"> SELECT count(*) from USER ; </select> </mapper>
接口:
package com.org.mapper; import com.org.domain.User; import java.util.List; public interface UserMapper { public User findUserByID(int id); public List<User> findUserAll(); public List<User> findUserLikeName(String username); public int addUser(User user); public int findUserCount(); }
测试类
public class Test01 { SqlSessionFactory ssf; @Before public void before(){ InputStream in = null; try { in = Resources.getResourceAsStream("SqlMapConfig.xml"); } catch (IOException e) { e.printStackTrace(); } ssf = new SqlSessionFactoryBuilder().build(in); } //查询所有老师 @Test public void test12(){ SqlSession sqlSession = ssf.openSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class); List<Teacher> teachers = mapper.findTeacherAll(); for (Teacher teacher : teachers) { System.out.println(teacher.getTid()+","+teacher.getTname()+","+teacher.getGender()+","+teacher.getAge()); } } //查询用户个数 @Test public void test11(){ SqlSession sqlSession = ssf.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); int userCount = mapper.findUserCount(); System.out.println(userCount); } //添加用户 @Test public void test10(){ SqlSession sqlSession = ssf.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = new User("lisi","123","男","成都"); mapper.addUser(user); sqlSession.commit(); System.out.println(user.getId()); sqlSession.close(); } //根据名字查询用户(模糊查询) @Test public void test09(){ SqlSession sqlSession = ssf.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> users = mapper.findUserLikeName("li"); for (User user : users) { System.out.println(user.getId()+","+user.getUsername()); } } //查询所有用户 @Test public void test08(){ SqlSession sqlSession = ssf.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); List<User> users = mapper.findUserAll(); for (User user : users) { System.out.println(user.getId()+","+user.getUsername()); } } //根据id查询用户 @Test public void test07(){ SqlSession sqlSession = ssf.openSession(); UserMapper mapper = sqlSession.getMapper(UserMapper.class); User user = mapper.findUserByID(27); System.out.println(user.getId()+","+user.getUsername()); } }
selectOne和selectList
动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据mapper接口方法的返回值决定,如果返回list则调用selectList方法,如果返回单个对象则调用selectOne方法。
namespace
mybatis官方推荐使用mapper代理方法开发mapper接口,程序员不用编写mapper接口实现类,使用mapper代理方法时,输入参数可以使用pojo包装对象或map对象,保证dao的通用性。