mapper代理(十一)

 

  原始 dao开发问题

1dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量。

2、调用sqlsession方法时将statementid硬编码了

3、调用sqlsession方法时传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误(传入的是泛型类),在编译阶段也不报错,不利于程序员开发。

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

 思路(mapper代理开发规范):

Mapper代理开发避免了原始的dao接口开发中实现类的很多重复代码,让程序员减轻了工作量

Sql语句的删除、更新、添加操作要进行会话的提交才会生效

程序员还需要编写mapper.xml映射文件

程序员编写mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象。

开发规范:

1、在mapper.xmlnamespace等于mapper接口地址

2、mapper.java接口中的方法名和mapper.xmlstatementid一致

(使用mapper代理对象,mybatis会自动根据接口地址和命名空间去查找相对应的statementid)

3mapper.java接口中的方法输入参数类型和mapper.xmlstatementparameterType指定的类型一致。

4mapper.java接口中的方法返回值类型和mapper.xmlstatementresultType指定的类型一致。

 

 代理对象内部调用selectOneselectList

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

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

 

 mapper接口方法参数只能有一个是否影响系统 开发

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

系统 框架中,dao层的代码是被业务层公用的。

即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

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

 

eclipse项目的结构

 

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">
<!-- namespace命名空间,作用就死对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要的作用(刚开始学还不能理解) -->
<mapper namespace="ql.mybatis.mapper.UserMapper">
    <!-- 在映射文件中配置很多sql语句-->
    <!-- 需求:通过id查询用户表的记录 -->
    <!-- 通过select 执行数据库的查询
    id:标识映射文件的sql
    将sql语句封装到mappedStatement对象中,所以将id称为statement的id
    parameterType:指定输入参数的类型,这里指定int型
    #{}表示一个占位符
    #{id}:其中的id表示接受输入的参数,参数名称就是id,如果输入的参数是简单类型,#{}中的参数可以任意
    resultType:指定sql输出的结果的所映射的java对象类型,select指定restultType表示将单条记录映射成java对象
    -->
    <select id="findUserById" parameterType="int" resultType="ql.mybatis.pojo.User">
        select * from User where id=#{id}
    </select>
    
    <select id="findUserById2" parameterType="ql.mybatis.pojo.User" resultType="ql.mybatis.pojo.User">
        select * from User where sex=#{sex} and address=#{address} 
    </select>
    
    <!-- 根据用户名称模糊查询用户信息,可能返回多条
    resultType:指定就是单条记录所映射的java对象 类型
    ${}:表示拼接sql串,将接收到参数的内容不加任何修饰拼接在sql中。
    使用${}拼接sql,引起 sql注入
    ${value}:接收输入 参数的内容,如果传入类型是简单类型,${}中只能使用value
     -->
    <select id="findUserByName" parameterType="String" resultType="ql.mybatis.pojo.User">
        SELECT * FROM USER WHERE username LIKE '%${value}%'
    </select>

    <!-- 添加用户 
    parameterType:指定输入 参数类型是pojo(包括 用户信息)
    #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值
    -->
    <insert id="insertUser" parameterType="ql.mybatis.pojo.User">
        insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
    </insert>
    
    <!-- 删除用户 -->
    <delete id="deleteUser" parameterType="java.lang.Integer">
     delete from user where id=#{id}
    </delete>
    
    <!-- 更新用户
    必须指定id,否则将会将表的内容全部更新
     -->
    <update id="updateUser" parameterType="ql.mybatis.pojo.User">
    update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}
    </update>
</mapper>

 

UserMapper接口:

package ql.mybatis.mapper;

import java.util.List;

import ql.mybatis.pojo.User;

public interface UserMapper {

    public User findUserById(int id) throws Exception;
    public List<User> findUserByName(String name) throws Exception;
    public User findUserById2(User user) throws Exception;
    public void insertUser(User user) throws Exception;
    public void deleteUser(int id) throws Exception;
}

 

单元测试类:

 

package ql.mybatis.test;

import java.io.InputStream;
import java.util.Date;
import java.util.List;

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 ql.mybatis.mapper.UserMapper;
import ql.mybatis.pojo.User;

public class UserMapperTest {

    SqlSession sqlSession = null;

    @Before
    public void setUp() throws Exception {
        // mybatis配置文件
        String resource = "SqlMapConfig.xml";
        // 得到配置文件流
        InputStream inputStream = Resources.getResourceAsStream(resource);
        // 创建会话工厂,传入mybatis的配置文件信息
        SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder()
                .build(inputStream);
        sqlSession = sqlSessionFactory.openSession();
    }

    @Test
    public void testFindUserById() throws Exception {

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = userMapper.findUserById(22);
        System.out.println(user);

    }

    @Test
    public void testFindUserByName() throws Exception {
        // 得到代理对象,接口回调
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        List<User> list = userMapper.findUserByName("小明");
        System.out.println(list);
    }

    @Test
    public void testInsertUser() throws Exception {

        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user = new User();
        user.setSex("1");
        user.setAddress("北京市");
        user.setBirthday(new Date());
        user.setUsername("王大东");
        userMapper.insertUser(user);
        sqlSession.commit();

    }

    @Test
    public void testDeleteUser() throws Exception {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        userMapper.deleteUser(10);
        sqlSession.commit();
    }
    @Test
    public void testFindUserById2() throws Exception {
        UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
        User user=new User();
        user.setSex("1");
        user.setAddress("福建福州");
        User user2=userMapper.findUserById2(user);
        System.out.println(user2);
    }

}

 还应在配置文件中SqlMapConfig.xml加上:

<mapper resource="mapper/UserMapper.xml"/>

 

可以看到并没有写UserMapper接口的实现类,mybatis帮我们生成了一个Mapper代理对象

 

posted @ 2015-05-26 12:52  加肥猫咪  阅读(449)  评论(0编辑  收藏  举报