zoukankan      html  css  js  c++  java
  • 用mybatis实现dao的编写或者实现mapper代理

    一、mybatis和hibernate的区别和应用场景
    hibernate:是一个标准的ORM框架(对象关系映射)。入门门槛较高的,不需要写sql,sql语句自动生成了。对sql语句进行优化、修改比较困难的。
    应用场景:使用与需求变化不多的中小型项目,比如:后台管理系统,erp、orm、oa
    mybatis:专注是sql本身,需要程序员写sql,修改优化比较方便。也可以实现映射。
    应用场景:使用需求变化较多的项目,比如:互联网项目,

    二、实现dao的编写(以user为例)

    1、编写userDAO

    package dao;
    
    import entity.users;
    
    public interface UserDao {
        public users findUserByid(int id) throws Exception;
        public void insertUser(users user) throws Exception;
        public void updateUser(users user) throws Exception;
        public void deleteUser(users user) throws Exception;
    }

    2、编写userDaoImpl

    因为现在没有和spring整合,所以SqlSessionFactory当工具类使用,用构造函数的方式注入,以后会交给spring管理

    package dao;
    
    import org.apache.ibatis.session.SqlSession;
    import org.apache.ibatis.session.SqlSessionFactory;
    
    import entity.users;
    
    public class UserDaoImpl implements UserDao {
        private SqlSessionFactory sqlSessionFactory=null;
        public UserDaoImpl(SqlSessionFactory sqlSessionFactory){
            this.sqlSessionFactory=sqlSessionFactory;
        }
    
        @Override
        public users findUserByid(int id) throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            users u=sqlSession.selectOne("test.srarchByid", id);
            System.out.println(u.getBirthday().toString());        
            sqlSession.close();
            return u;
            
        }
    
        @Override
        public void insertUser(users user) throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            sqlSession.insert("test.insertUser", user);
            System.out.println(user.getId());
            sqlSession.commit();
            sqlSession.close();
        }
    
        @Override
        public void updateUser(users user) throws Exception {
            // TODO Auto-generated method stub
            SqlSession sqlSession=sqlSessionFactory.openSession();
            sqlSession.update("updateUser",user);
            System.out.println(user.getId());
            sqlSession.commit();
            sqlSession.close();
            
        }
    
        @Override
        public void deleteUser(users user) throws Exception {
            // TODO Auto-generated method stub
            SqlSession sqlSession=sqlSessionFactory.openSession();
            sqlSession.delete("test.deleteUser",3);
            sqlSession.commit();
            sqlSession.close();
        }
    
    }

    3、测试类

    这里只测试了根据ID查询和插入,其他的类型,在这里不一一测试了。

    package dao;
    
    import java.io.InputStream;
    import java.util.Date;
    
    import org.apache.ibatis.io.Resources;
    import org.apache.ibatis.session.SqlSessionFactory;
    import org.apache.ibatis.session.SqlSessionFactoryBuilder;
    import org.junit.Before;
    import org.junit.Test;
    
    import entity.users;
    
    public class UserDaoImplTest {
        private SqlSessionFactory sqlSessionFactory;
    
        @Before
        public void setUpBeforeClass() throws Exception {
            String resource="SqlMapConfig.xml";
            InputStream stream=Resources.getResourceAsStream(resource);
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(stream);
        }
    
        @Test
        public void testFindUserByid() throws Exception {
            UserDao userDao=new UserDaoImpl(sqlSessionFactory);
            users u=userDao.findUserByid(1);
            System.out.println(u.getName());
            
        }
    
        @Test
        public void testInsertUser() throws Exception {
            users user=new users();
            user.setName("王五");
            user.setSex("f");
            user.setAddress("五道口");
            user.setBirthday(new Date());
            UserDao userDao=new UserDaoImpl(sqlSessionFactory);
            userDao.insertUser(user);
            
        }
    
    }

    三、原始DAO开发问题  

    1.DAO的接口实现类方法中存在大量的模板方法。
    2、调用SQLSession方法时将statement硬编码了。
    3、调用SQLSession方法时传入的变量,由于sqlsession方法使用泛型,即使参数类型错误,编译阶段不报错。

    由于以上的问题,mybatis提出了mapper代理的概念。这个概念的提出有效的解决了以上提出的问题,程序员只需要开发mapper代理(类似于dao的接口),框架自动为其生成实现类。下面将详细介绍mapper的开发步骤。

    四、mapper代理的开发(同样以user为例)

    1、开发规范

    1)在mapper.xml  namespace等于mapper接口地址
    2)mapper.java接口的方法名与mapper.xml的statement中得id一致
    3)mapper.java接口中得方法输入参数和mapper.xml中得statement的parameter指定的类型一致。
    4)接口返回值类型与statement中resultType类型一致。

    2、代码实现

    1)编写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">
    
    <!--mapper代理开发,namespace要与mapper接口的全名地址一样-->
    <mapper namespace="mapper.UserMapper">
        <select id="findUserByid" parameterType="int" resultType="entity.users">
            select * from users where id=#{id}
        </select>
        <select id="findUserByName" parameterType="String" resultType="entity.users">
            select * from users where name like '%${value}%'
        </select>
        <insert id="insertUser" parameterType="entity.users">
            insert into users(name,birthday,address,sex) values(#{name},#{birthday},#{address},#{sex})
            <selectKey keyProperty="id" order="AFTER" resultType="int">
                select last_insert_id()
            </selectKey>
        </insert>
        <delete id="deleteUser" parameterType="java.lang.Integer">
            delete from users where id=#{id}
        </delete>
        <update id="updateUser" parameterType="entity.users">
            update users set name=#{name},address=#{address},birthday=#{birthday},sex=#{sex} where id=#{id}
        </update>
    
    </mapper>

    在上一篇博文中我们开发了user.xml,这个是在开发普通dao时使用的配置文件,这里的userMapper与其功能类似。但需要注意的是namespace要与mapper接口的全名地址一样,mapper的ID要与mapper代理中得接口方法名相同。

    2)mapper代理接口

    package mapper;
    
    import java.util.List;
    
    import entity.users;
    
    public interface UserMapper {
        public users findUserByid(int id) throws Exception;
        public List<users> findUserByName(String name) throws Exception;
        public void insertUser(users user) throws Exception;
        public void updateUser(users user) throws Exception;
        public void deleteUser(int id) throws Exception;
        
    
    }

    3)测试代码

    package mapper;
    
    import static org.junit.Assert.fail;
    
    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 entity.users;
    
    public class UserMapperTest {
        private SqlSessionFactory sqlSessionFactory;
    
        @Before
        public void setUp() throws Exception {
            String resource="SqlMapConfig.xml";
            InputStream stream=Resources.getResourceAsStream(resource);
            sqlSessionFactory=new SqlSessionFactoryBuilder().build(stream);
        }
    
        @Test
        public void testFindUserByid() throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
            users user=userMapper.findUserByid(5);
            System.out.println(user.getName());
        }
    
        @Test
        public void testFindUserByName() throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
            List<users> list=userMapper.findUserByName("王");
            for(users u:list){
                System.out.println(u.getName());
            }
        }
    
        @Test
        public void testInsertUser() throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
            users user=new users();
            user.setName("Danny");
            user.setAddress("America");
            user.setBirthday(new Date());
            user.setSex("f");
            userMapper.insertUser(user);
            sqlSession.commit();
            sqlSession.close();
            System.out.println(user.getId());
        }
    
        @Test
        public void testUpdateUser() throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
            users user=new users();
            user.setId(19);
            user.setName("Danny");
            user.setAddress("America");
            user.setBirthday(new Date());
            user.setSex("m");
            userMapper.updateUser(user);
            sqlSession.commit();
            sqlSession.close();
            System.out.println(user.getId());
        }
    
        @Test
        public void testDeleteUser() throws Exception {
            SqlSession sqlSession=sqlSessionFactory.openSession();
            UserMapper userMapper=sqlSession.getMapper(UserMapper.class);
            userMapper.deleteUser(19);
            sqlSession.commit();
            sqlSession.close();
        }
    
    }

    mapper开发步骤总结为一下三个步骤
    1)程序员还需要编写mapper.xml映射文件
    2)编写mapper接口
    3)mybatis自动生成mapper接口的实现类对象

    五、SQLMapConfig中得其他配置内容

    1.properties

    需求:将数据库的连接参数单独配置在db.properties中,只需要在Sqlmapconfig.xml中加载db.properties的属性值,不需要再Sqlmapconfig.xml中硬编码了

    操作:

    新建一个db.properties,内容如下:

    jdbc.driver=com.mysql.jdbc.Driver
    jdbc.url=jdbc:mysql://localhost:3306/mybatisTest?characterEncoding=utf-8
    jdbc.username=root
    jdbc.password=123456

    然后在Sqlmapconfig.xml中加入以下标签

    <properties resource="db.properties"> </properties> ,这个标签要被<configuration>包住。同时可以在properties中再配置property,实现新的属性值,它会覆盖resource中得同名属性

    通过以上步骤就实现了数据库连接字符串的非硬编码实现。

    注意!Mybatis将按照下面的顺序来加载属性:
    在properties元素体内定义的属性首先被读取
    然后会读取properties元素中resource或url加载的属性,它会覆盖已读取得同名属性
    在最后读取parameterType传递的属性,它会覆盖已读取得同名属性。
    2.setting全局的参数配置
    用来调整一些运行参数,例如二级缓存和延迟加载。

    3.typeAliaes

    在mapper.xml中,定义很多的statement,statement需要parameterType和rusultType指定参数的类型,
    但是指定的类型要求是全路径的,不方便开发,就可以针对这些个全路径名字定义别名来实现。

    操作:

    (1)针对单个别名定义

    在Sqlmapconfig.xml中添加以下内容

    <typeAliases>
            <typeAlias type="entity.users" alias="user"/>
      </typeAliases> 

    然后在userMapper.xml中就可以用user代替entity.users

    (2)可以直接对整个package做别名定义,指定报名后,将自动扫描包中得类自动定义别名,别名为类名,首字母可大写也可小写。

    <typeAliases>
      <package name="entity"/>
    </typeAliases>

    4.mapper

    这个标签除了使用上面的resource属性外,还可以使用class,通过mapper接口加载映射文件

    需要遵循一些规范:需要mapper的类名和mapper.xml的名字一样且在一个目录下。

    同样class属性支持package批量加载。

  • 相关阅读:
    应用Dubbo框架打造仿猫眼项目 理解微服务核心思想
    慕课网--docker走进第一个javaweb应用
    金融行业微服务架构解析-转载炼数成金架构模块金融行业微服务架构解析
    StringEscapeUtils防止xss攻击详解
    尚硅谷 dubbo学习视频
    【面试篇】寒冬求职之你必须要懂的Web安全
    echo "" > 和 echo "" >> 的区别
    python函数、模块、包
    python学习笔记(7)--循环语句
    python学习笔记(6)--条件分支语句
  • 原文地址:https://www.cnblogs.com/softzrp/p/7096185.html
Copyright © 2011-2022 走看看