从零开始学Mybatis(五)——Mapper动态代理

  • 原始Dao开发方法
  1. 创建Mapping文件
<?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="Test2">
    <!--根据id查找用户-->
    <select id="queryCustomerById" parameterType="Integer" resultType="demo2.Customer">
        SELECT * FROM customer WHERE cust_id=#{cust_id}
    </select>
    <!--查询所有用户-->
    <select id="queryAll" resultType="demo2.Customer">
        SELECT * FROM  customer;
    </select>
    <!--根据用户名模糊查询用户-->
    <select id="queryByName" resultType="demo2.Customer" parameterType="String">
        SELECT * FROM customer WHERE cust_name LIKE #{cust_name}
    </select>
    <!--添加用户-->
    <insert id="addCustomer" parameterType="demo2.Customer">
        <!--返回新增加记录的主键-->
        <selectKey keyColumn="cust_id" keyProperty="cust_id" order="AFTER" resultType="Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT  INTO customer (cust_name,cust_profession,cust_phone,email) VALUES
        (#{cust_name},#{cust_profession},#{cust_phone},#{email})
    </insert>
    <!--更新用户-->
    <update id="updateeCustomerById" parameterType="demo2.Customer">
        UPDATE customer SET cust_name=#{cust_name}where cust_id=#{cust_id}
    </update>
    <!--删除用户-->
    <delete id="deleteById" parameterType="Integer">
        DELETE FROM customer WHERE cust_id=#{cust_id}
    </delete>
</mapper>
  1. 将Mapping加载到SqlMappingConfig中
<?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>
    <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/development"/>
                <property name="username" value="root"/>
                <property name="password" value="123456"/>
            </dataSource>
        </environment>
    </environments>
    <!--加载映射文件-->
    <mappers>

        <mapper resource="demo2/Mapping"/>
    </mappers>
</configuration>
  1. 创建customer表的ORM映射POJO类
@Setter@Getter
public class Customer {
    private Integer cust_id;
    private String cust_name;
    private String cust_profession;
    private String cust_phone;
    private String email;

    @Override
    public String toString() {
        return "Customer{" +
                "cust_id=" + cust_id +
                ", cust_name='" + cust_name + '\'' +
                ", cust_profession='" + cust_profession + '\'' +
                ", cust_phone='" + cust_phone + '\'' +
                ", email='" + email + '\'' +
                '}';
    }
}
  1. 创建Dao接口
public interface CustomerDao {
    //添加用户
    public void save(Customer customer);
    // 查询用户
    public Customer query(Integer id);
    // 更新用户
    public void update(Customer customer);
    // 删除用户
    public void delete(Integer id);
}
  1. 实现Dao接口
public class CustomerDaoImpl implements CustomerDao {
    private SqlSessionFactory sqlSessionFactory;
    public CustomerDaoImpl(SqlSessionFactory sqlSessionFactory){
        this.sqlSessionFactory=sqlSessionFactory;
    }
    @Override
    public void save(Customer customer) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.insert("addCustomer", customer);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public Customer query(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        Customer customer = sqlSession.selectOne("queryCustomerById", id);
        sqlSession.close();
        return customer;
    }

    @Override
    public void update(Customer customer) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.update("updateeCustomerById",customer);
        sqlSession.commit();
        sqlSession.close();
    }

    @Override
    public void delete(Integer id) {
        SqlSession sqlSession = sqlSessionFactory.openSession();
        sqlSession.delete("deleteById",id);
        sqlSession.commit();
        sqlSession.close();
    }
}
  1. 编写测试类
public class test {
    private SqlSessionFactory sqlSessionFactory;
    public void init() throws IOException {
        //1、创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //2、加载SqlMappingConfig配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMappingConfig");
        //3、创建sqlSessionFactory对象
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }
    @Test
    public void test() throws IOException {
        this.init();
        CustomerDaoImpl customerDaoImpl = new CustomerDaoImpl(this.sqlSessionFactory);
//        Customer customer = new Customer();
//        customer.setCust_name("刘雷");
//        customer.setCust_phone("142635276");
//        customer.setCust_profession("教授");
//        customer.setEmail("12@abn.com");
        // 测试保存
//        customerDaoImpl.save(customer);
        //测试更新
//        Customer customer1 = new Customer();
//        customer1.setCust_name("刘大雷");
//        customer1.setCust_phone("142636");
//        customer1.setCust_profession("教");
//        customer1.setEmail("12@abn.com");
//        customer1.setCust_id(13);
//        customerDaoImpl.update(customer1);
        // 测试查询
//        Customer customer2 = customerDaoImpl.query(13);
//        System.out.println(customer2);
        // 测试删除
        customerDaoImpl.delete(13);
        System.out.println("ok");

    }
}
  • Mapper动态代理

使用Mapper动态代理开发Dao需要满足以下要求

  1. Mapping中的namespace必须与Mapper接口类路径一致
  2. Mapping中的id必须和Mapper接口方法名一致
  3. Mapping中的parameterType必须和Mapper接口方法参数类型一致
  4. Mapping中的resultType必须和Mapper接口方法返回值类型一致

实现步骤

  1. 编写Mapping配置文件
