• Mybatis学习(2)原始dao开发和使用mapper接口代理开发


    基础知识:

    1).SqlSessionFactoryBuilder:

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

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

    2).SqlSessionFactory:

    通过SqlSessionFactory创建SqlSession,使用单例模式管理sqlSessionFactory(工厂一旦创建,使用一个实例)。将来mybatis和spring整合后,使用单例模式管理sqlSessionFactory。

    3).SqlSession:

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

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

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

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

    一、原始dao开发方法()

    需要编写dao接口和实现类;

    dao接口:

     1 package com.cy.Dao;
     2 
     3 import java.util.List;
     4 
     5 import com.cy.po.User;
     6 
     7 /**
     8  * dao接口,用户管理
     9  * @author chengyu
    10  *
    11  */
    12 public interface UserDao {
    13         //根据id查询用户信息
    14         public User findUserById(int id) throws Exception;
    15         
    16         //根据用户名列查询用户列表
    17         public List<User> findUserByName(String name) throws Exception;
    18         
    19         //添加用户信息
    20         public void insertUser(User user) throws Exception;
    21         
    22         //删除用户信息
    23         public void deleteUser(int id) throws Exception;
    24 }
    UserDao接口

    dao接口实现类:

     1 package com.cy.Dao;
     2 
     3 import java.util.List;
     4 
     5 import org.apache.ibatis.session.SqlSession;
     6 import org.apache.ibatis.session.SqlSessionFactory;
     7 
     8 import com.cy.po.User;
     9 
    10 /**
    11  * dao接口实现类
    12  * @author chengyu
    13  *
    14  */
    15 public class UserDaoImpl implements UserDao {
    16     // 需要向dao实现类中注入SqlSessionFactory
    17     // 这里通过构造方法注入
    18     private SqlSessionFactory sqlSessionFactory;
    19 
    20     public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
    21         this.sqlSessionFactory = sqlSessionFactory;
    22     }
    23 
    24     @Override
    25     public User findUserById(int id) throws Exception {
    26         SqlSession sqlSession = sqlSessionFactory.openSession();
    27         User user = sqlSession.selectOne("test.findUserById", id);
    28         
    29         // 释放资源
    30         sqlSession.close();
    31         return user;
    32     }
    33 
    34     @Override
    35     public List<User> findUserByName(String name) throws Exception {
    36         SqlSession sqlSession = sqlSessionFactory.openSession();
    37         List<User> list = sqlSession.selectList("test.findUserByName", name);
    38         sqlSession.close();
    39         return list;
    40     }
    41 
    42     @Override
    43     public void insertUser(User user) throws Exception {
    44         SqlSession sqlSession = sqlSessionFactory.openSession();
    45         sqlSession.insert("test.insertUser", user);
    46         sqlSession.commit();
    47         sqlSession.close();
    48 
    49     }
    50 
    51     @Override
    52     public void deleteUser(int id) throws Exception {
    53         SqlSession sqlSession = sqlSessionFactory.openSession();
    54         sqlSession.delete("test.deleteUser", id);
    55         sqlSession.commit();
    56         sqlSession.close();
    57     }
    58 
    59 }
    UserDaoImpl

    测试程序:

     1 package com.cy.Dao;
     2 
     3 import static org.junit.Assert.*;
     4 
     5 import java.io.InputStream;
     6 
     7 import org.apache.ibatis.io.Resources;
     8 import org.apache.ibatis.session.SqlSessionFactory;
     9 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    10 import org.junit.Before;
    11 import org.junit.Test;
    12 
    13 import com.cy.po.User;
    14 
    15 public class UserDaoImplTest {
    16     private SqlSessionFactory sqlSessionFactory;
    17     
    18     // 此方法是在执行testFindUserById之前执行
    19     @Before
    20     public void setUp() throws Exception {
    21         // mybatis配置文件
    22         String resource = "SqlMapConfig.xml";
    23         // 得到配置文件流
    24         InputStream inputStream = Resources.getResourceAsStream(resource);
    25 
    26         // 创建会话工厂,传入mybatis的配置文件信息
    27         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    28     }
    29         
    30     @Test
    31     public void testFindUserById() throws Exception {
    32         // 创建UserDao的对象
    33         UserDao userDao = new UserDaoImpl(sqlSessionFactory);
    34 
    35         // 调用UserDao的方法
    36         User user = userDao.findUserById(1);
    37         
    38         System.out.println(user);
    39     }
    40 
    41 }
    测试UserDao方法

    原始的dao开发方法问题总结:

    1)dao接口实现类方法中存在大量模板方法。

    2)调用sqlsession方法时将statement的id硬编码了

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

    二、使用mapper接口(相当于dao接口)代理开发方法:

    开发规范:遵循这些开发规范,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指定的类型一致

    UserMapper接口:

     1 package com.cy.mapper;
     2 
     3 import java.util.List;
     4 
     5 import com.cy.po.User;
     6 
     7 /**
     8  * mapper接口,用户管理
     9  * @author chengyu
    10  *
    11  */
    12 public interface UserMapper {
    13     //根据id查询用户信息
    14     public User findUserById(int id) throws Exception;
    15         
    16     //根据用户名列查询用户列表
    17     public List<User> findUserByName(String name)throws Exception;
    18         
    19     //插入用户
    20     public void insertUser(User user)throws Exception;
    21         
    22     //删除用户
    23     public void deleteUser(int id)throws Exception;
    24 }

    UserMapper.xml:

     1 <?xml version="1.0" encoding="UTF-8" ?>
     2 <!DOCTYPE mapper
     3 PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
     4 "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
     5 
     6 <!--使用mapper代理方法开发,namespace有特殊重要的作用,namespace等于mapper接口地址-->
     7 <mapper namespace="com.cy.mapper.UserMapper">
     8     <!--通过id查询用户 -->
     9     <select id="findUserById" parameterType="int" resultType="com.cy.po.User">
    10         SELECT * FROM USER WHERE id=#{value}
    11     </select>
    12     
    13     <!-- 根据用户名称模糊查询用户信息,可能返回多条-->
    14     <select id="findUserByName" parameterType="java.lang.String" resultType="com.cy.po.User">
    15         SELECT * FROM USER WHERE username LIKE '%${value}%'
    16     </select>
    17     
    18     <!-- 添加用户 -->
    19     <insert id="insertUser" parameterType="com.cy.po.User">
    20         <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
    21             SELECT LAST_INSERT_ID()
    22         </selectKey>
    23         insert into user(username,birthday,sex,address) value(#{username},#{birthday},#{sex},#{address})
    24     </insert>
    25     
    26     <!-- 根据id删除 用户-->
    27     <delete id="deleteUser" parameterType="java.lang.Integer">
    28         delete from user where id=#{id}
    29     </delete>
    30     
    31     <!-- 根据id更新用户 -->
    32     <update id="updateUser" parameterType="com.cy.po.User">
    33         update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} 
    34             where id=#{id}
    35     </update>
    36 </mapper>

    将UserMapper.xml映射文件加入:

    <!-- 加载 映射文件 -->
        <mappers>
            <mapper resource="mapper/UserMapper.xml"/>
        </mappers>

    UserMapper接口的测试方法:

     1 package com.cy.mapper;
     2 
     3 import static org.junit.Assert.*;
     4 
     5 import java.io.InputStream;
     6 import java.util.List;
     7 
     8 import org.apache.ibatis.io.Resources;
     9 import org.apache.ibatis.session.SqlSession;
    10 import org.apache.ibatis.session.SqlSessionFactory;
    11 import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    12 import org.junit.Before;
    13 import org.junit.Test;
    14 
    15 import com.cy.po.User;
    16 
    17 public class UserMapperTest {
    18 
    19     private SqlSessionFactory sqlSessionFactory;
    20 
    21     @Before
    22     public void setUp() throws Exception {
    23 
    24         String resource = "SqlMapConfig.xml";
    25         InputStream inputStream = Resources.getResourceAsStream(resource);
    26         sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    27     }
    28     
    29     @Test
    30     public void testFindUserById() throws Exception {
    31         SqlSession sqlSession = sqlSessionFactory.openSession();
    32         
    33         //创建UserMapper对象,mybatis自动生成mapper代理对象
    34         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    35         
    36         User user = userMapper.findUserById(1);
    37         System.out.println(user);
    38     }
    39     @Test
    40     public void testFindUserByName() throws Exception {
    41         SqlSession sqlSession = sqlSessionFactory.openSession();
    42         
    43         //创建UserMapper对象,mybatis自动生成mapper代理对象
    44         UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    45         
    46         List<User> list = userMapper.findUserByName("小明");
    47         sqlSession.close();
    48         System.out.println(list);
    49     }
    50 }
    View Code

    关于mapper接口代理开发的一些问题:

    1.代理对象内部是调用selectOne还是selectList?

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

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

    2、mapper接口方法参数只有一个是否影响开发?

    系统框架中,dao层的代码是被业务层公用的。即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求。

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

  • 相关阅读:
    面试题目小结
    面试题目3
    C#中new和override区别
    [转]:存储过程与函数的区别
    [转载]:C# 面试题大全
    [转]:C++虚函数表解析
    【修订版】C#/ASP.Net 面试题及答案(1)
    [转载]:C# 中结构与类的区别
    [转载]:C#笔试题面试题锦集
    [转载]:SQL Server性能调优之执行计划深度剖析 第一节 浅析SQL执行的过程
  • 原文地址:https://www.cnblogs.com/tenWood/p/6275858.html
Copyright © 2020-2023  润新知