文章目录
一、基于注解的CRUD操作
package com.song.dao;
import java.util.List;
import org.apache.ibatis.annotations.Delete;
import org.apache.ibatis.annotations.Insert;
import org.apache.ibatis.annotations.Select;
import org.apache.ibatis.annotations.Update;
import com.song.domain.User;
/**
* 在mybatis中针对,CRUD有四个注解
* @Select @Insert @Delete @Update
* //value可以省略
*/
public interface IUserDao {
/**
* 查询所有用户
* @return
*/
@Select("select * from user")
List<User> findAll();
/**
* 添加用户
* @param user
*/
@Insert("insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday})")
void saveUser(User user);
@Delete("delete from user where id>#{uid}")
void deleteUser(Integer id);
@Update("update user set address=#{address},sex=#{sex} where id=#{id}")
void updateUser(User user);
//根据id查询
@Select("select * from user where id=#{uid}")
User findById(Integer id);
//根据姓名模糊查找
@Select("select * from user where username like #{username}")
List<User> findByName(String username);
//查询总条数
@Select("select count(id) from user")
int findTotal();
}
二、解决基于注解的SQL字段和实体类属性名不一致
1、实体类
public class User implements Serializable{
private Integer userId;
private String userName;
private String userAddress;
private String userSex;
private Date userBirthday;
...//
}
2、持久层接口
public interface IUserDao {
/**
问题:使得数据库和实体类字段一一对应
Results
id属性:配置一个名字在想用的地方都可以引用。
引用方式:@ResultMap(value = {"userMap"})
注意:
如果@ResultMap中只有一个属性 value是可以省略的
@ResultMap({"userMap"})
如果数组中只有一个元素大括号是可以省略的
@ResultMap("userMap")
Result:
id属性:确定是否为主键
@return
*/
@Select("select * from user")
@Results(id = "userMap",value = {
@Result(id=true,column = "id",property = "userId"),//id默认false
@Result(column = "username",property = "userName"),
@Result(column = "birthday",property = "userBirthday"),
@Result(column = "sex",property = "userSex"),
@Result(column = "address",property = "userAddress")
})
List<User> findAll();//查询所有用户
//根据id查询
@ResultMap(value = {"userMap"})//使得数据库和实体类字段一一对应
@Select("select * from user where id=#{uid}")
User findById(Integer id);
//根据姓名模糊查找
@ResultMap(value = {"userMap"})//使得数据库和实体类字段一一对应
@Select("select * from user where username like #{username}")
List<User> findByName(String username);
}
三、多表注解
实现复杂关系映射之前我们可以在映射文件中通过配置来实现,在使用注解开发时我们需要借助@Results 注解,@Result 注解,@One 注解,@Many 注解。
1、复杂关系映射的注解说明
@Results 注解
代替的是标签<resultMap>
该注解中可以使用单个@Result 注解,也可以使用@Result 集合
@Results({@Result(),@Result()})或@Results(@Result())
@Result 注解
代替了 <id>标签和<result>标签
@Result中属性介绍:
id 是否是主键字段
column 数据库的列名
property 需要装配的属性名
one 需要使用的@One 注解(@Result(one=@One)()))
many 需要使用的@Many 注解(@Result(many=@many)()))
@One 注解(一对一)
代替了<assocation>标签,是多表查询的关键,在注解中用来指定子查询返回单一对象。
@One 注解属性介绍:
select 指定用来多表查询的 sqlmapper
fetchType 会覆盖全局的配置参数 lazyLoadingEnabled。。
使用格式:
@Result(column=" ",property="",one=@One(select=""))
@Many 注解(多对一)
代替了<Collection>标签,是是多表查询的关键,在注解中用来指定子查询返回对象集合。
注意:
聚集元素用来处理“一对多”的关系。需要指定映射的 Java 实体类的属性,属性的javaType(一般为 ArrayList)但是注解中可以不定义;
使用格式:
@Result(property="",column="",many=@Many(select=""))
2、基于注解的多表查询之一对一
案例:一个账户对应一个用户
需求:
加载账户信息时并且加载该账户的用户信息,根据情况可实现延迟加载。(注解方式实现)
(1)实体类
public class User implements Serializable{
private Integer id;
private String username;
private String address;
private String sex;
private Date birthday;
...//
}
public class Account implements Serializable{
private Integer id;
private Integer uid;
private double money;
//创建一个多对一(Mybatis称之为一对一)的对应关系的映射,一个关系只能对应一个用户
//还要获得账户下所属的用户信息
private User user;
public void setUser(User user) {
this.user = user;
}
public User getUser() {
return user;
}
...//
}
(2)持久层接口
IAccountDao.java
/**
* //问题:一对一的是实现?
* 对一:立即加载
* 对多:延迟加载
*/
public interface IAccountDao {
/**
* 查询所有账户,并且获取每个账户所属的用户信息
* @return
*/
@Results(id = "resultMap",value = {
@Result(id=true,column = "id",property ="id" ),
@Result(column = "uid",property="uid"),
@Result(column = "money",property="money"),
//property为要封装的User
//column属性:使用UID字段去查com.song.dao.IUserDao.findById
/**
* one属性:实现立即加载
* select属性:就是要指向 可以实现功能的方法 的全限定名(接口)
* fetchType属性:控制加载方式
* 立即加载:fetchType=FetchType.EAGER
* 懒加载:fetchType=FetchType.LAZY
* @return
*/
@Result(property = "user",column = "uid",one=
@One(select="com.song.dao.IUserDao.findById",
fetchType=FetchType.EAGER))
})
@Select("Select * from account")
List<Account> findAll();
}
IUserDao.java
public interface IUserDao {
//根据id查询
@Select("select * from user where id=#{uid}")
User findById(Integer id);
}
(3)测试类
@Test//查询所有
public void testfindAll() {
List<Account> accounts=accountDao.findAll();
for(Account account:accounts) {
System.out.print("每个账户的信息");
System.out.println(account);
System.out.println(account.getUser());
}
}
(4)测试结果
3、基于注解的多表查询之一对多
案例: 一个用户对应多个账户。
需求:
查询用户信息时,也要查询他的账户列表。使用注解方式实现。
分析:
一个用户具有多个账户信息,所以形成了用户(User)与账户(Account)之间的一对多关系。
(1)实体类
public class Account implements Serializable{
private Integer id;
private Integer uid;
private double money;
...//
}
public class User implements Serializable{
private Integer userId;
private String userName;
private String userAddress;
private String userSex;
private Date userBirthday;
//创建关系映射:一个用户对应多个账户关系映射
private List<Account> accounts;
public void setAccounts(List<Account> accounts) {
this.accounts = accounts;
}
public List<Account> getAccounts() {
return accounts;
}
...//
}
(2)持久层接口
IUserDao.java接口
/**
* 在mybatis中针对,CRUD有四个注解
* @Select @Insert @Delete @Update
* //value可以省略
*/
public interface IUserDao {
/**
* Results id属性:配置一个名字在想用的地方都可以引用。
* //使得数据库和实体类字段一一对应
* @ResultMap(value = {"userMap"})
* 注意:
* 如果@ResultMap中只有一个属性 value是可以省略的
* @ResultMap({"userMap"})
* 如果数组中只有一个元素大括号是可以省略的
* @ResultMap("userMap")
*
* Result id属性:确定是否为主键
*
* @return
*/
@Select("select * from user")
@Results(id = "userMap",value = {//id默认false
@Result(id=true,column = "id",property = "id"),
@Result(column = "username",property = "username"),
@Result(column = "birthday",property = "birthday"),
@Result(column = "sex",property = "sex"),
@Result(column = "address",property = "address"),
@Result(column = "id",property = "accounts",many =
@Many(select = "com.song.dao.IAccountDao.findAccountById",
fetchType=FetchType.LAZY))
})
List<User> findAll();//查询所有用户
}
IAccountDao.java接口
/**
* //问题:一对一的是实现?
* 对一:立即加载
* 对多:延迟加载
* @author 宋强
*
*/
public interface IAccountDao {
@Select("Select * from account where uid=#{uid}")
List<Account> findAccountById(Integer uid);
}
(3)测试类
@Test//查询所有
public void testfindAll() {
List<User> users=userDao.findAll();
for(User user:users) {
System.out.println(user);
System.out.println(user.getAccounts());
}
}
(4)测试结果
四、基于注解的二级缓存
1、配置SQLMapConfig.xml
<!-- 配置开启二级缓存 -->
<settings>
<setting name="cacheEnabled" value="true"/>
</settings>
2、持久层接口
//mybatis 基于注解方式实现配置二级缓存
@CacheNamespace(blocking = true)
public interface IUserDao {
//根据id查询
@Select("select * from user where id=#{uid}")
User findById(Integer id);
}