Mybatis20_mybatis注解开发9
一、Mybatis的常用注解
这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。
@Insert:实现新增
@Update:实现更新
@Delete:实现删除
@Select:实现查询
@Result:实现结果集封装
@Results:可以与@Result 一起使用,封装多个结果集
@One:实现一对一结果集封装
@Many:实现一对多结果集封装
二、xml完成基本的crud(Mybatis的增删改查)
User.java
package com.itheima.domain; import java.util.Date; public class User { private int id; private String username; private String password; private Date birthday; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", birthday=" + birthday + '}'; } }
UserMapper.java
package com.itheima.mapper; import com.itheima.domain.User; import java.util.List; public interface UserMapper { public void save(User user); public void update(User user); public void delete(int id); public User findById(int id); public List<User> findAll(); }
UserMapper.xml
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.itheima.mapper.UserMapper"> <insert id="save" parameterType="user"> insert into user values(#{id},#{username},#{password},#{birthday}) </insert> <update id="update" parameterType="user"> update user set username=#{username},password=#{password} where id=#{id} </update> <delete id="delete" parameterType="int"> delete from user where id=#{id} </delete> <select id="findById" parameterType="int" resultType="user"> select * from user where id=#{id} </select> <select id="findAll" resultType="user"> select * from user </select> </mapper>
jdbc.properties
jdbc.driver=com.mysql.jdbc.Driver jdbc.url=jdbc:mysql://localhost:3306/test jdbc.username=root jdbc.password=root
log4j.properties
### direct log messages to stdout ### log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.Target=System.out log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### direct messages to file mylog.log ### log4j.appender.file=org.apache.log4j.FileAppender log4j.appender.file.File=c:/mylog.log log4j.appender.file.layout=org.apache.log4j.PatternLayout log4j.appender.file.layout.ConversionPattern=%d{ABSOLUTE} %5p %c{1}:%L - %m%n ### set log levels - for more verbose logging change 'info' to 'debug' ### log4j.rootLogger=debug, stdout
sqlMapConfg.xml
<?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>
<!--通过properties标签加载外部properties文件-->
<properties resource="jdbc.properties"/>
<!--定义别名-->
<typeAliases>
<typeAlias type="com.itheima.domain.User" alias="user"/>
</typeAliases>
<!--数据源环境-->
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.username}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<!--加载映射文件-->
<mappers>
<mapper resource="com/itheima/mapper/UserMapper.xml"/>
</mappers>
</configuration>
MybatisTest.java
package com.itheima.test; import com.itheima.domain.User; import com.itheima.mapper.UserMapper; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; public class MybatisTest { private UserMapper mapper; @Before public void before() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(true); mapper = sqlSession.getMapper(UserMapper.class); } @Test public void testSave(){ User user = new User(); user.setUsername("tom"); user.setPassword("abc"); mapper.save(user); } @Test public void testUpdate(){ User user = new User(); user.setId(3); user.setUsername("lucy"); user.setPassword("123"); mapper.update(user); } @Test public void testDelete(){ mapper.delete(3); } @Test public void testFindById(){ User user = mapper.findById(2); System.out.println(user); } @Test public void testFindAll(){ List<User> userList = mapper.findAll(); for (User user : userList) { System.out.println(user); } } }
执行测试各个测试方法,可以执行成功。
三、注解完成基本的crud
修改UserMapper.java
package com.itheima.mapper; import com.itheima.domain.User; 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 java.util.List; public interface UserMapper { @Insert("insert into user values(#{id},#{username},#{password},#{birthday})") public void save(User user); @Update("update user set username=#{username},password=#{password} where id=#{id}") public void update(User user); @Delete("delete from user where id=#{id}") public void delete(int id); @Select("select * from user where id=#{id}") public User findById(int id); @Select("select * from user") public List<User> findAll(); }
删除resources的映射文件UserMapper.xml
修改sqlMapConfig.xml核心配置文件,我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可
<?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> <!--通过properties标签加载外部properties文件--> <properties resource="jdbc.properties"/> <!--定义别名--> <typeAliases> <typeAlias type="com.itheima.domain.User" alias="user"/> </typeAliases> <!--数据源环境--> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"></transactionManager> <dataSource type="POOLED"> <property name="driver" value="${jdbc.driver}"/> <property name="url" value="${jdbc.url}"/> <property name="username" value="${jdbc.username}"/> <property name="password" value="${jdbc.password}"/> </dataSource> </environment> </environments> <!--加载映射文件--> <!--<mappers>--> <!--<mapper resource="com/itheima/mapper/UserMapper.xml"/>--> <!--</mappers>--> <!--加载映射关系 --> <mappers> <!--指定接口所在的包,扫描使用注解的类所在的包--> <package name="com.itheima.mapper"></package> </mappers> </configuration>
执行MybatisTest中的测试方法,仍旧能成功。
四、Mybatis的注解实现复杂映射开发
实现复杂关系映射之前我们可以在映射文件中通过配置<resultMap>来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置
五、一对一的注解开发
使用上一篇(mybatis的多表操作8 )中的场景、数据库表和实体。
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户
Order.java同上一篇
OrderMapper.java
package com.itheima.mapper; import com.itheima.domain.Order; import org.apache.ibatis.annotations.Result; import org.apache.ibatis.annotations.Results; import org.apache.ibatis.annotations.Select; import java.util.List; public interface OrderMapper { @Select("select *,o.id oid from orders o,user u where o.uid=u.id") @Results({ @Result(column = "oid",property = "id"), @Result(column = "ordertime",property = "ordertime"), @Result(column = "total",property = "total"), @Result(column = "uid",property = "user.id"), @Result(column = "username",property = "user.username"), @Result(column = "password",property = "user.password"), }) public List<Order> findAll(); }
或者是(下面这种方法用的比较多)
对应的sql语句:
select * from orders;
select * from user where id=查询出订单的uid;
package com.itheima.mapper; import com.itheima.domain.Order; import com.itheima.domain.User; 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 java.util.List; public interface OrderMapper { @Select("select * from orders") @Results({ @Result(column = "id", property = "id"), @Result(column = "ordertime", property = "ordertime"), @Result(column = "total",property = "total"), @Result( property = "user",//要封装的属性名称 column = "uid",//根据哪个字段去查询user表的数据 javaType = User.class,//要封装的实体类型 //select属性 代表查询哪个接口的方法获得数据 one = @One(select = "com.itheima.mapper.UserMapper.findById") ), }) public List<Order> findAll(); }
MybatisTest2.java
package com.itheima.test; import com.itheima.domain.Order; import com.itheima.mapper.OrderMapper; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; public class MybatisTest2 { private OrderMapper mapper; @Before public void before() throws IOException { InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream); SqlSession sqlSession = sqlSessionFactory.openSession(true); mapper = sqlSession.getMapper(OrderMapper.class); } @Test public void testFindAll(){ List<Order> orderList = mapper.findAll(); for (Order order : orderList) { System.out.println(order); } } }
执行testFindAll方法,查看控制台打印结果:
Order{id=1, ordertime=Wed Dec 12 00:00:00 CST 2018, total=3000.0, user=User{id=1, username='lucy', password='123', birthday=null}} Order{id=2, ordertime=Wed Dec 12 00:00:00 CST 2018, total=4000.0, user=User{id=1, username='lucy', password='123', birthday=null}} Order{id=3, ordertime=Wed Dec 12 00:00:00 CST 2018, total=5000.0, user=User{id=2, username='haohao', password='123', birthday=null}}
六、一对多的注解开发
用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户
一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单
对应的sql语句:
select * from user;
select * from orders where uid=查询出用户的id;
User.java
package com.itheima.domain; import java.util.Date; import java.util.List; public class User { private int id; private String username; private String password; private Date birthday; //描述的是当前用户存在哪些订单 private List<Order> orderList; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public List<Order> getOrderList() { return orderList; } public void setOrderList(List<Order> orderList) { this.orderList = orderList; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", birthday=" + birthday + ", orderList=" + orderList + '}'; } }
OrderMapper.java
package com.itheima.mapper; import com.itheima.domain.Order; import com.itheima.domain.User; 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 java.util.List; public interface OrderMapper { @Select("select * from orders where uid=#{uid}") public List<Order> findByUid(int uid); }
UserMapper.java
package com.itheima.mapper; import com.itheima.domain.User; import org.apache.ibatis.annotations.*; import java.util.List; public interface UserMapper { @Select("select * from user") @Results({ @Result(id = true,column = "id",property = "id"), @Result(column = "username",property = "username"), @Result(column = "password",property = "password"), @Result( column = "id", property = "orderList", javaType = List.class, many = @Many(select = "com.itheima.mapper.OrderMapper.findByUid") ) }) public List<User> findUserAndOrderAll(); }
MyBatisTest.java新增测试方法
@Test public void testFindUserAndOrderAll(){ List<User> userAndOrderAll = mapper.findUserAndOrderAll(); for (User user : userAndOrderAll) { System.out.println(user); } }
执行此测试方法,查看控制台打印结果:
User{id=1, username='lucy', password='123', birthday=Wed Dec 12 00:00:00 CST 2018, orderList=[Order{id=1, ordertime=Wed Dec 12 00:00:00 CST 2018, total=3000.0, user=null}, Order{id=2, ordertime=Wed Dec 12 00:00:00 CST 2018, total=4000.0, user=null}]} User{id=2, username='haohao', password='123', birthday=Thu Dec 12 00:00:00 CST 2019, orderList=[Order{id=3, ordertime=Wed Dec 12 00:00:00 CST 2018, total=5000.0, user=null}]}
七、多对多的注解开发
用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用
多对多查询的需求:查询用户同时查询出该用户的所有角色
对应的sql语句:
select * from user;
select * from sys_role r,sys_user_role ur where r.id=ur.roleid and ur.userid=用户的id
User.java
package com.itheima.domain; import java.util.Date; import java.util.List; public class User { private int id; private String username; private String password; private Date birthday; //描述的是当前用户具备哪些角色 private List<Role> roleList; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } public Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public List<Role> getRoleList() { return roleList; } public void setRoleList(List<Role> roleList) { this.roleList = roleList; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", password='" + password + '\'' + ", birthday=" + birthday + ", roleList=" + roleList + '}'; } }
Role.java
package com.itheima.domain; public class Role { private int id; private String roleName; private String roleDesc; public int getId() { return id; } public void setId(int id) { this.id = id; } public String getRoleName() { return roleName; } public void setRolename(String roleName) { this.roleName = roleName; } public String getRoleDesc() { return roleDesc; } public void setRoleDesc(String roleDesc) { this.roleDesc = roleDesc; } @Override public String toString() { return "Role{" + "id=" + id + ", rolename='" + roleName + '\'' + ", roleDesc='" + roleDesc + '\'' + '}'; } }
RoleMapper.java
package com.itheima.mapper; import com.itheima.domain.Role; import org.apache.ibatis.annotations.Select; import java.util.List; public interface RoleMapper { @Select("select * from sys_role r,sys_user_role ur where r.id=ur.roleid and ur.userid=#{uid}") public List<Role> findByUid(int uid); }
UserMapper.java
package com.itheima.mapper; import com.itheima.domain.User; import org.apache.ibatis.annotations.*; import java.util.List; public interface UserMapper { @Select("select * from user") @Results({ @Result(id = true,column = "id",property = "id"), @Result(id=true,column = "username",property = "username"), @Result(id=true,column = "password",property = "password"), @Result( column = "id",//user表查询出的id property = "roleList", javaType = List.class, many = @Many(select = "com.itheima.mapper.RoleMapper.findByUid") ) }) public List<User> findUserAndRoleAll(); }
MybatisTest.java中新增测试方法
@Test public void testFindUserAndRoleAll(){ List<User> userAndRoleAll = mapper.findUserAndRoleAll(); for (User user : userAndRoleAll) { System.out.println(user); } }
执行测试方法,查看控制台打印结果:
User{id=1, username='lucy', password='123', birthday=Wed Dec 12 00:00:00 CST 2018, roleList=[Role{id=1, rolename='CTO', roleDesc='CTO'}, Role{id=2, rolename='COO', roleDesc='COO'}]}
User{id=2, username='haohao', password='123', birthday=Thu Dec 12 00:00:00 CST 2019, roleList=[Role{id=1, rolename='CTO', roleDesc='CTO'}, Role{id=2, rolename='COO', roleDesc='COO'}]}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通