Mybatis基于注解实现多表查询功能
对应的四种数据库表关系中存在四种关系:一对多,多对应,一对一,多对多。在前文中已经实现了xml配置方式实现表关系的查询,本文记录一下mybatis怎么通过注解实现多表的查询,算是一个知识的补充。
同样的先介绍一下demo的情况:存在两个实体类用户类和账户类,用户类可能存在多个账户,即一对多的表关系。每个账户只能属于一个用户,即一对一或者多对一关系。我们最后实现两个方法,第一个实现查询所有用户信息并同时查询出每个用户的账户信息,第二个实现查询所有的账户信息并且同时查询出其所属的用户信息。
1.项目结构
2.领域类
public class account implements serializable{ private integer id; private integer uid; private double money; private user user; //加入所属用户的属性 省略get 和set 方法............................. } public class user implements serializable{ private integer userid; private string username; private date userbirthday; private string usersex; private string useraddress; private list<account> accounts; 省略get 和set 方法............................. }
在user中因为一个用户有多个账户所以添加account的列表,在account中因为一个账户只能属于一个user,所以添加user的对象。
3.dao层
public interface accountdao { /** *查询所有账户并同时查询出所属账户信息 */ @select("select * from account") @results(id = "accountmap",value = { @result(id = true,property = "id",column = "id"), @result(property = "uid",column = "uid"), @result(property = "money",column = "money"), //配置用户查询的方式 column代表的传入的字段,一对一查询用one select 代表使用的方法的全限定名, fetchtype表示查询的方式为立即加载还是懒加载 @result(property = "user",column = "uid",one = @one(select = "com.example.dao.userdao.findbyid",fetchtype = fetchtype.eager)) }) list<account> findall(); /** * 根据用户id查询所有账户 * @param id * @return */ @select("select * from account where uid = #{id}") list<account> findaccountbyuid(integer id); } public interface userdao { /** * 查找所有用户 * @return */ @select("select * from user") @results(id = "usermap",value = {@result(id = true,column = "id",property = "userid"), @result(column = "username",property = "username"), @result(column = "birthday",property = "userbirthday"), @result(column = "sex",property = "usersex"), @result(column = "address",property = "useraddress"), @result(column = "id",property = "accounts",many = @many(select = "com.example.dao.accountdao.findaccountbyuid",fetchtype = fetchtype.lazy)) }) list<user> findall(); /** * 保存用户 * @param user */ @insert("insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})") void saveuser(user user); /** * 更新用户 * @param user */ @update("update user set username=#{username},birthday=#{birthday},sex=#{sex},address=#{address} where id=#{id}") void updateuser(user user); /** * 删除用户 * @param id */ @delete("delete from user where id=#{id}") void deleteuser(integer id); /** * 查询用户根据id * @param id * @return */ @select("select * from user where id=#{id}") @resultmap(value = {"usermap"}) user findbyid(integer id); /** * 根据用户名称查询用户 * @param name * @return */ // @select("select * from user where username like #{name}") @select("select * from user where username like '%${value}%'") list<user> findbyusername(string name); /** * 查询用户数量 * @return */ @select("select count(*) from user") int findtotaluser();
在findall()方法中配置@results的返回值的注解,在@results注解中使用@result配置根据用户和账户的关系而添加的属性,user中的属性list<account>一个用户有多个账户的关系的映射配置:@result(column = "id",property = "accounts",many = @many(select = "com.example.dao.accountdao.findaccountbyuid",fetchtype = fetchtype.lazy)),
使用@many来向mybatis表明其一对多的关系,@many中的select属性对应的accountdao中的findaccountbyuid方法的全限定名,fetchtype代表使用立即加载或者延迟加载,因为这里为一对多根据前面的讲解,懒加载的使用方式介绍一对多关系一般使用延迟加载,所以这里配置为lazy方式。在account中存在多对一或者一对一关系,所以配置返回值属性时使用:@result(property = "user",column = "uid",one = @one(select = "com.example.dao.userdao.findbyid",fetchtype = fetchtype.eager)),
property代表领域类中声明的属性,column代表传入后面select语句中的参数,因为这里为一对一或者说为多对一,所以使用@one注解来描述其关系,eager表示使用立即加载的方式,select代表查询本条数据时所用的方法的全限定名,fetchtype代表使用立即加载还是延迟加载。
4.demo中mybatis的配置
<?xml version="1.0" encoding="utf-8" ?> <!doctype configuration public "-//mybatis.org//dtd config 3.0//en" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <settings> <!--<!–开启全局的懒加载–>--> <!--<setting name="lazyloadingenabled" value="true"/>--> <!--<!–关闭立即加载,其实不用配置,默认为false–>--> <!--<setting name="aggressivelazyloading" value="false"/>--> <!--开启mybatis的sql执行相关信息打印--> <setting name="logimpl" value="stdout_logging" /> <!--<setting name="cacheenabled" value="true"/>--> </settings> <typealiases> <typealias type="com.example.domain.user" alias="user"/> <package name="com.example.domain"/> </typealiases> <environments default="test"> <environment id="test"> <!--配置事务--> <transactionmanager type="jdbc"></transactionmanager> <!--配置连接池--> <datasource type="pooled"> <property name="driver" value="com.mysql.jdbc.driver"/> <property name="url" value="jdbc:mysql://localhost:3306/test1"/> <property name="username" value="root"/> <property name="password" value="123456"/> </datasource> </environment> </environments> <mappers> <package name="com.example.dao"/> </mappers> </configuration>
主要是记得开启mybatis中sql执行情况的打印,方便我们查看执行情况。
5.测试
(1)测试查询用户同时查询出其账户的信息
测试代码:
public class usertest { private inputstream in; private sqlsessionfactory sqlsessionfactory; private sqlsession sqlsession; private userdao userdao; @before public void init()throws exception{ in = resources.getresourceasstream("sqlmapconfig.xml"); sqlsessionfactory = new sqlsessionfactorybuilder().build(in); sqlsession = sqlsessionfactory.opensession(); userdao = sqlsession.getmapper(userdao.class); } @after public void destory()throws exception{ sqlsession.commit(); sqlsession.close(); in.close(); } @test public void testfindall(){ list<user> userlist = userdao.findall(); for (user user: userlist){ system.out.println("每个用户信息"); system.out.println(user); system.out.println(user.getaccounts()); } }
测试结果:
(2)查询所有账户信息同时查询出其所属的用户信息
测试代码:
public class accounttest { private inputstream in; private sqlsessionfactory sqlsessionfactory; private sqlsession sqlsession; private accountdao accountdao; @before public void init()throws exception{ in = resources.getresourceasstream("sqlmapconfig.xml"); sqlsessionfactory = new sqlsessionfactorybuilder().build(in); sqlsession = sqlsessionfactory.opensession(); accountdao = sqlsession.getmapper(accountdao.class); } @after public void destory()throws exception{ sqlsession.commit(); sqlsession.close(); in.close(); } @test public void testfindall(){ list<account> accountlist = accountdao.findall(); for (account account: accountlist){ system.out.println("查询的每个账户"); system.out.println(account); system.out.println(account.getuser()); } } }
测试结果:
总结
以上所述是小编给大家介绍的mybatis基于注解实现多表查询功能,希望对大家有所帮助
推荐阅读
-
基于vue.js实现分页查询功能
-
mybatis基于注解实现增删改查(详细介绍)
-
Mybatis、Mybatis-Plus多表联合查询,通过注解实现,自定义SQL参考实现
-
MyBatis多表操作查询功能
-
Oracle使用MyBatis中RowBounds实现分页查询功能
-
springboot整合mybatis-plus 实现分页查询功能
-
asp.net实现的MVC跨数据库多表联合动态条件查询功能示例
-
FeignClient原理解析,100行代码实现feign功能,mybatis的mapper、dubbo、feign实现原理模拟。spring扫描自定义注解原理。Javassist实现动态代理原理
-
springboot+mybatis配置clickhouse实现插入查询功能
-
springboot整合mybatis实现多表查询的实战记录