需求分析,现有三个表:
user表,存储用户信息,包含用户id,姓名,手机号
product表,存储产品的信息,包含产品的id,产品名,产品的分类目录
transaction表,是一张中间表,存储user表的id、以及product表的id
【一对一查询】
需求:根据用户的id查询用户信息
- 在UserMappper.java中声明一个方法,用于查找信息时调用
//根据用户的id进行查找,查找的内容是多个对象,所以用集合进行封装
List<User> selectByPrimaryKey(Long id);
- 在对应的UserMapper.xml中写SQL语句
<select id="selectByPrimaryKey" parameterType="java.lang.Long" resultMap="BaseResultMap">
select
<include refid="Base_Column_List" />
from user
where ID = #{id,jdbcType=INTEGER}
</select>
防止sql注入,以及防止查找的内容出现null 的现象我们使用resultMap
<resultMap id="BaseResultMap" type="com.jyc.pojo.User">
<id property="id" column="ID" jdbcType="INTEGER"/>
<result property="username" column="UserName" jdbcType="VARCHAR"/>
<result property="tel" column="Tel" jdbcType="VARCHAR"/>
</resultMap>
- 编写测试方法
public class UserTest {
SqlSession sqlSession;
UserMapper mapper;
@Before
public void before() throws Exception{
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession(true);
mapper = sqlSession.getMapper(UserMapper.class);
}
@After
public void after() {
sqlSession.close();
}
@Test
public void selectByPrimaryKeyTest(){
List<User> user = mapper.selectByPrimaryKey(1L);
System.out.println(user);
}
}
至此,一对一查询就结束了。
【多对多查询】
需求1:根据用户的id查询用户所购买的商品全部信息
注:这里我们需要创建一个DTO(数据传输对象)包,用于存储封装查询的结果
- 创建TransactionProductDTO.java
package com.jyc.DTO;
import lombok.Data;
@Data
public class TransactionProductDTO {
private Integer userid;//用户的id
private Integer productid;//商品的id
private String productname;//商品的名
private String catalog;//商品的目录
}
- 创建一个方法,用于查询信息时调用
注:这里需要说明一下,创建的方法可以在任意存在的mapper类下,只要最后测试方法中扫描的“.class”文件是该方法所在的文件中即可
//我写在了ProductMapper.java中
List<TransactionProductDTO> findUserProductByUserId(int userid);
- 根据DTO类,需要新创建一个resultMap来定义【字段】和【属性】的映射关系
在ProductMapper.xml输入以下内容
<resultMap id="TestResultMap1" type="com.jyc.DTO.TransactionProductDTO">
<!-- “property” 的值是DTO类中声明的变量 “column” 的值是数据库中的列名,需要保持一致 -->
<id property="userid" column="UserId" jdbcType="INTEGER"/>
<id property="productid" column="ProductId" jdbcType="INTEGER"/>
<result property="productname" column="ProductName" jdbcType="VARCHAR"/>
<result property="catalog" column="Catalog" jdbcType="VARCHAR"/>
</resultMap>
- 书写SQL语句
<select id="findUserProductByUserId" resultMap="TestResultMap1" >
select transaction.userId,transaction.productId,product.ProductName,product.Catalog
from transaction,product
where transaction.productId = product.id and transaction.userId = #{userid}
</select>
注:这里需要特别说明,新创建的resultMap需要和对应的SQL语句连在一起,中间不能出现其他代码
- 在ProductTest.java中写测试方法
首先先把以下内容写在测试是方法前
package com.jyc;
public class TransactionTest {
SqlSession sqlSession;
ProductMapper mapper;
@Before
public void before() throws Exception{
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
sqlSession = sqlSessionFactory.openSession(true);
//因为我的方法声明在了ProductMapper.class中,所以扫包是扫描这个类
mapper = sqlSession.getMapper(ProductMapper.class);
}
@After
public void after(){
sqlSession.close();
}
}
测试方法
@Test
public void findUserProductByUserId(){
//传入要查找的用户id,封装在list集合中
List<TransactionProductDTO> list = mapper.findUserProductByUserId(1);
System.out.println(list);
}
需求2 :根据用户id 查找用户购买的商品信息以及用户的信息
注:这里我们就需要用到中间表Transaction,作为中间的条件
- 创建UserTransactionProductDTO.java类,用于封装存储查找的内容
package com.jyc.DTO;
import lombok.Data;
@Data
public class UserTransactionProductDTO {
private Integer userId;//用户的id
private String userName;//用户名
private String userTel;//用户电话号
private Integer productId;//所购买商品id
private String productName;//所购买的商品名
private String productCatalog;//所构面的商品对应的目录
}
- 在ProductMapper.java中声明查找信息的方法
List<UserTransactionProductDTO> findUserProductAndUserInfoByUserId(int userid);
- 根据DTO类,需要新创建一个resultMap来定义【字段】和【属性】的映射关系
在ProductMapper.xml输入以下内容
<resultMap id="TestResultMap2" type="com.jyc.DTO.UserTransactionProductDTO">
<!--
“property” 的值是DTO类中声明的变量 “column” 的值是数据库中的列名,需要保持一致
这里由于user表中用户的id名是ID,product表中的商品id 也是ID,
所以在对应的 “column” 中就不能同时赋值为“ID”
这里使用中间表Transaction中的列名,UserId、ProductId
我试了使用【数据库.列名】的方式,出现的查询结果是null
所以采用的中间表的列名
-->
<id property="userId" column="UserId" jdbcType="INTEGER"/>
<id property="productId" column="ProductId" jdbcType="INTEGER"/>
<result property="userName" column="userName" jdbcType="VARCHAR"/>
<result property="userTel" column="Tel" jdbcType="VARCHAR"/>
<result property="productName" column="ProductName" jdbcType="VARCHAR"/>
<result property="productCatalog" column="Catalog" jdbcType="VARCHAR"/>
</resultMap>
- 编写SQL语句
<select id="findUserProductAndUserInfoByUserId" resultMap="TestResultMap2">
select transaction.userid,user.UserName,user.Tel,transaction.productid,product.productname,product.Catalog
from user inner join transaction on user.id = transaction.UserId
inner join product on transaction.productid = product.id
where user.id = #{userid}
</select>
- 编写测试方法
@Test
public void findUserProductAndUserInfoByUserId(){
//传入需要查找的用户id
List<UserTransactionProductDTO> userProductAndUserInfoByUserId = mapper.findUserProductAndUserInfoByUserId(1);
System.out.println(userProductAndUserInfoByUserId);
}
另外说明:我的包结构如下
至此,全部的需求已完成,感谢阅读,存在不足之处,还请指点!