• Spring+SpringMVC+MyBatis深入学习及搭建(二)——MyBatis原始Dao开发和mapper代理开发(转发同上)


    前面有写到Spring+SpringMVC+MyBatis深入学习及搭建(一)——MyBatis的基础知识。MybatisFirst中存在大量重复的代码。这次简化下代码:

    原地址:http://www.cnblogs.com/shanheyongmu/p/7121016.html

    使用MyBatis开发Dao,通常有两种方法,即原始Dao开发方法和Mapper接口开发方法。

    1.SqlSession使用范围

    1.1 SqlsessionFactoryBuilder

    通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory,将SqlSessionFactoryBuilder当成一个工具类使用即可,不需要使用单例管理SqlSessionFactoryBuilder。

    在需要创建SqlSessionFactory时候,只需要new一次SqlSessionFactoryBuilder即可。

    1.2 SqlsessionFactory

    通过SqlSessionFactory创建SqlSession,使用单例模式管理SqlSessionFactory(工厂一旦创建,使用一个实例)。

    将来MyBatis和Spring整合后,使用单例模式管理SqlSessionFactory。

    1.3 SqlSession

    SqlSession是一个面向用户(程序员)的接口。

    SqlSession提供了很多操作数据库的方法,如:selectOne(返回单个对象)、selectList(返回单个或多个对象)。

    SqlSession是线程不安全的,在SqlSession实现类中除了有接口中的方法(操作数据库的方法)还有数据域属性。

    SqlSession最佳应用场合在方法体内,定义成局部变量使用。

    2.原始dao开发方法(程序员需要写dao接口和dao实现类)

    2.1 思路

    程序员需要写dao接口和dao实现类。

    需要向dao的实现类中注入SqlSessionFactory,在方法体内通过SqlSessionFactory创建SqlSession.

    2.2 dao接口

    复制代码
    public interface UserDao {
        //根据id查询用户信息
        public User findUserById(int id) throws Exception;
        //添加用户信息
        public void insertUser(User user) throws Exception;
        //删除用户信息
        public void deleteUser(int id) throws Exception;
    }
    复制代码

    2.3 dao接口实现类

    复制代码
    public class UserDaoImpl implements UserDao{
        //需要向dao实现类中注入SqlSessionFactory
        //这里通过构造方法注入
        private SqlSessionFactory sqlSessionFactory;
        public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
            super();
            this.sqlSessionFactory = sqlSessionFactory;
        }
    
        @Override
        public User findUserById(int id) throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            User user=sqlSession.selectOne("test.findUserById", id);
            //释放资源
            sqlSession.close();
            return user;
        }
    
        @Override
        public void insertUser(User user) throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            sqlSession.insert("test.insertUser", user);
            //提交事务
            sqlSession.commit();
            //释放资源
            sqlSession.close();
        }
    
        @Override
        public void deleteUser(int id) throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            sqlSession.delete("test.deleteUser", id);
            //提交事务
            sqlSession.commit();
            //释放资源
            sqlSession.close();
        }
    }
    复制代码

    2.4 测试代码

    复制代码
    public class UserDaoImplTest {
        private SqlSessionFactory sqlSessionFactory;
        
        @Before
        public void setUp() throws IOException{
            //创建sqlSessionFactory
            //mybatis配置文件
            String resource="SqlMapConfig.xml";
            //得到配置文件流
            InputStream inputStream=Resources.getResourceAsStream(resource);
            //创建会话工厂,传入mybatis的配置文件信息
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        }
        
        @Test
        public void findUserByIdTest() throws Exception{
            UserDao userDao=new UserDaoImpl(sqlSessionFactory);
            User user=userDao.findUserById(1);
            System.out.println(user);
        }
    }
    复制代码

    2.5 总结原始dao开发问题

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

    (2)调用sqlSession方法时将statement的id硬编码了。

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

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

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

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

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

    开发规范:

    (1)在mapper.xml中namespace等于mapper接口地址

    (2)mapper.java接口中的方法名和mapper.xml中statement的id一致

    (3)mapper.java接口中的方法输入参数类型和mapper.xml中statement的parameterType指定的类型一致。

    (4)mapper.java接口中的方法返回值类型和mapper.xml中statement的resultType指定的类型一致。

    总结:

    以上方法开发规范主要是对下边的代码进行统一生成:

    User user = sqlSession.selectOne("test.findUserById", id);
    sqlSession.insert("test.insertUser", user);
    ......

    3.2 mapper.java

    复制代码
    package joanna.yan.mybatis.mapper;
    
    import java.util.List;
    import joanna.yan.mybatis.entity.User;
    /**
     * 相当于dao接口
     * @author Joanna.Yan
     *
     */
    public interface UserMapper {
        //根据id查询用户信息
        public User findUserById(int id) throws Exception;
        //根据名字查询用户
        public List<User> findUserByName(String name) throws Exception;
        //添加用户信息
        public void insertUser(User user) throws Exception;
        //删除用户信息
        public void deleteUser(int id) throws Exception;
    }
    复制代码

    3.3 mapper.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有特殊作用,namespace等于mapper接口地址  -->
    <mapper namespace="joanna.yan.mybatis.mapper.UserMapper">
        <select id="findUserById" parameterType="java.lang.Integer" resultType="joanna.yan.mybatis.entity.User">
            select * from user where id=#{id}
        </select>
        <select id="findUserByName" parameterType="java.lang.String" resultType="joanna.yan.mybatis.entity.User">
            select * from user where username LIKE '%${value}%'
        </select>
    </mapper>
    复制代码

    3.4 在SqlMapConfig.xml中加载mapper.xml

    3.5 测试

    复制代码
    public class UserMapperTest {
    private SqlSessionFactory sqlSessionFactory;
        
        @Before
        public void setUp() throws IOException{
            //创建sqlSessionFactory
            //mybatis配置文件
            String resource="SqlMapConfig.xml";
            //得到配置文件流
            InputStream inputStream=Resources.getResourceAsStream(resource);
            //创建会话工厂,传入mybatis的配置文件信息
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
        }
        
        @Test
        public void findUserByIdTest() throws Exception{
            SqlSession sqlSession=sqlSessionFactory.openSession();
            //创建UserMapper对象,mybatis自动生成mapper代理对象
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
            //调用userMapper的方法
            User user=userMapper.findUserById(1);
            System.out.println(user);
        }
        
        @Test
        public void findUserByNameTest() throws Exception{
            SqlSession sqlSession=sqlSessionFactory.openSession();
            //创建UserMapper对象,mybatis自动生成mapper代理对象
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
            //调用userMapper的方法
            List<User> list=userMapper.findUserByName("小明");
            System.out.println(list);
        }
    }
    复制代码

    3.6一些问题总结

    3.6.1 代理对象内部调用selectOne或selectList

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

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

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

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

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

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

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

    早年同窗始相知,三载瞬逝情却萌。年少不知愁滋味,犹读红豆生南国。别离方知相思苦,心田红豆根以生。
  • 相关阅读:
    ESP8266 wifi钓鱼
    九,ESP8266 判断是断电上电(强制硬件复位)之后运行的内部程序还是内部软件复位之后运行的程序(基于Lua脚本语言)
    关于Http 传输二维json
    Android6.0权限大全和权限分类
    Android 多线程-----AsyncTask详解
    关于加密(转载文章)
    java基础之:匿名内部类
    系统吞吐量(TPS)、用户并发量、性能测试概念和公式
    java多线程之:SynchronousQueue队列
    Hibernate之:各种主键生成策略与配置详解
  • 原文地址:https://www.cnblogs.com/ycmxm/p/7125568.html
Copyright © 2020-2023  润新知