mybatis注解的使用

https://blog.csdn.net/IT_CREATE/article/details/86564305

 

关于spring整合mybatis的步骤applicationContext.xml的配置:https://blog.csdn.net/IT_CREATE/article/details/85329007
mybtis中的级联关系(关联关系、集合关系)association、collection(一对一关系、一对多关系、多对多关系):https://blog.csdn.net/IT_CREATE/article/details/86523101
mybatis框架之mapper的xml映射配置的编写(insert、delete、update、select标签使用):https://blog.csdn.net/IT_CREATE/article/details/85687293
mybatis中动态sql的操作(where、foreach、if、set、choose、trim标签的使用):https://blog.csdn.net/IT_CREATE/article/details/86557260
mybatis中的级联关系中的鉴别器(discriminator、case、result):https://blog.csdn.net/IT_CREATE/article/details/86561051
 

使用注解的话,就不需要在配置xml了,只需要写接口就可以了,不过我建议使用注解来写静态sql语句,通过xml来写动态sql,这样更有效率。下面的有些属性什么意思,看过xml配置的基本都能从名字来转换得知它的意思。遵循方式和xml的配置方式都是差不多的。

 

静态sql情况下的使用
新增方式(@Insert)条件参数是数组,所以可以执行多条新增sql语句,格式就是@Insert(value= {" "," "," "...})

@Insert("insert into t_hus (hus_name,age,fk_wife_id) values (#{h.husbandName},#{h.age},#{h.wife.id})")
@Options(useGeneratedKeys=true,keyProperty="h.id")
void addHusbandBean(@Param("h") HusbandBean hus);
@Param("u")就是给参数取别名,在sql中去调用这个参数

 

删除方式(@Delete)条件参数是数组,所以可以执行多条删除sql语句,格式就是@Delete(value= {" "," "," "...})

@Delete({"delete from t_wife where id = #{h.wife.id};","delete from t_hus where id = #{h.id};"})
int deleteHusbandBean(@Param("h") HusbandBean hus);

 

修改方式(@Update)条件参数是数组,所以可以执行多条修改sql语句,格式就是@Update(value= {" "," "," "...})

@Update("update t_user set user_name=#{u.realName},login_name=#{u.userName},`password`=#{u.pwd},fk_role_id=#{u.userGradeValue},update_time=#{u.updateTime} where id=#{u.id}")
int updateUser(@Param("u")UserBean userBean);

 

查询方式(@Select)条件参数是数组,所以可以执行多条查询sql语句,格式就是@Select(value= {" "," "," "...})

1、@ResultType接收数据(就和xml中的resultType一样),遵循规则与xml一样(sql查询出来的列的列别名必须和对象属性一样,保持一致。可以使用Map、基本数据类型、引用数据类型接收数据;如果是Map,取别名就以别名为键,不取别名默认以列名作为键名;如果是其他数据类型,比如本数据类型这些,那么查询的返回结果必须也是与之对应的单一结果,也就是一个结果)

@Select("select id,game_name as gameName from t_game")
@ResultType(GameBean.class)
List<GameBean> findAllGameBean();

 

@Param("u")就是给参数取别名,在@Select中我们才能方便去使用这个参数,使用方法就是: 别名.属性

#{ }的作用就是取值的意思,传入对象就用#{别名.属性名};像对象这种层层结构的,比如Map就有这种结构,就可以这样去取值;如果没有这种结构,比如字符串这种单一类型,直接用#{别名} 

#{ }和${ }的作用都是取值,区别就是#{ }要进行预编译,而${ }直接编译
 

2、@Results接收数据(就是xml中的resultMap一样,属性这些就不具体说了)

@Select("select id,player_name from t_player where player_name like concat(#{p.playerName},'%')")
@Results({
@Result(id=true,property="id",column="id",javaType=Integer.class),
@Result(property="playerName",column="player_name",javaType=String.class)
@Result(property="games",javaType=List.class,column="id",many=@Many(fetchType=FetchType.LAZY,select="getGameBeanById")) 
})
List<PlayerBean> findPlayerBeanListByObject(@Param("p") PlayerBean player);

 

动态sql的使用(自定义sql语句)
用来自定义的sql语句的四个注解:@SelectProvider、@InsertProvider、@UpdateProvider、@DeleteProvider;他们就是用来顶替@Select、@Insert、@Update、@Delete的;用了这几个注解,我们就可以使用我们动态拼接的sql语句了。

这四个注解都有两个属性,type指定用的是哪个类,method指定用该类的哪个方法来实现动态sql返回

1、接口定义

@InsertProvider(type=UserSQLProvider.class,method="addBatchUserBean")
int addBatchUserBean(@Param("users") List<UserBean> users);

 

1、新建类和拼接sql的方法(不管方法中的逻辑怎么写,你只需要返回的是一个sql语句就行了)

public class UserSQLProvider {

/**
* 无法规避SQL注入的问题
* 
* 返回必须是String,因为要返回sql语句;
* 用Map<String,Object> params可以获取接口方法的参数,通过键值去获取参数值,就是接口中@Param() 取的别名去获取
* @param params 固定参数
* @return 固定返回
* @throws ParseException
*/
public String addBatchUserBean(Map<String,Object> params) throws ParseException {

StringBuilder sb = new StringBuilder("insert into t_user(login_name,user_name,user_pwd,age,gender,birthday,create_time) values ");
List<UserBean> users = (List<UserBean>) params.get("users");


//这串代码 使用的是直接编译
for (UserBean user : users) {
sb.append("('"+user.getLoginName()+"','"+user.getUserName()+"','"+user.getPassword()+"','"+user.getAge()+"','"+user.getGender()+"','"+DateUtil.date2Str(user.getBirthday(), "yyyy-MM-dd")+"',now()),");
}

String sql = sb.toString().substring(0, sb.toString().length() - 1);
System.out.println(sql);

return sql;
}

}

 

