MyBatis2-the realization of Dao layer

Dao layer implementation of MyBatis

Introduction to agent development method**

- 采用Mybatis的代理开发方式实现DAO层的开发,这种方式是我们后面进入企业的主流
- Mybatis接口开发方法只需要程序员编写Mapper接口(相当于Dao接口) , 由Mybatis框架根据接口定义创建接口的动态代理对象
- Mybatis接口开发需要遵循以下规范 : 
   - Mapper.xml文件中的namespace与mapper接口的全限定名相同
   - Mapper接口方法名和Mapper.xml中定义的每个statement的id相同
   - Mapper接口方法的输入参数类型和mapper.xml中定义的每个sql的paramentType的类型相同
   - Mapper接口方法的输出参数类型和mapper.xml中定义的每个sql的resultType的类型相同
Insert picture description here


Code for UserMapper interface:

package mybatis.dao;

import mybatis.domain.User;

import java.io.IOException;
import java.util.List;

public interface UserMapper {
    public List<User> findAll() throws IOException;
    public User findById(int id);
}

Configuration of UserMapping.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">

<mapper namespace="mybatis.dao.UserMapper">
    <delete id="delete" parameterType="java.lang.Integer">
        delete from user where id=#{id}
    </delete>

    <update id="update" parameterType="mybatis.domain.User">
        update user set username=#{username},password=#{password} where id=#{id}
    </update>

    <insert id="save" parameterType="mybatis.domain.User">
        insert into user values(#{id},#{username},#{password})
    </insert>

    <select id="findAll" resultType="mybatis.domain.User">
        select * from user
    </select>

    <select id="findById" resultType="mybatis.domain.User" parameterType="int">
        select * from user where id=#{id}
    </select>
</mapper>

Test code:

import mybatis.dao.UserMapper;
import mybatis.domain.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.Test;

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

public class ServiceDemo {
    @Test
    public void test1() throws IOException {
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        SqlSession sqlSession = build.openSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
        User byId = mapper.findById(4);
        System.out.println(byId);
    }
}

MyBatis mapping file in-depth

Dynamic sql: if

<select id="findByCondition" parameterType="user" resultType="mybatis.domain.User">
        select * from user
        <where>
            <if test="id!=0">
                and id=#{id}
            </if>
            <if test="username!=null">
                and username=#{username}
            </if>
            <if test="password!=null">
                and password=#{password}
            </if>
        </where>
    </select>

Dynamic Sql: foreach:

<select id="findByIds" parameterType="int" resultType="user">
        select * from user
        <where>
            <foreach collection="list" open="id in (" close=")" item="id" separator=",">
                #{id}
            </foreach>
        </where>
    </select>

Extraction of sql fragments:

    <sql id="selectUser">select * from user</sql>
    <select id="findAll" resultType="mybatis.domain.User">
        <include refid="selectUser"/>
    </select>

MyBatis core configuration file in-depth

Common tags for MyBatis core configuration files:

  • properties tag: This tag can load external properties files
  • typeAliases tag: set type aliases
  • environment tag: Data source environment configuration tag
  • typeHandlers tag: configure custom type handlers
  • plugins tag: configure MyBatis plugins
  1. typeHandlers tags
  2. You can rewrite the type processor or create your own type processor to handle unsupported or non-standard types. The specific method is to implement the org.apache.ibatis.type.TypeHandler interface, or inherit a very convenient class org.apache .ibatis.type.BaseTypeHandler, you can then optionally map it to a JDBC type.
  3. Development steps:
  • Define conversion class inheritance class BaseTypeHandler<T>
  • Covers 4 unimplemented methods, among which setNonNullParameter is a callback method for java program to set data to the database, and getNullableResult is a method for converting mysql string type to java Type type when querying.
  • Register in the MyBatis core configuration file
  • Test whether the conversion is correct

Configure the typeHandler tag in sqlMapConfig.xml:

<!--    注册类型转换器-->
    <typeHandlers>
        <typeHandler handler="mybatis.handler.DateTypeHandler"/>
    </typeHandlers>

Customize a conversion class inheriting class org.apache.ibatis.type.BaseTypeHandler:

package mybatis.handler;

import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;

import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Date;

public class DateTypeHandler extends BaseTypeHandler<Date> {
    //将java类型转换成数据库需要的类型
    @Override
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType jdbcType) throws SQLException {
        long time = date.getTime();
        preparedStatement.setLong(i,time);
    }

    //将数据库中的类型转换成java类型
    //String 参数  要转换的字段名称
    //ResultSet 查询出的结果集
    @Override
    public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
        long aLong = resultSet.getLong(s);
        Date date = new Date(aLong);
        return date;
    }

    //将数据库中类型转换成java类型
    @Override
    public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
        long aLong = resultSet.getLong(i);
        Date date = new Date(aLong);
        return date;
    }

    //将数据库中类型 转换成java类型
    @Override
    public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        long aLong = callableStatement.getLong(i);
        Date date = new Date(aLong);
        return date;
    }
}

