mybatis学习(七、使用注解开发)

七、使用注解开发

1.面向接口编程

  1. 什么是面向接口编程?
    面向接口编程是开发程序的功能先定义接口,接口中定义约定好的功能方法声明,通过实现该接口进行功能的实现,完成软件或项目的要求.软件或项目随着时间的不断变化,软件的功能要进行升级或完善,开发人员只需要创建不同的新类重新实现该接口中所有方法,就可以达到系统升级和扩展的目的。

  2. 面向接口编程与面向对象开发的区别:

    • 面向对象开发:
      UserDao dao = new UserDao();

      假设项目开发中dao层的技术要升级改造,那么面向对象开发有两种实现方式

      • 将UserDao中的代码删除,全部重写,但是方法名称不允许改变,为了不影响其他层,如service层调用dao的方法
      • 创建一个新的类,如:UserDaoTwo 所有的方法名称照搬,用新技术重写方法体中的内容,但是需要调用dao层的位置,要全部更换为新的类,new UserDaoTwo();
    • 面向接口编程:

      UserDao dao = new UserDaoImpl();

      1.项目需要升级改造时:

      • 不需要修改原来的类,只要创建一个新的类,实现这个接口,以前的方法全部都有,只要重写方法体即可,不会漏写
      • 为了不在调用dao处,修改多次,可以写为UserDao dao = 工具类.getImpl(); 这时如果我们项目升级过程中更改了实现类,只需要在工具类中修改一次,项目中就全部修改了

      这时我们又发现,工具类中如果给多个接口返回实现类,就有如下代码冗余的问题:

        public static Object getBean(){
             return new UserDaoImpl();
        }
        public static Object getCategoryBean(){
             return new CategoryDaoImpl();
        }
        public static Object getFavoriteDaoImpl(){
         	 return new FavoriteDaoImpl();
        }
      

      这时就出现了,面向接口编程的最终版:

      • UserDao dao = 工具类.getImpl(id);在创建实现类的时候,传入一个id. 在配置文件中,根据id唯一标识一个实现类的全限定类名.工具类中只需要根据这个id去配置文件中获得内容,反射 动态实例化创建对象就好了.以后,再修改升级功能时,只需要在配置文件中修改全限定类名就好了

      工具类代码:

      public class BeanFactoryUtils {
      public static Object getBean(String id) throws ClassNotFoundException, IllegalAccessException, InstantiationException {
      //1.根据传入id 获得配置文件中已经配置好的value属性 ==>全限定类名
            ResourceBundle bundle = ResourceBundle.getBundle("bean");//bean为配置文件
            String className = bundle.getString(id);
      //2.反射 动态实例化对象  ==>>必须有全限定类名 ==>> 字符串 ==>> 抽取到配置文件中
            Class clazz = Class.forName(className);
            return clazz.newInstance();
      	}	
      }	
      
      

      配置文件:bean.properties 格式为key=value书写

  3. 面向接口编程的好处

    • 降低了程序的耦合性.其能够最大限度的解耦,所谓解耦既是解耦合的意思,它和耦合相对。耦合就是联系,耦合越强,联系越紧密。在程序中紧密的联系并不是一件好的事情,因为两种事物之间联系越紧密,你更换其中之一的难度就越大,扩展功能和debug的难度也就越大。
    • 易扩展. 我们知道程序设计的原则是对修改关闭,对新增开放.面向接口编程扩展功能只需要创建新实现类重写接口方法进行升级扩展就可以,达到了在不修改源码的基础上扩展的目的.
    • 易维护

2.使用注解开发

可以直接在接口上添加注解,跳过Mapper.xml配置文件直接实现SQL

  1. 接口

    //查询全部用户
    @Select("select * from user")
    List<User> getUserList();
    
  2. 核心配置文件

    <!--绑定接口-->
    <mappers>
        <mapper class="com.lzt.dao.UserMapper"/>
    </mappers>
    

    本质:反射机制实现

    底层:动态代理

使用注解来映射简单语句会使代码显得更加简洁,然而对于稍微复杂一点的语句,Java 注解就力不从心了,并且会显得更加混乱。 因此,如果你需要完成很复杂的事情,那么最好使用 XML 来映射语句

选择何种方式来配置映射,以及认为映射语句定义的一致性是否重要,这些完全取决于你和你的团队。 换句话说,永远不要拘泥于一种方式,你可以很轻松的在基于注解和 XML 的语句映射方式间自由移植和切换。

3.mybatis的具体执行流程

4.CRUD(注解)

我们可以在工具类创建的时候实现自动提交事务

public static SqlSession getSqlSession(){
    return sqlSessionFactory.openSession(true);
}

在openSession中设置为true,为自动提交事务

  1. 接口

    //通过id查询,如果方法存在多个参数,必须加上@param()注解
    @Select("select * from user where id=#{id}")
    User getUserById(@Param("id") int id);
    
    //增加
    @Insert("insert into user(id,name,pwd) values(#{id},#{name},#{pwd})")
    int addUser(User user);
    
    //修改
    @Update("update user set name=#{name},pwd=#{pwd} where id=#{id}")
    int updateUser(User user);
    
    //删除
    @Delete("delete from user where id=#{id}")
    int deleteUser(@Param("id") int id);
    
  2. 测试

    @Test
    public void getUserById(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
        User user = mapper.getUserById(1);
        System.out.println(user);
    
        sqlSession.close();
    }
    
    @Test
    public void addUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
        mapper.addUser(new User(7,"hahaah","12312312"));
    
        sqlSession.close();
    }
    
    @Test
    public void updateUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
        mapper.updateUser(new User(7,"balabal","2222"));
    
        sqlSession.close();
    }
    
    @Test
    public void deleteUser(){
        SqlSession sqlSession = MybatisUtils.getSqlSession();
        UserMapper mapper = sqlSession.getMapper(UserMapper.class);
    
        mapper.deleteUser(7);
    
        sqlSession.close();
    }
    

注意:必须要将接口注册绑定到mybatis核心配置文件当中!

关于@param()注解

  • 基本类型和String类型,需要加上
  • 引用数据类型
  • 如果只有一个基本类型的话,可以忽略,但是建议加上
  • 在SQL中引用的就是@param("xxx")中设定的属性名

#{}、${}的区别

  • {}是预编译处理,$ {}是字符串替换(当做占位符来用)。

  • mybatis在处理#{}时,会将sql中的#{}替换为?号,调用PreparedStatement的set方法来赋值;

  • mybatis在处理 $ {} 时,就是把 ${} 替换成变量的值。

  • 使用 #{} 可以有效的防止SQL注入,提高系统安全性。SQL注入是发生在编译的过程中,因为恶意注入了某些特殊字符,最后被编译成了恶意的执行操作。而预编译机制则可以很好的防止SQL注入。

posted @ 2021-03-02 09:07  HoneyOneD  阅读(93)  评论(0)    收藏  举报