注解的作用就是代替映射xml文件,这个操作由mybatis自己实现。从上面这句话我们就知道 MyBatis可以利用SQL映射文件来配置,也可以利用Annotation来设置。
注意事项:
- 不要再@Select等中SQL套SQL,也就是不要子查询
- 再service层调用mapper的时候入参也不能包含mapper的调用
我们就拿一个springboot项目来说,前提是已经在pom.xml中假如了mybatis的依赖。
第一步:在启动类上添加mapper扫描的注解
启动类上得加一个@MapperScan(“com.lc.mybatis.mapper,这是mapper获得dao文件的类全名”) 扫描某个包目录下的Mapper,将Mapper接口类交给Spring进行管理。
也可以用通配符代替包名,如:com.lc..mapper,
多个路径用逗号隔开,如“com.lc.mybatis1.mapper”,“com.lc.mybatis2.mapper”
第二步:在mapper或者dao层的接口上添加让mybatis管理的接口
@Mapper,该注解目的就是为了不再写mapper映射文件 (UserMapper.xml),而把这个功能交给mybatis去完成,且将实现类的对象存储到spring容器中。
@Mapper
public interface UserMapper { // dao层
User selectById(Integer id);
}
第三步:在dao或mapper的接口方法上使用注解添加sql语句
sql语句可以分为动态SQL和普通SQL,在注解这方面也是这样划分的。
注意:无论是增删改查的slq,其对于的注解功能都是一样的,划分这么多个知识为了规范和区分,就像@Component@Controller这类的注解一样。
普通SQL
都是直接在接口方法上面加注解就行
增 @Insert 插入注解 的一些特殊性
通常我们建表的时候会设置主键id,那我用注解会实现主键ID的添加吗?
对此基本上有三种方案,分别是:
- 手动指定(应用层)
理解就是,mybatis不知道那个字段是主键字段,都看成一般字段来处理
@Insert("INSERT INTO t_user (id, username, passwd) VALUES (#{id}, #{username}, #{passwd})")
int addUserAssignKey(User user);
// user看成当前的了上下文,那#{}里面直接填写user的属性
- 自增主键(数据层单表)
使用Option注解来确定哪个字段为主键,且使什么增长模式,userGeneratordKeys表示要使用自增主键,keyProperty用来指定主键字段的字段名。自增主键会使用数据库底层的自增特性。
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("INSERT INTO t_user (username, passwd) VALUES (#{username}, #{passwd})")
int addUserGeneratedKey(User user);
- 选择主键(数据层多表) 很少用
选择主键从数据层生成一个值,并用这个值作为主键的值。
动态SQL
动态SQL的注解实现,得结合代码;
- @SelectProvider
- @InsertProvider + @Options
- @UpdateProvider
- @DeleteProvider
以上注解由两个属性:
type 只当一个类的class对象
method 上面属性指定的类里面的某个方法名,就是我门要执行的sql,这个方法返回是一个定义了sql语句的sql对象;
注意: method引用的方法和dao层接口的方法入参要一致
例子:
public interface EmployeeMapper {
@SelectProvider(type=Intefaceproxy.Dyno.EmployeeDynaSqlProvider.class,method="selectWhitParamSql")
List<Employee> selectWithParam(Map<String,Object> param);
}
public class EmployeeDynaSqlProvider {
//方法中的关键字是区分大小写的 SQL SELECT WHERE
//该方法会根据传递过来的map中的参数内容 动态构建sql语句
public String selectWhitParamSql(Map<String, Object> param) {
return new SQL() {
{
SELECT("*");
FROM("tb_employee");
if (param.get("id")!=null) {
WHERE("id=#{id}");
}
if(param.get("loginname")!=null) {
WHERE("loginname=#{loginname}");
}
if(param.get("password")!=null) {
WHERE("password=#{password}");
}
if(param.get("name")!=null) {
WHERE("name=#{name}");
}
if(param.get("sex")!=null) {
WHERE("sex=#{sex}");
}
if(param.get("age")!=null) {
WHERE("age=#{age}");
}
if(param.get("phone")!=null) {
WHERE("phone=#{phone}");
}
if(param.get("sal")!=null) {
WHERE("sal=#{sal}");
}
if(param.get("state")!=null) {
WHERE("state=#{state}");
}
}
}.toString();
}
}
public String insertEmployeeSql(Employee employee) {
return new SQL() {
{
INSERT_INTO("tb_employee");
if(employee.getLoginname()!=null) {
VALUES("loginname","#{loginname}");
}
if(employee.getPassword()!=null) {
VALUES("password", "#{password}");
}
if(employee.getName()!=null) {
VALUES("name", "#{name}");
}
if(employee.getSex()!=null) {
VALUES("sex", "#{sex}");
}
if(employee.getAge()!=``null) {
VALUES("age", "#{age}");
}
if(employee.getPhone()!=null) {
VALUES("phone", "#{phone}"`);
}
if(employee.getSal()!=null) {
VALUES("sal", "#{sal}");
}
if(employee.getState()!=null) {
VALUES("state", "#{state}");
}
}
}.toString();
}
//updateEmployeeSql
public String updateEmployeeSql(Employee employee) {
return` `new` `SQL() {
``{
UPDATE(``"tb_employee"``);
if``(employee.getLoginname()!=``null``) {
SET(``"loginname=#{loginname}"``);
}
if``(employee.getPassword()!=``null``) {
SET(``"password=#{password}"``);
}
if``(employee.getName()!=``null``) {
SET(``"name=#{name}"``);
}
if``(employee.getSex()!=``null``) {
SET(``"sex=#{sex}"``);
}
if``(employee.getAge()!=``null``) {
SET(``"age=#{age}"``);
}
if``(employee.getPhone()!=``null``) {
SET(``"phone=#{phone}"``);
}
if(employee.getSal()!=``null``) {
SET(``"sal=#{sal}"``);
}
if(employee.getState()!=``null``) {
SET(``"state=#{state}"``);
}
WHERE(``"id=#{id}"``);
}
}.toString();
}
//deleteEmployeeSql
public String deleteEmployeeSql(Employee employee) {
return new SQL() { {
DELETE_FROM("tb_employee");
if(employee.getLoginname()!=null) {
WHERE("loginname=#{loginname}"); }
if(employee.getPassword()!=null) {
WHERE("password=#{password}"); }
if(employee.getName()!=null) {
WHERE("name=#{name}"); }
} }.toString();
}
扩展:
order,limit等等
最后,特殊情况
假如实体类的属性名称和表字段名称对不上
@Results 用于查询到的列和实体类之间的映射,把不匹配的名字匹配上