Test class:

import mybatis.domain.User;
import mybatis.mapper.UserMapper;
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.Test;

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

public class MyBatisTest {

    @Test
    public void test2() throws IOException {
        //获得核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        //获得session工厂对象
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //获得session会话对象
        SqlSession sqlSession = build.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User select = mapper.select(8);
        System.out.println(select.getBirthday());
        //释放资源
        sqlSession.close();
    }

    @Test
    public void test1() throws IOException {
        //获得核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        //获得session工厂对象
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //获得session会话对象
        SqlSession sqlSession = build.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        User user = new User();
        user.setPassword("123");
        user.setUsername("zk");
        user.setBirthday(new Date());
        mapper.insert(user);

        sqlSession.commit();
        //释放资源
        sqlSession.close();
    }

}

  1. plugins tags
  • PageHelper is to encapsulate the complex operations of paging, and you can get the relevant data of the paging in a simple way.
  • Development steps:
  • Import the coordinates of the general PageHelper
  • Configure the PageHelper plugin in the mybatis core configuration file
  • Test paging data acquisition

Jar package configuration in pom.xml:

<dependency>
            <groupId>com.github.pagehelper</groupId>
            <artifactId>pagehelper</artifactId>
            <version>3.7.5</version>
        </dependency>
        <dependency>
            <groupId>com.github.jsqlparser</groupId>
            <artifactId>jsqlparser</artifactId>
            <version>0.9.1</version>
        </dependency>

Configuration in sqlMapContext.xml:

<!--    配置分页助手插件-->
    <plugins>
        <plugin interceptor="com.github.pagehelper.PageHelper">
            <property name="dialect" value="mysql"></property>
        </plugin>
    </plugins>

Test class:

    @Test
    public void test3() throws IOException {
        //获得核心配置文件
        InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
        //获得session工厂对象
        SqlSessionFactory build = new SqlSessionFactoryBuilder().build(resourceAsStream);
        //获得session会话对象
        SqlSession sqlSession = build.openSession();

        UserMapper mapper = sqlSession.getMapper(UserMapper.class);

        //设置分页的相关参数,当前页 每页显示的条数
        PageHelper.startPage(1,3);

        List<User> all = mapper.findAll();
        for(User uk:all){
            System.out.println(uk);
        }

        //获得与分页相关的参数
        PageInfo<User> pageInfo = new PageInfo<User>(all);
        System.out.println("当前页: "+pageInfo.getPageNum());
        System.out.println("每页显示条数:"+pageInfo.getPageSize());
        System.out.println("总条数:"+pageInfo.getTotal());
        System.out.println("总页数:"+pageInfo.getPages());
        System.out.println("上一页:"+pageInfo.getPrePage());
        System.out.println("下一页:"+pageInfo.getNextPage());
        System.out.println("是否是第一个:"+pageInfo.isIsFirstPage());
        System.out.println("是否是最后一个:"+pageInfo.isIsLastPage());
        //释放资源
        sqlSession.close();
    }