MyBatis的注解配置

之前我们MaBatis的增删改查,关联映射、动态SQL语句等知识,其所有配置都是通过XML完成的,编写大量的XML配置比较繁琐。注解还是更简单一点的,从章节分配上就能看出来,前面的写了三章,注解的就一章搞定

基于注解的单表增删改查

1.既然时要基于注解,那就要把之前基于xml的删掉然后再mapper下新建一个接口

package com.mybatis.mapper;

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.mybatis.pojo.UserInfo;

public interface UserInfoMapper {
	//根据用户编号查询用户
	@Select("select * from user_info where id=#{id}")
	public UserInfo findUserInfoById(int id);
	//根据用户名模糊查询用户
	@Select("select * from user_info where userName like CONCAT(CONCAT('%',#{userName}),'%')")
	public List<UserInfo> findUserInfoByUserName(String userName);
	//添加用户
	@Insert("insert into user_info(userName,password) values (#{userName},#{password})")
	public int addUserInfo(UserInfo ui);
	//修改用户
	@Update("update user_info set userName=#{userName},password=#{password} where id=#{id}")
	public int updateUserInfo(UserInfo ui);
	//删除用户
	@Delete("delete from user_info where id=#{id}")
	public int deleteUserInfo(int id);
}

在mybatis-config.xml文件中引用接口配置

<!-- 引用接口文件 -->
	<mappers>
		<mapper class="com.mybatis.mapper.UserInfoMapper"/>
	</mappers>

修改测试类方法,全部用接口来实现,只举两个例子
在这里插入图片描述
运行结果和之前一样,没啥好说的,主要是简单了好多,省去了配置xml过程(其实感觉也没简单多少,还要多学一章,多记一些东西。。。)

基于注解的一对一关联映射

还是以idcard和person数据表为例,基于注解配置实现这两张表之间的一对一关联映射:
1.写IdcardMapper接口和PersonMapper接口

package com.mybatis.mapper;

import org.apache.ibatis.annotations.Select;

import com.mybatis.pojo.Idcard;

public interface IdcardMapper {
	//根据id查询身份证信息
	@Select("select * from idcard where id=#{id}")
	public Idcard findIdcardById(int id);
}

package com.mybatis.mapper;

import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.mybatis.pojo.Person;

public interface PersonMapper {
	//根据个人id编号查询个人信息
	@Select("select * from person where id = #{id}")
	//但person还有个关联属性Idcard,所以我们这里要手动完成映射
	@Results({@Result(column = "cid",property = "idcard",one = @One(select = "com.mybatis.mapper.IdcardMapper.findIdcardById"))})
	public Person findPersonById(int id);
}

这里注意:Person对象中的基本属性可以自动完成结果映射,而关联的对象属性idcard需要手工完成映射。这里@Results注解中使用了一个@Result注解来映射关联结果。在@Result注解中,property属性用来指定关联属性,one属性用来指定数据表属于那种关联关系,通过@One注解表明数据表idcard和person是一对一关联关系。
在@One注解中,select属性用于指定关联属性idcard的值是通过IdcardMapper接口里定义的findIdcardById方法获得的
@Result注解的column属性用于指定传入findIdardById(int id)方法的参数名,这里为cid,表示从数据表person查询出的cid字段值

2.添加接口文件的引用

<!-- 引用接口文件 -->
	<mappers>
		<mapper class="com.mybatis.mapper.UserInfoMapper"/>
		<mapper class="com.mybatis.mapper.IdcardMapper"/>
		<mapper class="com.mybatis.mapper.PersonMapper"/>
	</mappers>

3.编写测试方法

//测试一对一关联映射
	@Test
	public void testOne2One() {
		PersonMapper pm = sqlSession.getMapper(PersonMapper.class);
		Person person = pm.findPersonById(1);
		System.out.println(person.toString());
	}

运行结果还就那样
在这里插入图片描述

基于注解的一对多关联映射

0.实体类如下
在这里插入图片描述
在这里插入图片描述
1.创建接口ProductInfoMapper接口和TypeMapper接口

package com.mybatis.mapper;

import java.util.List;

import org.apache.ibatis.annotations.One;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.mybatis.pojo.ProductInfo;

public interface ProductInfoMapper {	
	//根据商品类型编号查询所有商品
	@Select("select * from product_info where tid=#{tid}")
	List<ProductInfo> findProductInfoByTid(int tid);
	//根据商品编号来查询商品信息
	@Select("select * from product_info where id = #{id}")
	@Results({@Result(column = "tid",property = "type",one = @One(select = "com.mybatis.mapper.TypeMapper.findTypeById"))})
	ProductInfo findProductInfoById(int id);
}

package com.mybatis.mapper;

import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.mybatis.pojo.Type;

public interface TypeMapper {
	//根据商品类型编号查询商品类型信息
	@Select("select * from type where id=#{id}")
	@Results({@Result(id = true,column = "id",property = "id"),
		@Result(column = "name",property = "name"),
		@Result(column = "id",property = "pis",many = @Many(select = "com.mybatis.mapper.ProductInfoMapper.findProductInfoByTid"))})
	Type findTypeById(int id);
}