接口方法使用了@Param注解的话,那么相应sql拼装方法必须接受Map<String, Object>做为参数,通过键值去获取参数值,就是接口中@Param() 取的别名去获取。

对于只有一个参数的情况,可以直接使用,将参数直接传入sql拼接的方法。比如:

@SelectProvider(type = SqlProvider.class, method = "selectUser")
@ResultMap("userMap")
public User getUser(long userId);
public class SqlProvider {
public String selectUser(long userId) {
return "select * from user where userId=" + userId;
}
}

 

@ResultMap是我们去调取xml中的方法,所以如果都用注解了,这样调取岂不是多此一举,用@Results就行了,上面有说明。

接口中如果没有参数传入的话,就sql方法也可以不写参数。

 

级联关系:
一对一的情况(one=@One):对于丈夫来说,它有一个妻子

@Select("select id,hus_name,age,fk_wife_id from t_hus where id = #{id}")
@Results({
@Result(id=true,property="id",column="id",javaType=Integer.class),
@Result(property="husbandName",column="hus_name",javaType=String.class),
@Result(property="age",column="age",javaType=Integer.class),
@Result(property="wife",javaType=WifeBean.class,column="fk_wife_id",one=@One(fetchType=FetchType.LAZY,select="com.gezhi.mybatis01.o2omag.mapper.WifeMapper.getWifeBeanById"))
})
HusbandBean getHusbandBeanById(@Param("id")int id);

 

一对多的情况(many=@Many):对一个老师来说,他对应多个学生

@Select("select id,teacher_name,age from t_teacher where id = #{id}")
@Results({
@Result(id=true,property="id",column="id",javaType=Integer.class),
@Result(property="teacherName",column="teacher_name",javaType=String.class),
@Result(property="age",column="age",javaType=Integer.class),
@Result(property="stus",javaType=List.class,column="id",many=@Many(fetchType=FetchType.LAZY,select="findStudentBeanByFkTeacherId"))
})
TeacherBean getTeacherBeanById(@Param("id") int id);


@Select("select id,student_name as studentName,age from t_student where fk_teacher_id = #{id}")
@ResultType(StudentBean.class)
StudentBean findStudentBeanByFkTeacherId(@Param("id") int id);

 


多对多的情况(需要中间表来关联多对多的两张表,依然用many=@Many,通过中间表来查询另一张表的信息)

@Select("select g.id,g.game_name as gameName from t_game as g,t_player_game as pg where g.id = pg.fk_game_id and fk_player_id = #{id}")
@ResultType(GameBean.class)
GameBean getGameBeanById(@Param("id") int id);

/**
* 根据玩家名称查询
* @param playerName
* @return
*/

@Select("select id,player_name from t_player where player_name like concat(#{p.playerName},'%')")
@Results({
@Result(id=true,property="id",column="id",javaType=Integer.class),
@Result(property="playerName",column="player_name",javaType=String.class),
@Result(property="games",javaType=List.class,column="id",many=@Many(fetchType=FetchType.LAZY,select="getGameBeanById"))
})
List<PlayerBean> findPlayerBeanListByObject(@Param("p") PlayerBean player);

 


鉴别器的情况(其余的不说了,概念什么的,只能说一下父类是宠物pet类,子类是狗类DogBean,还有猫类CatBean)

@Select("select id,pet_name,pet_type,bone,fish from t_pet")
@Results({ 
@Result(id = true, property = "id", column = "id", javaType = Integer.class),
@Result(property = "petName", column = "pet_name", javaType = String.class) 
})
//鉴别器的配置
@TypeDiscriminator(column = "pet_type", javaType = Integer.class, cases = {
@Case(value = "0", type = DogBean.class, results = {
@Result(property="bone",column="bone",javaType=Integer.class)
}), 
@Case(value = "1", type = CatBean.class, results = {
@Result(property="fish",column="fish",javaType=Integer.class)
})
})
List<PetBean> findAllPetBean();
 

 

通过即时加载的方式也调取对象中另一对象的属性:(学生对象中含有一个老师对象)通过这种方式也可完成映射,但是就没有了延时加载的效果。

@Select("select s.id,s.student_name,s.age, t.id as tId,t.teacher_name,t.age as tAge from t_student as s,t_teacher as t where s.fk_teacher_id = t.id")
@Results({
@Result(id=true,property="id", column="id",javaType=Integer.class),
@Result(property="studentName",column="student_name",javaType=String.class),
@Result(property="age",column="age",javaType=Integer.class),
@Result(property="teacher.id",column="tId",javaType=Integer.class),
@Result(property="teacher.teacherName",column="teacher_name",javaType=String.class),
@Result(property="teacher.age",column="tAge",javaType=Integer.class)
})
List<StudentBean> findAllStudentBeanAndTeacherBean();

 

动态sql:https://www.cnblogs.com/jhj117/p/5388748.html

注解的使用:https://blog.csdn.net/wfq784967698/article/details/78786001

posted @ 2019-11-14 09:45  门罗的魔术师  阅读(300)  评论(0编辑  收藏  举报