如果实体的属性名与表中字段名不一致,可以使用ResutlMap实现手动封装到实体类中
resultType : 如果实体的属性名与表中字段名一致,将查询结果自动封装到实体类中
2.2 多条件查询 @Param()
ListfindByIdAndUsername2(@Param("id") int id, @Param("username") String username);
使用pojo对象传递参数select * from user where id = #{id} and username = #{username}
List2.3 模糊查询 #{} (推荐使用)findByIdAndUsername3(User user);
ListfindByUsername(String username);
@Test
public void test6() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
// 当前返回的 其实是基于UserMapper所产生的代理对象:底层:JDK动态代理 实际类型:proxy
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List users = mapper.findByUsername("%子慕%");
for (User user : users) {
System.out.println(user);
}
sqlSession.commit();
sqlSession.close();
}
#{} 和 ${}
#{}:表示一个占位符号
- 通过 #{} 可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换,#{}可以有效防止sql注入。
- #{} 可以接收简单类型值或pojo属性值。
- 如果parameterType传输单个简单类型值, #{} 括号中名称随便写。
${}:表示拼接sql串
- 通过 ${} 可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换,会出现sql注入
问题。 - ${} 可以接收简单类型值或pojo属性值。
- 如果parameterType传输单个简单类型值, ${} 括号中只能是value。
2.5 动态sql ifinsert into user(username, birthday, sex, address) values (#{username}, #{birthday}, #{sex}, #{address}) SELECT LAST_INSERT_ID(); insert into user(username,birthday,sex,address) values(#{username},#{birthday},#{sex},#{address})
根据id和username查询,但是不确定两个都有值。
set
动态更新user表数据,如果该属性有值就更新,没有值不做处理
foreachupdate user where id = #{id} username = #{username}, birthday = #{birthday}, sex = #{sex}, address = #{address},
主要是用来做数据的循环遍历,类似 where id in (1,2,3) 传入的参数部分必须依靠foreach遍历才能实现。
如果查询条件为普通类型 List集合,collection属性值为:collection 或者 list
如果查询条件为普通类型 Array数组,collection属性值为:array
sql片段
映射文件中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的
2.6 PageHelperSELECT * FROM `user` #{id}
- 导入依赖
- 核心配置文件进行配置
- 使用
com.github.pagehelper pagehelper 3.7.5 com.github.jsqlparser jsqlparser 0.9.1
@Test
public void test15() throws IOException {
InputStream resourceAsStream = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(resourceAsStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
// 设置分页参数
// 参数1: 当前页
// 参数2: 每页显示的条数
PageHelper.startPage(1,2);
List users = mapper.findAllResultMap();
for (User user : users) {
System.out.println(user);
}
// 获取分页相关的其他参数
PageInfo pageInfo = new PageInfo(users);
System.out.println("总条数"+ pageInfo.getTotal());
System.out.println("总页数"+ pageInfo.getPages());
System.out.println("是否是第一页"+ pageInfo.isIsFirstPage());
sqlSession.close();
}
2.7 多表查询
1 对 1 association
一个订单只从属于一个用户 查订单的时候把用户信息查出来
Orders实体类
public class Orders {
private Integer id;
private String ordertime;
private Double total;
private Integer uid;
// 表示当前订单属于那个用户 association
private User user;
}
Mapper.xml
1 对 多 collection
一个用户有多个订单,查用户的时候把他的订单查出来
public class User implements Serializable {
private Integer id;
private String username;
private Date birthday;
private String sex;
private String address;
// 表示多方关系:集合 : 代表了当前用户所具有的订单列表 collection
private List ordersList;
// 表示多方关系:集合 : 代表了当前用户所具有的角色列表 collection
private List roleList;
}
多 对 多
一个用户有多个角色,一个角色被多个用户使用
其实是一对多的变种
2.8 嵌套查询
将原来多表查询中的联合查询拆成单个查询 (简化多表查询操作,但是浪费性能)
1 对 1 association查询一个订单,与此同时查询出该订单所属的用户
SELECT * FROM orders o LEFT JOIN USER u ON o.uid = u.id
-- 先查询订单
SELECt * FROM orders;
-- 再根据订单uid外键,查询用户
SELECt * FROM `user` WHERe id = #{订单的uid};
接口需要2个
ListfindAllWithUser2(); List findByUid(Integer uid);
映射文件
1 对 多 collection
查询所有用户,与此同时查询出该用户具有的订单
-- 先查询用户
SELECT * FROM `user`;
-- 再根据用户id主键,查询订单列表
SELECt * FROM orders where uid = #{用户id};
接口
User findById(Integer id); ListfindAllWithOrder2();
映射文件xml
多 对 多SELECT * FROM USER SELECT * FROM user WHERe id = #{id}
一个用户有多个角色,一个角色被多个用户使用。类似一对多
ListfindAllWithRole2(); List findByUid(Integer uid);
SELECT * FROM USER SELECT * FROM sys_role r INNER JOIN sys_user_role ur ON ur.roleid = r.id WHERe ur.userid = #{uid}



