• 使用注解开发(重点)


    1、面向接口编程

    • 根本原因:解耦,可拓展,提高复用,分层开发中,上层不用管具体的实现,大家都遵守共同的标准,使得开发变得容易,规范性更好。

    • 在一个面向对象的系统中,系统的各种功能是由许许多多的不同对象协作完成的。在这种情况下,各个对象内部是如何实现自己的,对系统设计人员来讲就不用那么重要了;

    • 各个对象之前的协作关系则成为系统设计的关键。小到不同类之前的通讯,大到各模块之间的交互,在系统设计之初都是要着重要考虑的,这也是系统设计的主要工作内容。面向接口编程就是指按照这种思想来编程。

    关于接口的理解

    • 接口从更深层次的理解,应是定义(规范,约束)与实现(名实分离的原则)的分离

    • 接口的本身反映了系统设计人员对系统的抽象理解

    • 接口应有两类:

      • 第一类是对一个个体的抽象,它对应为一个抽象体(abstract class)

      • 第二类是对一个个体某一方便的抽象,即形成一个抽象面(interface)

    • 一个个体有可能有多个抽象面。抽象体和抽象面是有区别的。

    三个面向区别

    • 面向对象:我们考虑问题时,以对象为单位,考虑它的属性及方法

    • 面向过程:我们考虑问题时,以一个具体的流程(事务过程)为单位,考虑它的实现

    • 接口设计与非接口设计是针对复用技术而言的,与面向对象(过程)不是一个问题。更多的体现就是对系统整体的架构。

    2、使用注解开发

    (1)注解在接口上实现

    1. @Select("select id, name, pwd from `user`")
    2. List getUserList();

    (2)需要在核心配置文件中绑定接口

    1. <mappers>
    2. <mapper class="com.gt.dao.UserMapper"/>
    3. mappers>

    (3)测试

    1. @Test
    2. public void getUserList() {
    3. SqlSession sqlSession = null;
    4. try {
    5. sqlSession = MybatisUtils.getSqlSession();
    6. //底层主要应用反射
    7. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    8. List userList = userMapper.getUserList();
    9. for (User user : userList) {
    10. System.out.println(user.toString());
    11. }
    12. } finally {
    13. if (sqlSession != null) {
    14. sqlSession.close();
    15. }
    16. }
    17. }

    UserMapper: 

    mybatis-config: 

     UserMapper:

     本质:反射机制

    底层:动态代理

    mybatis详细的执行流程

    3、CRUD

    (1)我们可以造工具类创建的时候实现自动提交事务!

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

    (2)编写接口,增加注解

    1. import com.gt.pojo.User;
    2. import org.apache.ibatis.annotations.Delete;
    3. import org.apache.ibatis.annotations.Insert;
    4. import org.apache.ibatis.annotations.Param;
    5. import org.apache.ibatis.annotations.Select;
    6. import org.apache.ibatis.annotations.Update;
    7. import java.util.List;
    8. public interface UserMapper {
    9. @Select("select id, name, pwd from `user`")
    10. List getUserList();
    11. @Select("select id, name, pwd from `user` where id=#{id} ")
    12. User getUserById(@Param("id") int id);
    13. @Insert("insert into `user`(id, name, pwd) values (#{id},#{name},#{password})")
    14. int addUser(User user);
    15. @Update("update `user` set name=#{name},pwd=#{password} where id=#{id}")
    16. int updateUser(User user);
    17. @Delete("delete from `user` where id=#{uid}")
    18. int deleteUser(@Param("uid") int id);
    19. }

     

    测试类

            【注意:我们必须要将接口注册绑定到我们的核心配置文件中】

    关于@Param()注解

    • 基本类型的参数或者String类型,需要加上

    • 引用类型不需要加

    • 如果只有一个基本类型的话,可以忽略,但是建议大家都加上

    • 我们在sql中引用的就是我们这里的@Param()中设定的属性名

    1. import com.gt.pojo.User;
    2. import com.gt.utils.MybatisUtils;
    3. import org.apache.ibatis.session.SqlSession;
    4. import org.junit.Test;
    5. import java.util.List;
    6. public class UserMapperTest {
    7. @Test
    8. public void getUserList() {
    9. SqlSession sqlSession = null;
    10. try {
    11. sqlSession = MybatisUtils.getSqlSession();
    12. //底层主要应用反射
    13. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    14. List userList = userMapper.getUserList();
    15. for (User user : userList) {
    16. System.out.println(user.toString());
    17. }
    18. } finally {
    19. if (sqlSession != null) {
    20. sqlSession.close();
    21. }
    22. }
    23. }
    24. @Test
    25. public void getUserById() {
    26. SqlSession sqlSession = null;
    27. try {
    28. sqlSession = MybatisUtils.getSqlSession();
    29. //底层主要应用反射
    30. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    31. User user = userMapper.getUserById(1);
    32. System.out.println(user);
    33. } finally {
    34. if (sqlSession != null) {
    35. sqlSession.close();
    36. }
    37. }
    38. }
    39. @Test
    40. public void addUser() {
    41. SqlSession sqlSession = null;
    42. try {
    43. sqlSession = MybatisUtils.getSqlSession();
    44. //底层主要应用反射
    45. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    46. int count = userMapper.addUser(new User(6, "gt6", "123456"));
    47. System.out.println(count);
    48. } finally {
    49. if (sqlSession != null) {
    50. sqlSession.close();
    51. }
    52. }
    53. }
    54. @Test
    55. public void updateUser() {
    56. SqlSession sqlSession = null;
    57. try {
    58. sqlSession = MybatisUtils.getSqlSession();
    59. //底层主要应用反射
    60. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    61. int count = userMapper.updateUser(new User(6, "gt2", "123123"));
    62. System.out.println(count);
    63. } finally {
    64. if (sqlSession != null) {
    65. sqlSession.close();
    66. }
    67. }
    68. }
    69. @Test
    70. public void deleteUser() {
    71. SqlSession sqlSession = null;
    72. try {
    73. sqlSession = MybatisUtils.getSqlSession();
    74. //底层主要应用反射
    75. UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    76. int count = userMapper.deleteUser(5);
    77. System.out.println(count);
    78. } finally {
    79. if (sqlSession != null) {
    80. sqlSession.close();
    81. }
    82. }
    83. }
    84. }

    扩展 #{} ${}区别:

    (1)对比

    •         使用${}方式传入的参数,mybatis不会对它进行特殊处理
    •         使用#{}传进来的参数,mybatis默认会将其当成字符串
    •         可能在赋值给如id=#{id}和id=${id}看不出多大区别,但是作为表名或字段参数时可以明显看出,可以看看下面的例子:

    假设传入的参数为表名test

    selec * from #{table};

    解析后是:

    select * from "test";

    然而

    传入的参数为表名test

    select * from ${table};

    解析后是:

    select * from test;
    • 很明显,前者多了字符串的引号,会失败,后者正常查询会成功
    • 所以对于传入分组(order)字段或者排序字段(order),应使用${},避免出现order  by "id" 等情况。

    (2)#和$在预编译处理中是不一样的。#类似jdbc中的PreparedStatement,对于传入的参数,在预处理阶段会使用?代替,比如:

    select * from student where id = ?;

    待真正查询的时候即在数据库管理系统中(DBMS)才会代入参数。

    而${}则是简单的替换,如下:

    select * from student where id = 2;

    总结

    1. 能使用#{}的地方应尽量使用#{}
    2. 像PreparedStatement ,#{}可以有效防止sql注入,${}则可能导致sql注入成功。

    所谓sql注入,就是指把用户输入的数据拼接到sql语句后面作为sql语句的一部分执行,例如:

    select * from user where name=' "+name+" ' and password=' "+password+" '

     那么只要用户输入用户名:admin和密码:123456' or  'abc' = 'abc',那么拼接出来的语句就为

    select * from user where name=' admin ' and password='123456' or 'abc'= 'abc';

     这样只要user表有数据,就会返回结果,达到sql注入的目的。同样,用户输入用户名a'则 and password=' "+password+" '就会被注释掉,也达到注入sql的目的。

    这里提下防止sql注入的几种方式(可能不止这几种):

    1. jdbc使用 PreparedStatement代替Statement, PreparedStatement 不仅提高了代码的可读性和可维护性.而且也提高了安全性,有效防止sql注入;
    2. 在程序代码中使用正则表达式过滤参数。使用正则表达式过滤可能造成注入的符号,如' --等
    3. 在页面输入参数时也进行字符串检测和提交时进行参数检查,同样可以使用正则表达式,不允许特殊符号出现。
       

  • 相关阅读:
    HNUCM 您好中国
    学校网页设计成品 基于HTML+CSS+JavaScript仿山东财经大学官网 学校班级网页制作模板 校园网页设计成品
    基于AT89C51单片机超声波水位液位控制系统设计(含文档、源码与proteus仿真,以及系统详细介绍)
    网络流量监测与调度技术研究
    随着云计算和容器技术的广泛应用,如何在这些环境中有效地运用 Shell 进行自动化部署和管理?
    vivo 容器集群监控系统优化之道
    如何让销售管理更高效?
    04. Springboot集成Mybatis-flex(二)
    第十三章 Python操作数据库
    JAVA异常机制
  • 原文地址:https://blog.csdn.net/qq_46423017/article/details/126519421