Mybatis框架_day01
学习笔记,把笔记放在本地,没有电脑时就没办法了,找个博客放笔记。
1. 什么是mybatis
- mybatis是一个持久层的框架,是Apache下的*项目。
- mybatis让程序将主要精力放在sql上,通过mybatis提供的映射方式,*灵活生成(半自动化,大部分需要程序员编写sql)满足需要sql语句。
- mybatis可以将preparedStatement中的输入参数自动进行输入映射,将查询结果集灵活映射成java对象(输出映射)
2. Mybatis框架
3. 入门程序
3.1. 需求
- 根据用户id(主键)查询用户信息
- 根据用户名称模糊查询用户信息
- 添加用户
- 删除用户
- 更新用户
3.2. Mybatis运行环境
-
导入mybatis3.2.7jar核心包
-
lib下,依赖包
-
log4j.properties
-
数据库驱动包
-
SqlMapConfig.xml
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 和spring整合后environments配置将废除 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理 --> <transactionManager type="JDBC"> <!-- 数据库连接池 --> <dataSource type="POOLED"> <property name="driver" value="com.microsoft.sqlserver.jdbc.SQLServerDriver" /> <property name="url" value="jdbc:sqlserver://localhost:1433;database=mybatis_day01" /> <property name="username" value="sa" /> <property name="password" value="123456" /> </dataSource> </transactionManager> </environment> </environments> </configuration>
3.3. 根据用户id(主键)查询用户信息
3.3.1. 创建po类
public class User {
//属性名和数据库表的字段对应
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
3.3.2. 映射文件
-
映射文件名称:
- User.xml,mapper代理开发映射文件名称加XXXMapper.xml,比如:UserMapper.xml、itemsMapper.xml
-
在映射文件中配置sql语句
<?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"> <!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要作用 --> <mapper namespace="test"> <!-- 在映射文件中配置很多sql语句 --> <!-- 通过select执行数据库查询 id:用于表示映射文件中的sql 将sql语句封装到mapperstatement对象中,所以将id成为statement的id parameterType:指定输入参数类型,这里指定int型 #{}表示一个占位符 #{id}:其中id表示接收输入的参数,参数名称为id,如果输入参数是简单类型,#{}中的参数名可以任意,可以是value或其他名称 resultType:输出结果所映射的java对象类型,select执行resultType表示将单条记录所映射成的java对象 --> <select id="findUserBuId" parameterType="int" resultType="cn.itcast.mybatis.po.User"> SELECT * FROM t_user WHERE id = #{id} </select> </mapper>
-
在sqlMapConfig.xml加载映射文件
<!-- 加载映射文件 --> <mappers> <mapper resource="sqlmap/User.xml"/> </mappers>
3.3.3. 写测试代码
//mybatis配置文件
String resource = "SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建会话工厂,传入mybatis的配置文件信息
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//通过会话工厂得到sqlsession
SqlSession sqlSession = sqlSessionFactory.openSession();
//通过sqlsession操作数据库
//第一个参数:映射文件中statement的id,等于namespace+"."+statement的id
//指定和映射文件中管所匹配的parameterType类型的参数
//最终结果是与映射文件中所匹配的resultType类型的对象
User user = sqlSession.selectOne("test.findUserById",1);
System.out.println(user);
3.4. 根据用户名称模糊查询用户信息
3.4.1 映射文件
-
使用User.xml
<!-- 根据用户名称模糊查询用户信息,可返回多条 resultType指定的就是将单条记录所映射成的java对象类型 ${}:表示拼接sql语句,将接收到参数的内容不加任何修饰拼接在sql中 使用${}拼接sql,引起sql注入 ${value}:接收输入参数的内容,如果传入类型是简单类型,${}中是能使用value --> <select id="findUserByName" parameterType="java.lang.String" resultType="cn.itcast.mybatis.po.User"> SELECT * FROM t_user WHERE username LIKE '%${value}%' </select>
3.4.2 程序代码
List<User> list = sqlSession.selectList("test.findUserByName", "赵");
3.5. 添加用户
3.5.1 映射文件
-
在User.xml文件中配置添加用户的Statement
<!-- 添加用户 parameterType:指定输入参数类型是pojo(包括用户信息) #{}中指定pojo的属性名,接收到pojo对象的属性值,mybatis通过OGNL获取对象的属性值 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User"> INSERT INTO t_user(username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}) </insert>
3.5.2. 程序代码
//插入用户对象
User user = new User();
user.setUsername("王小军");
user.setBirthday(new Date());
user.setSex("男");
user.setAddress("中国");
sqlSession.insert("test.insertUser", user);
//提交事务
sqlSession.commit();
3.5.3. 自增主键的返回
-
在MySQL中使用函数
SELECT LAST_INSERT_ID()
;在SQLServer中可用其函数SELECT SCOPE_IDENTITY()
-
MySQL中可用
<!-- 将插入的主键返回,返回到user对象中 SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用于自增主键 keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性 order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说 resultType:指定SELECT LAST_INSERT_ID()的结果类型 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> SELECT LAST_INSERT_ID() </selectKey>
-
SQLServer中用
<!-- 方法一 --> <!-- keyProperty 是实体里面的属性,如果传入是map就是map里的属性, keyColumn是表上的主键名称 --> <insert id="insertUser" parameterType="cn.itcast.mybatis.po.User" useGeneratedKeys="true" keyProperty="id" keyColumn="id"> INSERT INTO t_user(username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address}) SELECT SCOPE_IDENTITY() </insert> <!-- 方法二 --> <selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer"> SELECT @@IDENTITY </selectKey>
3.5.4. 非自增主键的返回(使用uuid())
3.6. 删除用户
3.6.1. 映射文件
<!-- 根据id删除 -->
<delete id="deleteUser" parameterType="java.lang.Integer">
DELETE FROM t_user WHERE id=#{id}
</delete>
3.6.2. 代码实现
//传入id删除用户
sqlSession.delete("test.deleteUser", 8);
3.7. 更新用户
3.7.1. 映射文件
<!-- 更新用户
需要传入用户id
需要传入用户更新信息
parameterType指定user对象,包括id和更新信息,注意:id必须存在
#{id}:从输入的user对象中获取id属性值 -->
<update id="updateUser" parameterType="cn.itcast.mybatis.po.User">
update t_user set username=#{username},birthday=#{birthday},sex=#{sex},address={address} where id=#{id}
</update>
3.7.2. 代码实现
//更新用户对象
User user = new User();
user.setId(15);
user.setUsername("王大小");
user.setBirthday(new Date());
user.setSex("女");
user.setAddress("中国");
//传入id删除用户
sqlSession.update("test.updateUser", user);
3.8. 总结
3.8.1. parameterType
- 在映射文件中通过parameterType指定输入参数的类型
3.8.2. resultType
- 在映射文件中通过resultType指定输出结果的类型
3.8.3. #{}和${}
- #{}表示一个占位符。
- #{}接收输入参数,类型可以是简单类型,pojo,hashmap。如果接收的是简单类型。
- #{}中可以写成value或其他名称。
- #{}接收pojo对象值,通过OGNL解析对象中的属性值,通过属性.属性.属性…
- ${}表示一个拼接符号,会引起sql注入,不建议使用。
- ${}接收输入参数,类型可以是简单类型,pojo,hashmap。如果接收的是简单类型。
- 如果接收简单类型,只能写成vlaue。
- ${}接收pojo对象值,通过OGNL解析对象中的属性值,通过属性.属性.属性…
3.8.4. selectOne和selectList
- selectOne表示查询出一条记录进行映射,如果使用selectOne可以实现,使用selectList也可以实现(list中只有一个记录)
- selectList表示查询吃一个列表(多条记录)进行映射,不可以使用selectOne实现
3.9. Mybatis和Hibernate本质区别和应用场景
3.9.1. Hibernate
- 是一个标准的ORM框架(对象关系映射)。入门门槛高,不需要程序员写sql,sql语句自动生成。对sql语句进行优化、修改比较困难。
- 应用场景:适用于需求变化不多的中小型项目,比如:后台管理系统,erp,orm,oa。
3.9.2. Mybatis
- 专注是sql本身,需要程序员写sql语句,sql修改、有话比较方便。mybatis是一个不完全的ORM框架,虽然程序员自己写sql,mybatis也可以实现映射(输入映射、输出映射)。
- 应用场景:适用于需求变化较多的项目,比如:互联网项目。
4. Mybatis开发dao的方法
4.1. sqlSession适用范围
4.1.1. SqlSessionFactoryBuilder
- 通过SqlSessionFactoryBuilder创建会话工厂SqlSessionFactory
- 将SqlSessionFactoryBuilder当成工具类即可,不需要使用单例管理SqlSessionFactoryBuilder
- 在需要创建SqlSessionFactory时,只需要new一次SqlSessionFactoryBuilder即可
4.1.2. SqlSessionFactory
- 通过SqlSessionFactory创建Sqlsession,使用单例模式管理SQLSessionFactory(工厂一旦创建,使用一个实例)
- 将来mybatis和spring整合之后,使用单例模式管理SQLSessionFactory
4.1.3. SqlSession
- SqlSession是一个面向用户(程序员)的接口
- SqlSession中提供了很多操作数据库的方法,如:selectOne(返回单个对象)、selectList(返回单个或多个对象)
- SqlSession是线程不安全的,在SqlSession实现勒种,除了有接口中的方法(操作数据库的方法)还有数据域属性。
- SqlSession最佳应用场合在方法体内,定义成局部变量使用。
4.2. 原始dao开发方法(程序员需要些dao接口和dao实现类)
4.2.1. 思路
- 需要向dao实现类中注入会话工厂SqlSessionFactory,在方法体内通过工厂创建SqlSession
4.2.2. Dao接口
public interface UserDao {
//根据id查询用户信息
public User findUserById(int id) throws Exception;
//添加用户信息
public void inserUser(User user) throws Exception;
//删除用户信息
public void deleteUser(int id) throws Exception;
}
4.2.3. Dao实现类
public class UserDaoImpl implements UserDao{
//需要向dao实现类中注入SqlSessionFactory
//通过构造方法注入
private SqlSessionFactory sqlSessionFactory = null;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User findUserById(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
User user = sqlSession.selectOne("test.findUserById",id);
//释放资源
sqlSession.close();
return user;
}
@Override
public void inserUser(User user) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.insert("test.insertUser", user);
//执行事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
@Override
public void deleteUser(int id) throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
sqlSession.delete("test.deleteUser", id);
//执行事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
}
4.2.4. 测试代码
public class UserDaoImplTest {
private SqlSessionFactory sqlSessionFactory;
//此方法是在执行testFindUserById之前执行
@Before
public void setUp() throws Exception {
//创建SQLSessionFactory
//mybatis配置文件
String resource = "SqlMapConfig.xml";
//得到配置文件流
InputStream inputStream = Resources.getResourceAsStream(resource);
//创建会话工厂,传入mybatis的配置文件信息
sqlSessionFactory = new SqlSessionFactoryBuilder()
.build(inputStream);
}
@Test
public void testFindUserById() throws Exception {
//创建userDao对象
UserDao userDao = new UserDaoImpl(sqlSessionFactory);
//调用UserDao方法
User user = userDao.findUserById(1);
System.out.println(user);
}
}
4.2.5. 总结原始dao开发问题
- dao接口实现类方法中讯在大量模板方法
- 嗲用sqlsession方法是将statement的id硬编码了
- 调用sqlsession方法是传入的变量,由于sqlsession方法使用泛型,即使变量类型传入错误在编译阶段也不报错
4.3. mapper代理方法(程序员只需要写mapper接口(相当于dao接口))
4.3.1. 思路(mapper代理开发规范)
-
写mapper.xml映射文件
-
写mapper接口需遵循一些开发规范,mybatis可以自动生成mapper接口实现类代理对象
-
开发规范:
-
在mapper.xml中mapper的namespace等于mapper.java接口的地址
<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离 注意:使用mapper代理方法开发,namespace有特殊重要作用 --> <mapper namespace="cn.itcast.mybatis.mapper.UserMapper">
-
mapper.java接口中的方法名和mapper.xml中statement的id一致
-
mapper.java接口中方法的参数类型和mapper.xml中statement的parameterType指定的类型一致
-
mapper.java接口中的方法返回累心个mapper.xml中resultType指定的类型一致
//根据id查询用户信息 public User findUserById(int id) throws Exception;
-
-
总结:以上开发规范主要是对下面的代码进行统一生成:
User user = sqlSession.selectOne("test.findUserById",id);
sqlSession.insert("test.insertUser", user);
sqlSession.delete("test.deleteUser", id);
4.3.2. mapper.java
public interface UserMapper {
//根据id查询用户信息
public User findUserById(int id) throws Exception;
//根据用户名查询用户列表
//
public List<User> fingUserByName(String name) throws Exception;
//插入用户
public void insertUser(User user) throws Exception;
//删除用户
public void deleteUser(int id) throws Exception;
}
4.3.3. mapper.xml
4.3.4. 在SqlMapperConfig.xml中加载mapper.xml
<mapper resource="mapper/UserMapper.xml"/>
4.3.5. 测试代码
@Test
public void testFindUserById() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User user = userMapper.findUserById(1);
System.out.println(user);
}
4.3.6. 一些问题总结
4.3.6.1. 代理对象内部调用selectOne或selectList
- 如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库.
- 如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库.
4.3.6.2. mapper接口方法参数只能有一个
- mapper接口方法参数只能有一个,是否不利于扩展维护。
- 在系统框架中,dao层的代码是被业务层公用的,即使mapper接口只有一个参数,可以使用包装类型的pojo满足不同的业务方法的需求
- 注意:持久层中方法的参数可以用包装类型,map…,service方法中建议不要使用包装类型(不利于业务层的可扩展)
5. SqlMapConfig.xml
mybatis的全局配置文件SqlMapConfig.xml,配置内容如下:
<properties>
用来加载属性文件<settings>
用来设置全局参数<typeAliases>
用来设置类型的别名<typeHandlers>
用来设置类型处理器<objectFactory>
用来设置对象工厂<plugins>
用来设置插件<environments>
用来设置mybatis的环境<mappers>
用来配置映射文件
5.1. properties属性
5.1.1 需求
-
将数据库连接参数单独配置在db.properties中,只需要在SqlMapConfig.xml中加载db.properties属性值
-
在SqlMapConfig.xml中就不需要对数据库连接参数硬编码
-
将数据库连接参数值配置在db.properties
<!-- 加载属性文件 --> <properties resource="db.properties"></properties> <!-- 和spring整合后environments配置将废除 --> <environments default="development"> <environment id="development"> <!-- 使用jdbc事务管理 --> <transactionManager type="JDBC" /> <!-- 数据库连接池 --> <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>
5.1.2. properties特性:
- 注意:Mybatis将按照下面的顺序来加载属性:
- 在properties元素体内定义的属性首先被读取
- 然后会读取properties元素中resource或url加载的属性,它会覆盖已读取的同名属性
- 最后读取parameterType传递的属性,它会覆盖已读取的同名属性
5.1.3. 建议:
- 不要在properties元素体内添加任何属性值,只将属性值定义在properties文件中
- 在properties文件中定义属性名要有一定的特殊性,比如:xxxx.xxxx
5.2. settings全局参数配置
- mybatis框架在运行时可以调整一些运行参数,比如开启二级缓存,开启延迟加载
5.3. typeAliases别名定义(重点)
5.3.1. 需求
- 在mapper.xml中,定义很多的statement,statement需要parameterType指定输入参数的类型,需要resultType执行输出结果的映射类型
- 如果在指定类型是输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义一些别名,在mapper.xml中通过别名定义,方便开发
5.3.2. mybatis默认支持别名
5.3.3. 自定义别名
5.3.3.1. 别名定义
<!-- 别名定义 -->
<typeAliases>
<!-- 针对单个别名的定义
type:类型的路径
alias:别名
-->
<typeAlias type="cn.itcast.mybatis.po.User" alias="user"/>
</typeAliases>
-
引用别名
<select id="findUserById" parameterType="int" resultType="user"> SELECT * FROM t_user WHERE id = #{id} </select>
5.3.3.2. 批量定义(常用)
<!-- 批量别名定义
指定包名:mybatis自动扫描包中的po类,
自动定义别名,别名就是类名(首字母大写或小写都可以)
-->
<package name="cn.itcast.mybatis.po"/>
5.4. typeHandler类型处理器
- mybatis中通过typeHandler完成jdbc类型和java类型的转换
- 通常情况下,mybatis提供的类型处理器满足日常需要,不需要自定义
5.5. mapper映射配置
5.5.1. 通过resource方法一次加载单个映射文件
<!-- 通过resource方法一次加载一个映射文件 -->
<mapper resource="mapper/UserMapper.xml"/>
5.5.2. 通过mapper接口加载
<!-- 通过mapper接口加载映射文件
遵循一些规范:需要将mapper接口的类名和mapper.xml映射文件名称保持一致,且在一个目录中
上边规范前提是:使用的是mapper代理的方法
-->
<mapper class="cn.itcast.mybatis.mapper.UserMapper"/>
- 按照上面的规范,需将mapper.java和mapper.xml放在同一个文件中
5.5.3. 批量加载多个mapper(推荐使用)
<!-- 批量加载mapper
mapper接口的报名,mybatis在自动扫描包下边所有mapper接口进行加载
遵循一些规范:需要将mapper接口的类名和mapper.xml映射文件名称保持一致,且在一个目录中
上边规范前提是:使用的是mapper代理的方法
-->
<package name="cn.itcast.mybatis.mapper"/>
6. 输入映射
- 通过parameterType指定输入参数类型,可以是简单类型,HashMap,pojo的包装类型
6.1. 传递pojo的包装对象
6.1.1 需求
- 完成用户信息的综合查询,需要传入很多查询条件(可能包括童虎信息、其他信息,比如商品、订单的)
6.1.2. pojo包装类型
-
针对上边需求,建议使用自定义的包装类型的pojo
-
在包装类型的pojo中将复杂的查询条件包装进去
public class UserQueryVo { //在这里包装所需要的查询条件 //用户查询条件 private UserCustom userCustom; public UserCustom getUserCustom() { return userCustom; } public void setUserCustom(UserCustom userCustom) { this.userCustom = userCustom; } //可以包装其他的查询条件,比如订单,商品 //...
6.1.3. mapper.xml
-
在UserMapper.xml中定义用户信息综合查询(查询条件复杂,通过高级查询进行复杂查询)。
<!-- 用户信息综合查询 #{userCustom.sex}:取出pojo包装对象中性别值 ${userCusotm.username}:取出pojo包装对象中用户姓名 --> <select id="findUserList" parameterType="cn.itcast.mybatis.po.UserQueryVo" resultType="cn.itcast.mybatis.po.UserCustom"> SELECT * FROM t_user where user.sex=#{userCustom.sex} and user.username like '%${userCusotm.username}%' </select>
6.1.4. mapper.java
//用户信息综合查询
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception;
6.1.5. 测试代码
public void testFindUserList() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setSex("男");
userCustom.setUsername("赵");
userQueryVo.setUserCustom(userCustom);
//调用userMapper的方法
List<UserCustom> list = userMapper.findUserList(userQueryVo);
System.out.println(list);
}
7. 输出映射
7.1. resultType
- 使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功
- 如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象
- 只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象
7.1.1. 输出简单类型
7.1.1.1. 需求
- 用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页
7.1.1.2. mapper.xml
<!-- 用户信息综合查询总数
parameterType:指定输入类型和发ingUserList一样
-->
<select id="findUserCount" parameterType="cn.itcast.mybatis.po.UserQueryVo" resultType="int">
SELECT COUNT(*) FROM t_user where sex=#{userCustom.sex} and username like '%${userCustom.username}%'
</select>
7.1.1.3. mapper.java
//用户信息综合查询总数
public int findUserCount(UserQueryVo userQueryVo) throws Exception;
7.1.1.4. 测试代码
public void testFindUserCount() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
userCustom.setSex("男");
userCustom.setUsername("赵");
userQueryVo.setUserCustom(userCustom);
//调用userMapper的方法
int count = userMapper.findUserCount(userQueryVo);
System.out.println(count);
}
7.1.1.5. 小结
- 查询出来的结果集是一行且一列,可以使用简单类型进行输出映射
7.1.2. 输出pojo对象和pojo对象列表
- 不管输出的pojo单个对象还是一个列表(list中包括pojo),在mapper.xml中resultType指定的类型是一样的
- 在mapper.java指定的方法返回值类型不一样:
- 输出单个pojo对象,方法返回值是单个对象类型
- 输出pojo对象列表,方法返回值是List
- 生成的动态代理对象中是根据mapper方法的返回值类型确定调用selectOne还是selectList
7.2. resultMap
- mybatis中可以使用resultMap完成高级输出结果映射
7.2.1. resultMap使用方法
- 如果查询出来的列名和pojo属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做映射关系
- 第一步 定义resultMap
- 第二步 使用resultMap作为statement的输出映射类型
7.2.2 需求:将下边的sql使用User完成映射
SELECT id id_,username username_ FROM t_user where id=#{value}
- User类中属性名和上边查询列名不一致
7.2.2.1. 定义resultMap
<!-- 定义resultMap
将SELECT id id_,username username_ FROM t_user和User类中的属性做一个映射关系
type:resultMap最终所映射的java对象类型,可以使用别名
id:对resultMap的唯一标识
-->
<resultMap type="user" id="userResultMap">
<!-- id标识查询结果集中唯一标识
column:查询出来的列名
property:type指定的pojo类型中的属性名
最终resultMap对column和property做一个映射关系(对应关系)
-->
<id column="id_" property="id"/>
<!--
result对普通列的定义
-->
<result column="username_" property="username"/>
</resultMap>
7.2.2.2. 使用resultMap作为statement的输出映射类型
<!-- 使用resultMap进行输出映射
resultMap:指定定义的resultMap的id,如果这个resultMap在其他的mapper文件中,前边应加namespace
-->
<select id="findUserCount" parameterType="cn.itcast.mybatis.po.UserQueryVo" resultType="userResultMap">
SELECT id id_,username username_ FROM t_user where id=#{value}
</select>
7.2.2.3. mapper.java
//根据用户名查询用户列表
public List<User> fingUserByName(String name) throws Exception;
7.2.2.4. 测试
public void testFindUserByIdResultMap() throws Exception {
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper的方法
User user = userMapper.findUserByIdResultMap(1);
System.out.println(user);
}
7.3. 小结
- 使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功
- 如果查询出来的列名和pojo属性名不一致,通过定义一个resultMap对列名和pojo属性名之间做映射关系
8. 动态sql
8.1. 什么是动态sql
- mybatis核心 对sql语句进行灵活操作,通过表达式进行判断,对sql进行灵活拼接、组装
8.2. 需求
- 用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql
- 对查询条件进行判断,如果输入参数不为空才进行查询条件拼接。
8.3. mapper.xml
<select id="findUserList" parameterType="cn.itcast.mybatis.po.UserQueryVo"
resultType="cn.itcast.mybatis.po.UserCustom">
SELECT username,address,birthday FROM t_user
<!-- where可以自动去掉条件中第一个and -->
<where>
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
</if>
</where>
</select>
8.4. 测试代码
//创建包装对象,设置查询条件
UserQueryVo userQueryVo = new UserQueryVo();
UserCustom userCustom = new UserCustom();
//由于使用动态sql,不设置值,条件不会拼接在sql中
userCustom.setSex("男");
//userCustom.setUsername("赵");
userQueryVo.setUserCustom(userCustom);
//调用userMapper的方法
List<UserCustom> list = userMapper.findUserList(null);
8.5. sql片段
8.5.1. 需求
- 将上边实现的动态sql判断代码块抽取出来,组成一个sql片段。其他statement中就可以引用sql片段
8.5.2. 定义sql片段
<!-- 定义sql片段
id:sql片段唯一标识
经验:是基于单标定义sql片段,这样这个sql片段可重用性才高
在sql片段中不要包含where
-->
<sql id="query_user_where">
<if test="userCustom!=null">
<if test="userCustom.sex!=null and userCustom.sex!=''">
and sex=#{userCustom.sex}
</if>
<if test="userCustom.username!=null and userCustom.username!=''">
and username like '%${userCustom.username}%'
</if>
</if>
</sql>
8.5.3. 引用sql片段
<select id="findUserList" parameterType="cn.itcast.mybatis.po.UserQueryVo"
resultType="cn.itcast.mybatis.po.UserCustom">
SELECT username,address,birthday FROM t_user
<!-- where可以自动去掉条件中第一个and -->
<where>
<!-- 引用sql片段的id,如果refid引用的片段不在本mapper中,需要加namespace -->
<include refid="query_user_where"></include>
<!-- 这里还可以引用其他的sql片段 -->
</where>
</select>
8.6. foreach
- 向sql传递数组或list,mybatis使用foreach解析
8.6.1. 需求
- 在用户查询列表和查询总数的statement中,增加多个id的输入查询
- sql语句如下:
SELECT * FROM t_user WHERE id=1 or id=3 or id=4
8.6.2. 在输入参数类型中添加listids传入多个id
//传入多个id
private List<Integer> ids;
8.6.3. 修改mapper.xml
-
在查询条件中,查询条件定义成了sql片段,需要修改sql片段
<if test="ids!=null"> <!-- 使用foreach遍历传入ids collection:指定输入对象中集合属性 item:每次遍历生成的变量名 open:开始便利是要拼接的串 close:结束遍历是拼接的串 separator:每遍历的两个对象中间需要拼接的串 --> <!-- 实现下边的sql拼接 AND (id=1 OR id=3 OR id=4) --> <foreach collection="ids" item="item_id" open="AND (" close=")" separator="OR"> <!-- 每个遍历需要拼接的串 --> id=#{item_id} </foreach> </if>
8.6.4. 测试代码
//传入多个id
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(3);
ids.add(4);
userQueryVo.setIds(ids);
userQueryVo.setUserCustom(userCustom);
//调用userMapper的方法
List<UserCustom> list = userMapper.findUserList(userQueryVo);
上一篇: 短视频app源代码vue关于微信开发,输入法把底部顶上去的情况
下一篇: SSM框架实现分页查询例子
推荐阅读
-
01.【MyBatis框架】
-
Mybatis框架_day01
-
SSM框架分页查询NullPointerException
-
SSM框架实现分页查询例子
-
Spring集成Quartz定时任务框架介绍和Cron表达式详解 博客分类: spring
-
canvas学习 博客分类: web框架 web进度条js
-
Spring集成Quartz定时任务框架介绍和Cron表达式详解 博客分类: spring
-
选择器学习 博客分类: web框架 cssjshtml
-
ibatis文档 博客分类: web框架 线程安全sqlmap新手入门注意事项mybatis
-
form表单的Action.java文件和jsp之间数据传递 博客分类: web框架 strutsjavajspJavaScriptXHTML