基于mapper的动态代理的开发方式——MyBatis的第二种开发方式
2018-03-27 23:42
816 查看
MyBatis有两种开发方式
1. 原始的 Ibatis 接口实现类的方式
通过 SqlSessionFactory 创建 SqlSession 来调用增删改查接口,操作 statement 的 id 硬编码来实现,老项目常用这种方式。缺点:重复代码过多,操作 statement 的 id 硬编码将来影响维护。
2. 基于mapper的动态代理的开发方式
mybatis根据一些规则自动创建接口的实现类的代理对象,通过 sqlSession.getMapper(xxx.class) 的方式生成接口的代理对象,调用相应的方法来执行增删改查,新项目使用这种方式。优点:无需写实现类(自动生成代理),重复代码量减少,便于维护。
本篇介绍第二种:基于 mapper 的动态代理的开发方式。
基于mapper的动态代理的开发方式需要遵循一些规则:
UserMapper.xml 中的 namespace 必须指定为要代理的接口全限定性类名。
UserMapper.xml 中的 statement 的 id 必须指定为要代理的接口中的方法名
UserMapper.xml 中的 statement 的输入参数类型必须和对应方法的参数类型相同
UserMapper.xml 中的 statement 的返回类型必须和对应方法返回值类型相同
在配置上述四点的时候会遇到几个问题:
mapper.xml 中 statement 的输入参数和返回值类型太长了。
解决:为类起别名,之后就可以在对应的参数和返回值中直接写对应的类名不用加包名。
<typeAliases> <!-- 批量定义别名 --> <package name="com.lyu.shopping.sysmanage.entity" /> <package name="com.lyu.shopping.sysmanage.dto" /> <package name="com.lyu.shopping.recommendate.dto" /> </typeAliases>
查询的时候需要给字段后起别名才能与实体类的属性一一对应
解决:开启驼峰命名,之后只要数据库中的表的字段名为 xxx_yyy 即可自动映射java bean 中的 xxxYyy 类。
<settings> <setting name="mapUnderscoreToCamelCase" value="true"/> </settings>
MyBatis 主要的两个配置文件:
主配置文件(mybatis-cfg.xml)内容如下:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 配置一些属性 --> <settings> <!-- 开启驼峰命名,映射表字段与 pojo 实体类的属性名 --> <!-- 例:数据库字段名 user_id 对应实体类属性名 userId --> <setting name="mapUnderscoreToCamelCase" value="true"/> <!-- 打印SQL执行过程的日志 --> <setting name="logImpl" value="STDOUT_LOGGING"/> </settings> <typeAliases> <!-- 单个类起别名 --> <typeAlias type="全限定性类名" alias="别名" /> <!-- 批量定义别名,为一个包里面的类添加别名 --> <package name="com.lyu.shopping.sysmanage.entity" /> <package name="com.lyu.shopping.sysmanage.dto" /> <package name="com.lyu.shopping.recommendate.dto" /> </typeAliases> <!-- 配置pageHelper分页插件 --> <plugins> <plugin interceptor="com.github.pagehelper.PageHelper"> <!-- 设置数据库类型 Oracle,Mysql,MariaDB,SQLite,Hsqldb,PostgreSQL六种数据库--> <property name="dialect" value="mysql"/> <!-- RowBounds参数offset作为PageNum使用 - 默认不使用 --> <property name="offsetAsPageNum" value="false"/> <!-- 使用RowBounds分页会进行count查询 --> <property name="rowBoundsWithCount" value="false"/> <!--当设置为true的时候,如果pagesize设置为0 就不执行分页,返回全部结果 --> <property name="pageSizeZero" value="true"/> <!--合理化查询 比如如果pageNum<1会查询第一页;如果pageNum>pages会查询最后一页(设置为false返回空)--> <property name="reasonable" value="false"/> <!-- 支持通过Mapper接口参数来传递分页参数 --> <property name="supportMethodsArguments" value="false"/> <!-- 总是返回PageInfo类型,check检查返回类型是否为PageInfo,none返回Page --> <property name="returnPageInfo" value="none"/> </plugin> </plugins> <mappers> <!-- 需要生成代理的接口所在的包 --> <package name="com.lyu.shopping.*.mapper"/> </mappers> </configuration>
mapper配置文件(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="com.lyu.shopping.sysmanage.mapper.AdminMapper"> <!-- 管理员表所有的字段(除去password字段) --> <sql id="all_admin_columns"> id, login_name, admin_name, password, age, sex, email, mobile, address, status, gmt_create, gmt_modified, is_deleted delFlag </sql> <!-- 通过管理员id获取管理员的详细信息 --> <select id="getAdminByAdminId" parameterType="long" resultType="admin"> SELECT <include refid="all_admin_columns" /> FROM shopping_sys_admin WHERE id = #{adminId} AND is_deleted = 0 </select> </mapper>
其中,namespace 为要代理的接口的全限定性类名,id 为要调用的句柄(类似PreparedStatement),parameterType 为传入的参数类型,resultType 为此次查询返回的类型,以上这两种类型都可以使用别名来定义(前提是在主配置文件中配置了别名)。
注:如果有多个简单类型的参数,就不需要写 parameterType ,在 SQL 中用 #{0}, #{1},… 来接收即可;模糊查询需要用 ${} 拼接符 将 SQL 和参数拼接起来(这也就容易引起注入和效率问题,能用 # 就不要用 $)
关于动态 SQL :
<!-- if标签 --> <if test="userName != null"> AND user_name = #{userName} </if> <!-- where标签 --> <where> <if test="userName != null"> AND user_name = #{userName} </if> <if test="birthday != null"> AND birthday= #{birthday} </if> ... </where>
where 标签主要有两个作用:
添加 where 关键字。
判断第一个条件不加 and(where 标签中可能嵌套多个 if 标签,由于不确定哪个 if 标签能满足条件,所以每个 if 标签中都要加 AND 关键字来预防条件的连接,但是如果第一个条件加上 AND 就不符合 SQL 语法规范,所以 where 就有了这个作用)。
if 标签的作用:
根据 test 条件是否成立,决定是否添加标签内 SQL。
那么为什么会出现 if,where 标签呢?
是由于业务需求导致的,比如:多条件查询,天猫超市买东西,用户可能根据商品的价格查找,商品的销量,商品的名称… 这些条件是不确定的,所以就有 if 标签来进行判断,动态生成 SQL,简化代码,提高编码效率。
相关文章推荐
- Mybatis(二)— 使用Mapper动态代理方式进行开发
- mybatis3整合spring4-采用mapper动态代理的方式开发Dao
- mybatis之入门到开发(四)之 Mapper动态代理方式
- MyBatis学习记录(3):Mapper动态代理方式开发DAO
- MyBatis动态代理的方式DAO开发设置
- Mybatis基于接口代理的方式来开发Dao(一)
- mybatis开发Mapper代理方式
- Mybatis Mapper代理的开发方式
- MyBatis之Mapper动态代理开发
- Mybatis 动态代理方式开发 Demo
- mybatis基于mapper代理的开发
- Mybatis之Mapper动态代理方式
- Spring与MyBatis整合上_Mapper动态代理方式
- JavaEE_Mybatis_SpringMVC_整合开发_lesson2_Mapper代理开发方式
- Mybatis实现Mapper动态代理方式详解
- 原始dao和Mapper动态代理的开放方式---Mybatis学习笔记(六)
- 框架学习系列 mybatis 第九篇 mybatis中Mapper代理的开发方式
- mybatis入门--mapper代理方式开发
- 基于Maven的Mybatis+spring+springMVC框架整合(mapper代理方式)
- Mybatis基于接口代理的方式来开发Dao(二)