<?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="demo2.CustomerMapper">
    <!--根据id查找用户-->
    <select id="queryCustomerById" parameterType="Integer" resultType="demo2.Customer">
        SELECT * FROM customer WHERE cust_id=#{cust_id}
    </select>
    <!--查询所有用户-->
    <select id="queryAll" resultType="demo2.Customer">
        SELECT * FROM  customer;
    </select>
    <!--根据用户名模糊查询用户-->
    <select id="queryByName" resultType="demo2.Customer" parameterType="String">
        SELECT * FROM customer WHERE cust_name LIKE #{cust_name}
    </select>
    <!--添加用户-->
    <insert id="addCustomer" parameterType="demo2.Customer">
        <!--返回新增加记录的主键-->
        <selectKey keyColumn="cust_id" keyProperty="cust_id" order="AFTER" resultType="Integer">
            SELECT LAST_INSERT_ID()
        </selectKey>
        INSERT  INTO customer (cust_name,cust_profession,cust_phone,email) VALUES
        (#{cust_name},#{cust_profession},#{cust_phone},#{email})
    </insert>
    <!--更新用户-->
    <update id="updateeCustomerById" parameterType="demo2.Customer">
        UPDATE customer SET cust_name=#{cust_name}where cust_id=#{cust_id}
    </update>
    <!--删除用户-->
    <delete id="deleteById" parameterType="Integer">
        DELETE FROM customer WHERE cust_id=#{cust_id}
    </delete>
</mapper>
  1. 编写Mapper接口
package demo2;
import java.util.List;


public interface CustomerMapper {
   public Customer queryCustomerById(Integer id);
   public List<Customer> queryAll();
   public Customer queryByName(String name);
   public void addCustomer(Customer customer);
   public void updateeCustomerById(Customer customer);
   public void deleteById(Integer id);
}
  1. 编写测试类
public class test {
    private SqlSessionFactory sqlSessionFactory;
    public void init() throws IOException {
        //1、创建SqlSessionFactoryBuilder对象
        SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
        //2、加载SqlMappingConfig配置文件
        InputStream inputStream = Resources.getResourceAsStream("SqlMappingConfig");
        //3、创建sqlSessionFactory对象
        sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
    }
  @Test
public void test1() throws IOException {
    this.init();
    //1、创建sqlSession对象
    SqlSession sqlSession = sqlSessionFactory.openSession();
    //2、加载Mapper接口
    CustomerMapper mapper = sqlSession.getMapper(CustomerMapper.class);
    //3、调用Mapper中的方法执行sql
    Customer customer = mapper.queryCustomerById(5);
    System.out.println(customer);
    //4、关闭连接,释放资源
    // 如果有对数据库进行操作,则需要提交事务
    // sqlSession.commit();
    sqlSession.close();
}

}

说明:selectOne和selectList

动态代理对象调用sqlSession.selectOne()和sqlSession.selectList()是根据Mapper接口方法的返回值决定的,如果返回List则调用selectList()方法,如果返回单个对象或者简单类型则调用selectOne()方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis Mapper 实现动态代理的调用思路: 1. 定义 Mapper 接口,该接口可以通过注解或 XML 文件的方式定义 SQL 语句和参数映射关系。 2. 使用 MyBatisMapperFactory 创建 MapperProxyFactory 对象,该对象用于创建 Mapper 接口的代理对象。 3. 创建 MapperProxy 对象,该对象实现了 InvocationHandler 接口,用于处理代理对象方法的调用。 4. 通过 MapperProxyFactory 对象的 newInstance 方法创建 Mapper 接口的代理对象,该对象会被传入 MapperProxy 对象的构造函数中。 5. 通过代理对象调用 Mapper 接口的方法时,会被 MapperProxy 对象的 invoke 方法拦截,该方法会根据方法名和参数类型动态生成 SQL 语句,并通过 MyBatis 的 SqlSession 执行 SQL 语句。 下面是使用 Java 代码实现 MyBatis Mapper 动态代理的调用过程: 1. 定义 Mapper 接口 ```java public interface UserMapper { @Select("SELECT * FROM users WHERE id = #{id}") User getUserById(int id); } ``` 2. 创建 MapperProxyFactory 对象 ```java public class MapperFactory { private final Configuration configuration; public MapperFactory(Configuration configuration) { this.configuration = configuration; } public <T> T getMapper(Class<T> mapperInterface) { return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[]{mapperInterface}, new MapperProxy(configuration, mapperInterface)); } } ``` 3. 创建 MapperProxy 对象 ```java public class MapperProxy<T> implements InvocationHandler { private final SqlSession sqlSession; private final Class<T> mapperInterface; public MapperProxy(Configuration configuration, Class<T> mapperInterface) { this.sqlSession = new SqlSessionFactoryBuilder().build(configuration).openSession(); this.mapperInterface = mapperInterface; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { String statement = mapperInterface.getName() + "." + method.getName(); MappedStatement mappedStatement = sqlSession.getConfiguration().getMappedStatement(statement); if (mappedStatement == null) { throw new RuntimeException("Can't find mapped statement for " + statement); } Object result = null; switch (mappedStatement.getSqlCommandType()) { case SELECT: result = sqlSession.selectOne(statement, args); break; case INSERT: result = sqlSession.insert(statement, args); break; case UPDATE: result = sqlSession.update(statement, args); break; case DELETE: result = sqlSession.delete(statement, args); break; default: throw new RuntimeException("Unknown SqlCommandType " + mappedStatement.getSqlCommandType()); } sqlSession.commit(); return result; } } ``` 4. 创建 Mapper 接口的代理对象 ```java Configuration configuration = new Configuration(); configuration.addMapper(UserMapper.class); MapperFactory mapperFactory = new MapperFactory(configuration); UserMapper userMapper = mapperFactory.getMapper(UserMapper.class); ``` 5. 调用 Mapper 接口的方法 ```java User user = userMapper.getUserById(1); ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值