2.引用接口文件
在这里插入图片描述
3.写测试方法
在这里插入图片描述
测试testOne2Many结果部分截取

DEBUG [main] - ==>  Preparing: select * from type where id=? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - ====>  Preparing: select * from product_info where tid=? 
DEBUG [main] - ====> Parameters: 1(Integer)
DEBUG [main] - <====      Total: 6
DEBUG [main] - <==      Total: 1
Type [id=1, name=电脑, pis=[ProductInfo [id=1, code=1378538, name=AppleMJVE2CH/A], ProductInfo [id=2, code=1309456, name=ThinkPadE450C(20EH0001CD)], ProductInfo [id=3, code=1999938, name=联想小新300经典版], ProductInfo [id=4, code=1466274, name=华硕FX50JX], ProductInfo [id=5, code=1981672, name=华硕FL5800], ProductInfo [id=6, code=1904696, name=联想G50-70M]]]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@352c1b98]

测试testMany2One结果部分截取

DEBUG [main] - ==>  Preparing: select * from product_info where id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - ====>  Preparing: select * from type where id=? 
DEBUG [main] - ====> Parameters: 1(Integer)
DEBUG [main] - ======>  Preparing: select * from product_info where tid=? 
DEBUG [main] - ======> Parameters: 1(Integer)
DEBUG [main] - <======      Total: 6
DEBUG [main] - <====      Total: 1
DEBUG [main] - <==      Total: 1
ProductInfo [id=1, code=1378538, name=AppleMJVE2CH/A]
Type [id=1, name=电脑, pis=[ProductInfo [id=1, code=1378538, name=AppleMJVE2CH/A], ProductInfo [id=2, code=1309456, name=ThinkPadE450C(20EH0001CD)], ProductInfo [id=3, code=1999938, name=联想小新300经典版], ProductInfo [id=4, code=1466274, name=华硕FX50JX], ProductInfo [id=5, code=1981672, name=华硕FL5800], ProductInfo [id=6, code=1904696, name=联想G50-70M]]]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@352c1b98]

基于注解的多对多关联映射

其实跟一对多的差不多
两个接口:

package com.mybatis.mapper;

import java.util.List;

import org.apache.ibatis.annotations.Select;

import com.mybatis.pojo.Functions;

public interface FunctionMapper {
	//根据管理员id获取其功能权限列表
	@Select("select * from functions where id in (select fid from powers where aid = #{id})")
	List<Functions> findFunctionsByAid(int aid);
}

package com.mybatis.mapper;

import org.apache.ibatis.annotations.Many;
import org.apache.ibatis.annotations.Result;
import org.apache.ibatis.annotations.Results;
import org.apache.ibatis.annotations.Select;

import com.mybatis.pojo.AdminInfo;

public interface AdminInfoMapper {
	//根据管理员id获取管理员信息
	@Select("select * from admin_info where id = #{id}")
	@Results({@Result(id = true,column = "id",property = "id"),
		@Result(column = "name" ,property = "name"),
		@Result(column = "id",property = "fs",many = @Many(select = "com.mybatis.mapper.FunctionMapper.findFunctionsByAid"))})
	public AdminInfo findAdminInfoById(int id);
}

配置接口
在这里插入图片描述
测试方法

	//测试多对多关联映射
	@Test
	public void testM2M() {
		AdminInfoMapper aim = sqlSession.getMapper(AdminInfoMapper.class);
		AdminInfo adminInfo = aim.findAdminInfoById(1);
		System.out.println(adminInfo.toString());
	}

运行结果

DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@258d79be]
DEBUG [main] - ==>  Preparing: select * from admin_info where id = ? 
DEBUG [main] - ==> Parameters: 1(Integer)
DEBUG [main] - ====>  Preparing: select * from functions where id in (select fid from powers where aid = ?) 
DEBUG [main] - ====> Parameters: 1(Integer)
DEBUG [main] - <====      Total: 10
DEBUG [main] - <==      Total: 1
AdminInfo [id=1, name=admin, fs=[Functions [id=1, name=电子商城管理后台], Functions [id=2, name=商品管理], Functions [id=3, name=商品列表], Functions [id=4, name=商品类型列表], Functions [id=5, name=订单管理], Functions [id=6, name=查询订单], Functions [id=7, name=创建订单], Functions [id=8, name=用户管理], Functions [id=9, name=用户列表], Functions [id=11, name=退出系统]]]
DEBUG [main] - Resetting autocommit to true on JDBC Connection [com.mysql.jdbc.JDBC4Connection@258d79be]

基于注解的动态SQL

对应的运行结果效果上一张有,这个就是换了种方式实现,达到的目的,效果一样,这里能省我就省了,去动态sql那一章看。

@SelectProvider

数据表参照动态SQL那一章的笔记,用的是同一个数据库,数据表。
1.修改UserInfoMapper接口

