Mybatis 也可以使用注解开发方式,这样我们就可以减少编写 Mapper 映射文件了。先围绕一些基本的 CRUD 来学习。
环境搭建
老样子,创建maven工程,配置好pom.xml文件,把实体类以及接口建好,主配置文件不要忘了加上
<typeAliases>
<package name="cn.junko.domain"/>
</typeAliases>
········
<mappers>
<!--指定带有注解的dao接口所在位置-->
<package name="cn.junko.dao"/>
</mappers>
在DAO接口的方法中添加注解,先测试一下select
@Select(value = "select * from user")
List<User> findAll();
value可以省略
@Test
public void testSelect(){
List<User> users = userDao.findAll();
for (User user : users) {
System.out.println(user);
}
}
测试是可以在控制台输出数据的。 有一点需要注意,当使用注解开发的时候,不能同时在同一个dao下存在映射文件xml,不然必定会报错!
单表CRUD
/**
* 插入操作
* @param user
*/
@Insert("insert into user (username,address,sex,birthday) values (#{username},#{address},#{sex},#{birthday})")
void saveUser(User user);
/**
* 更新
* @param user
*/
@Update("update user set username=#{username},address=#{address} where id = #{id}")
void updateUser(User user);
/**
* 删除
*/
@Delete("delete from user where id=${id}")
void deleteUser(Integer id);
- 还有一些条件查询、模糊查询等的单表简单操作就不列出来了
- 在dao层写好注解之后,测试类里面的方法过程和之前一样
注解建立实体类属性名与表列名的对应关系
虽然属性名与列名之间不区分大小写,但是当实体类中的每个属性名和数据库表中的列名内容长度对应不上,那一开始的注解语句肯定是不能获取到自己想要的结果。
- 方法一:起别名
但是这个方法会导致我们要对每一条注解语句起别名,工作量太大
- 方法二:
@Results
注解
代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合 @Results({@Result(),@Result()})或@Results(@Result())
使用方法:在dao层添加注解Results
@Select("select * from user")
@Results(id = "resultMap",value = {
@Result(id=true,column = "id",property = "userId"),
@Result(column = "address",property = "userAddress"),
@Result(column = "sex",property = "userSex"),
})
List<User> findAll();
- id:是否是主键字段
- column:数据库的列名
- property:需要装配的属性名
当把上面的一段写完之后,就相当于把需要对应的数据都对应上了,可以继续测试是否成功。
其他方法也不需要再写一遍上面的一段代码,只要添加resultMap
注解,把Results
注解的id传过来即可
@Insert("insert into user (username,address,sex,birthday) values (#{username},#{address},#{sex},#{birthday})")
@ResultMap(value = {"resultMap"})
void saveUser(User user);
多表查询
* 一对一(多对一)
在@Result
注解中还有两个属性,分别是one和many
@One 注解(一对一)
代替了<assocation>
标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍:
select 指定用来多表查询的 sqlmapper。
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。。
使用格式: @Result(column=" ",property="",one=@One(select=""))
Account表实现一对多查询
//Account表对应实体类
public class Account implements Serializable {
private Integer id;
private Integer uid;
private Double money;
// 多对一(一对一)
private User user;
//setter....getter....toString....
}
//User表对应实体类
public class User implements Serializable {
private Integer id;
private String username;
private String sex;
private String address;
private Date birthday;
//setter....getter....toString....
}
//AccountDao接口层
public interface AccountDao {
@Select("select * from account")
@Results(id="accountMap",value = {
@Result(id=true,column = "id",property = "id"),
@Result(column = "uid",property = "uid"),
@Result(column = "money",property = "money"),
@Result(property = "user",column = "uid",
one=@One(select ="cn.junko.dao.UserDao.findByID",fetchType = FetchType.EAGER)),
})
List<Account> findAll();
}
//UserDao接口层
@Select("select * from user where id=#{uid}")
@ResultMap(value = {"resultMap"})
User findByID(Integer id);
这里我们通过Account的findAll方法,查询到账户的数据,再把账户表中的uid传给user,通过UserDao的findById方法查询到每个账户对应的每个用户。
select * from user where id= #{uid}
* 一对多
在原先的User实体类添加一个List<Account>
集合,Account类不需改变
//User实体类
public class User implements Serializable {
private Integer id;
private String username;
private String sex;
private String address;
private Date birthday;
//一对多关系映射,一个用户对应多个账户
private List<Account> accounts;
public List<Account> getAccounts() {
return accounts;
}
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
//setter....getter....toString....
}
@Many注解(一对多)
代替了<Collection>
标签,是多表查询的关键,在注解中用来指定子查询返回对象集合。
使用格式:@Result(property="",column="",many=@Many(select=""))
////UserDao接口层
@Select("select * from user")
@Results(id = "resultMap",value = {
@Result(id=true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "address",property = "address"),
@Result(column = "sex",property = "sex"),
@Result(column = "birthday",property = "birthday"),
@Result(property = "accounts",column = "id",
many = @Many(select = "cn.junko.dao.AccountDao.findAccountByUid",fetchType = FetchType.LAZY)),
})
List<User> findAll();
//AccountDao接口层提供根据用户id查询账户的方法
/**
* 根据用户ID查询账户
* @param id
* @return
*/
@Select("select * from account where uid=#{userid}")
List<Account> findAccountByUid(Integer id);