Mybatis_12 Mybatis注解开发

一、基于注解的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);

}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值