package com.mybatis.mapper;

import java.util.List;
import java.util.Map;

import org.apache.ibatis.annotations.SelectProvider;

import com.mybatis.pojo.UserInfo;

public interface UserInfoMapper {
	@SelectProvider(type = UserInfoDynaSqlProvider.class,method = "selectWithParam")
	List<UserInfo> findUserInfoByCond(Map<String, Object> param);
}

2.在统一包下去写那个UserInfoDynaSqlProvider类,添加方法和说起来语句

package com.mybatis.mapper;

import java.util.Map;

import org.apache.ibatis.jdbc.SQL;

public class UserInfoDynaSqlProvider {
	public String selectWithParam(Map<String, Object> param) {
		return new SQL() {
			{
				SELECT("*");
				FROM("user_info");
				if (param.get("id")!=null) {
					WHERE("id = #{id}");
				}
				if (param.get("userName") !=null) {
					WHERE("userName=#{userName}");
				}
				if (param.get("password") !=null) {
					WHERE("password=#{password}");
				}
			}
		}.toString();
	}
}

这个格式挺复杂的,我查了几遍最后搞定,觉得这个要比直接用动态sql要麻烦
3.添加接口文件的引用

<mappers>
		<mapper class="com.mybatis.mapper.UserInfoMapper" />
	</mappers>

4.添加测试方法

@Test
	public void testFindUserInfoByCond() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("userName", "tom");
		param.put("password", "123456");
		List<UserInfo> list = uim.findUserInfoByCond(param);
		for (UserInfo userInfo : list) {
			System.out.println(userInfo.toString());
		}
	}

5.运行结果:

DEBUG [main] - Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7e19ebf0]
DEBUG [main] - ==>  Preparing: SELECT * FROM user_info WHERE (userName=? AND password=?) 
DEBUG [main] - ==> Parameters: tom(String), 123456(String)
DEBUG [main] - <==      Total: 1
UserInfo [id=1, userName=tom, password=123456]
@InsertProvider注解

1.在接口UserInfoMapper中添加新的方法与注解

@InsertProvider(type = UserInfoDynaSqlProvider.class,method = "insertUserInfo")
	@Options(useGeneratedKeys = true,keyProperty = "id")
	int insertUserInfo(UserInfo ui);

其中@Options(useGeneratedKeys = true,keyProperty = "id")
这样在向user_info插入数据时,自动将主键id的自增值赋值给对象ui的属性id
在UserInfoDynaSqlProvider 类中新增一个方法

public String insertUserInfo(UserInfo ui) {
		return new SQL() {
			{
				INSERT_INTO("user_info");
				if (ui.getUserName() != null) {
					VALUES("userName","#{userName}");
				}
				if (ui.getPassword() != null) {
					VALUES("password","#{password}");
				}
			}
		}.toString();
	}

添加测试类

@Test
	public void testInsertUserInfo() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		UserInfo ui = new UserInfo();
		ui.setUserName("tt");
		ui.setPassword("xx");
		uim.insertUserInfo(ui);
		System.out.println(ui.getId());
	}

运行结果
在这里插入图片描述
不加@Options(useGeneratedKeys = true,keyProperty = "id")的话虽说在数据库中插入成功了,但是这里却并得不到id值,会显示0.

@UpdateProvider
@UpdateProvider(type = UserInfoDynaSqlProvider.class,method = "updateUserInfo")
	int updateUserInfo(UserInfo ui);
public String updateUserInfo(UserInfo ui) {
		return new SQL() {
			{
				UPDATE("user_info");
				if (ui.getUserName() != null) {
					SET("userName = #{userName}");
				}
				if (ui.getPassword() != null) {
					SET("password = #{password}");
				}
				WHERE("id=#{id}");
			}
		}.toString();
	}
@Test
	public void testUpdateUserInfo() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("id", 1);
		UserInfo uInfo = uim.findUserInfoByCond(param).get(0);//0是取出第一个元素
		uInfo.setPassword("55555");
		uim.updateUserInfo(uInfo);
	}

在这里插入图片描述

DeleteProvide注解
@DeleteProvider(type = UserInfoDynaSqlProvider.class,method = "deleteUserInfo")
	void deleteUserInfo(Map<String, Object> param);
public String deleteUserInfo(Map<String, Object> param) {
		return new SQL() {
			{
				DELETE_FROM("user_info");
				if (param.get("id")!=null) {
					WHERE("id = #{id}");
				}
				if (param.get("userName")!=null) {
					WHERE("userName = #{userName}");
				}
				if (param.get("password")!=null) {
					WHERE("password = #{password}");
				}
			}
		}.toString();
	}
@Test
	public void testDeleteUserInfo() {
		UserInfoMapper uim = sqlSession.getMapper(UserInfoMapper.class);
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("userName", "tt");
		param.put("password", "xx");
		uim.deleteUserInfo(param);
	}

就删掉了
其实用习惯了也蛮方便的

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值