【 MyBatis 的 Dao 编写(mapper 代理方式实现) 】

Mapper代理的开发方式,程序员只需要编写mapper接口(相当于dao接口)即可。Mybatis会自动的为mapper接口生成动态代理实现类。
不过要实现mapper代理的开发方式,需要遵循一些开发规范。

开发规范

1.	mapper接口的全限定名要和mapper映射文件的namespace的值相同。
2.	mapper接口的方法名称要和mapper映射文件中的statement的id相同;
3.	mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
4.	mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致;

通过规范式的开发mapper接口,可以解决原始dao开发当中存在的问题:
- 模板代码已经去掉;
- 剩下去不掉的操作数据库的代码,其实就是一行代码。这行代码中硬编码的部分,通过第一和第二个规范就可以解决。

编写步骤

第一步:重新写个 UserMapper 配置文件和定义 mapper 映射文件UserMapper.xml(内容同Users.xml,除了namespace的值),放到新创建的目录mapper下。

【 MyBatis 的 Dao 编写(mapper 代理方式实现) 】
【 MyBatis 的 Dao 编写(mapper 代理方式实现) 】

package cn.ys.mapper;

import cn.ys.model.User;

public interface UserMapper {

    /**
     *
     * @param user
     * @return 受影响的行数
     */
    public int save(User user);

    public User findUserById(int id);

}

<?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="cn.ys.mapper.UserMapper">

   <insert id="save" parameterType="cn.ys.model.User">
      INSERT INTO user (username,sex,birthday,address)
        VALUE (#{username},#{sex},#{birthday},#{address})
   </insert>

    <select id="findUserById" parameterType="int" resultType="cn.ys.model.User">
        SELECT * FROM user WHERE id = #{id}
    </select>

</mapper>

db.properties

driverClass=com.mysql.jdbc.Driver
url=jdbc:mysql://yangnanxi.cn:3306/mybatis?useUnicode=true&amp;characterEncoding=utf8
name=yang
password=123456

创建 SqlMapConfig.xml

在 classpath(src) 下,创建 SqlMapConfig.xml 文件【SqlMapConfig.xml(文件头可以从mybatis-3.2.7.pdf文档的2.1.2小节中拷贝)】

<?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"/>

    <!-- 配置mybatis的环境信息 -->
    <environments default="development">
        <environment id="development">
            <!-- 配置JDBC事务控制,由mybatis进行管理 -->
            <transactionManager type="JDBC"></transactionManager>
            <!-- 配置数据源,采用dbcp连接池 -->
            <dataSource type="POOLED">
                <property name="driver" value="${driverClass}"/>
                <property name="url" value="${url}"/>
                <property name="username" value="${name}"/>
                <property name="password" value="${password}"/>
            </dataSource>
        </environment>
    </environments>

    <!-- 告诉mybatis加载映射文件 -->
    <mappers>
        <mapper resource="cn/ys/mapper/UserMapper.xml"></mapper>
    </mappers>

</configuration>

测试

package cn.ys.test;

import cn.ys.mapper.UserMapper;
import cn.ys.model.User;
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.After;
import org.junit.Before;
import org.junit.Test;

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

public class Demo04 {

    SqlSession session;
    @Before
    public void before() throws IOException {
        System.out.println("before.....获取session");
//        a)读取配置文件;
        InputStream is = Resources.getResourceAsStream("SqlMapConfig.xml");

        //b)通过SqlSessionFactoryBuilder创建SqlSessionFactory会话工厂。
        SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(is);

        session = sessionFactory.openSession();
    }

    @After
    public void after(){
        session.close();
    }

    @Test
    public void test1() throws IOException {

        UserMapper userMapper =  session.getMapper(UserMapper.class);
        //System.out.println(obj.getClass());

        //获取数据
        System.out.println(userMapper.findUserById(1));


        //保存
        User user2 = new User();
        user2.setUsername("xxx");
        user2.setSex("x");
        user2.setBirthday(new Date());
        user2.setAddress("xx");

        userMapper.save(user2);
        session.commit();

    }
    
}

控制台打印

C:\Java\jdk1.8.0_181\bin\java.exe -ea -Didea.test.cyclic.buffer.size=1048576 "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\lib\idea_rt.jar=63975:C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\lib\idea_rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\plugins\junit\lib\junit-rt.jar;C:\Program Files\JetBrains\IntelliJ IDEA 2018.2.1\plugins\junit\lib\junit5-rt.jar;C:\Java\jdk1.8.0_181\jre\lib\charsets.jar;C:\Java\jdk1.8.0_181\jre\lib\deploy.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\access-bridge-64.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\cldrdata.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\dnsns.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\jaccess.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\jfxrt.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\localedata.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\nashorn.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunec.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunjce_provider.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunmscapi.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\sunpkcs11.jar;C:\Java\jdk1.8.0_181\jre\lib\ext\zipfs.jar;C:\Java\jdk1.8.0_181\jre\lib\javaws.jar;C:\Java\jdk1.8.0_181\jre\lib\jce.jar;C:\Java\jdk1.8.0_181\jre\lib\jfr.jar;C:\Java\jdk1.8.0_181\jre\lib\jfxswt.jar;C:\Java\jdk1.8.0_181\jre\lib\jsse.jar;C:\Java\jdk1.8.0_181\jre\lib\management-agent.jar;C:\Java\jdk1.8.0_181\jre\lib\plugin.jar;C:\Java\jdk1.8.0_181\jre\lib\resources.jar;C:\Java\jdk1.8.0_181\jre\lib\rt.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\out\production\mybatis;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\asm-3.3.1.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\cglib-2.2.2.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\commons-logging-1.1.1.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\javassist-3.17.1-GA.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\junit-4.8.2.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\log4j-1.2.17.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\log4j-api-2.0-rc1.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\log4j-core-2.0-rc1.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\mybatis-3.2.7.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\mysql-connector-java-5.1.7-bin.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\slf4j-api-1.7.5.jar;C:\Users\ys951\Desktop\JavaSETest\JavaEE\mybatis\lib\slf4j-log4j12-1.7.5.jar" com.intellij.rt.execution.junit.JUnitStarter -ideVersion5 -junit4 cn.ys.test.Demo04,test1
before.....获取session
DEBUG [main] - Logging initialized using 'class org.apache.ibatis.logging.slf4j.Slf4jImpl' adapter.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - PooledDataSource forcefully closed/removed all connections.
DEBUG [main] - Opening JDBC Connection
DEBUG [main] - Created connection 157683534.
DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@9660f4e]
DEBUG [main] - ==>  Preparing: SELECT * FROM user WHERE id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - <==      Total: 1
User [id=1, username=王五, sex=2, birthday=null, address=null]
DEBUG [main] - ==>  Preparing: INSERT INTO user (username,sex,birthday,address) VALUE (?,?,?,?) 
DEBUG [main] - ==> Parameters: xxx(String), x(String), 2019-02-28 21:04:14.146(Timestamp), xx(String)
DEBUG [main] - <==    Updates: 1
DEBUG [main] - Committing JDBC Connection [com.mysql.jdbc.JDBC4Connection@9660f4e]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@9660f4e]
DEBUG [main] - Closing JDBC Connection [com.mysql.jdbc.JDBC4Connection@9660f4e]
DEBUG [main] - Returned connection 157683534 to pool.

Process finished with exit code 0