SpringMVC-day07

已有 53 次阅读2017-4-17 18:08 |个人分类:mybatis的学习|系统分类:学习纪录| 配置文件, setting, 处理器, 数据源, 知识点

mybatis学习的第六天
今天是mybatis学习的第六天,今天学习了关于mybatis的别名定义,动态sql的基本使用,以及配置文件的使用,对于今天的学习,脑海里面已经基本有了一个关于mybatis框架的认识,对于这些知识点的牢固掌握,还需要接下来抽时间去多加的联系与尝试,对于mybatis的运用要达到自己期望的炉火纯青还有很长一段路要走,但是温故知新,对于mybatis的学习就能更上一层楼,今天对于昨天的配置文件的理解更加的到位了。
下面就是对应的学习笔记:
5.SqlMapConfig.xml
mybatis的全局配置文件
properties(属性)
setting(全局配置参数)
typeAliases(类型别名)
typeHandles(类处理器)
objectFactory(对象工厂) //一般不用
plugins(插件) //一般不用
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器) //重点掌握
5.1 properties(属性)
需求:将数据库连接参数单独配置在中,只需要在SqlMapConfig.xml中加载db.properties的属性
在SqlMapConfig.xml中就不需要对数据库的连接参数进行硬编码了
在这个里面,方便为了对运行的参数进行统一的管理。其他的XML可以引用该配置文件,类似于降低耦合
properties特性:
注意:mybatis将按照下面的顺序来加载属性
1.在properties元素体内定义的属性将首先被加载
2.然后会读取properties元素中resource或url加载的属性,它会覆盖已读取的同名属性
3.最后读取parameteType传递的属性,它会覆盖已读取的同名属性
因此,通过parameteType传递的属性具有最高优先级,resource或URL加载的属性次之,最低优先级的是properties元素体内定义的属性
建议:
不要在properties体内,添加任何属性。只是将属性值定义在properties中,在properties文件中定义属性名要有一定的特殊性
5.2 setting(全局配置参数)
mybatis框架可以调整运行时的参数
比如二级缓存,
但是全局参数将会影响mybatis的运行行为
5.3 typeAliases(别名) 重点
5.3.1 需求
在mapper.xml中,定义了许多的statement,statement需要parameteType指定输入参数的类型、需要resultType指定输出结果的映射类型。
如果在指定类型时输入类型全路径,不方便进行开发,可以根据parameteType或者resultType来设置定义别名,然后再mapper.xml通过别名来定义,方便开发
5.3.2 mybatis支持定义别名,
5.3.2.1 单个别名的定义
<!-- 针对单个别名的定义 
type:类型的路径
Aliases:别名-->
<typeAlias type="com.Sopp.mybatis.pojo.User" alias="User"/>
5.3.2.2 批量别名的定义(常用)
<!-- 批量别名 
指定一个包名,mybatis会自动的来扫描包中的po类,自动的定义别名,别名就是类名(首字母大写或者小写)-->
<package name="com.Sopp.mybatis.pojo"/>
如果想定义很多,那么就需要定义很多包,然后进行批量扫描包就行。
5.4 typeHandlers(类处理器)
mybaits中通过typeHandlers来进行JDBC和Java类型之间的转换
一般不需要自定义,mybatis自身就支持很多处理器了,满足日常的需要,不需要我们进行自定义,
5.5 mappers(mapper的配置,也就是映射的配置)
5.5.1 加载单个映射文件
<!-- 加载映射文件 -->
<mappers>
<mapper resource = "sqlmap/User.xml"/>
<!--通过resource方法,来加载单个的映射文件-->
<mapper resource = "mapper/UserMapper.xml"/>
</mappers>  
5.5.2 通过mapper接口来加载
<!-- 通过mapper接口加载单个映射文件
需要遵循一些规范:
1.需要将mapper接口的类名和mapper.xml映射文件名称保持一致,且在一个目录 
上述规范的前提是使用的是mapper代理的方法
按照上面的规范,需要将mapper接口和mapper.xml放在一个目录下面,并且同名
但是下列方法,只是通过mapper接口加载了一个方法-->
<mapper class = "com.Sopp.mybatis.mapper.UserMapper"/>
5.5.3 通过mapper接口加载很多映射文件(推荐使用)
<!-- 还可以就行批量的进行加载
但是在这个里面我们需要制定mapper接口的包名,就会自动的对我们mapper接口包名进行加载 -->
<package name="com.Sopp.mybatis.mapper"/>
注意:在这里使用了这个包扫描过后,不能使用单个扫描,否则会报错,说已经扫描到了
6. 输入映射
通过parameteType指定输入参数的类型,可以是简单类型,HashMap,包装类型(pojo)
6.1 传递pojo的包装对象
6.1.1 需求
完成用户信息的综合查询,传入很多的查询条件(可能会包括:用户信息、其他信息、商品的、订单的);
针对上面的需求,建议使用自定义的包装类型的pojo。
6.1.2 在包装类型pojo将自己需要的复杂的查询条件包装进去
6.1.3 映射文件 mapper.xml和mapper.java
在UserMapper.xml中定义用户信息的综合查询(查询条件复杂,通过高级查询来进行复杂的关联查询),
<!-- 用户信息综合查询 
userQueryVo.sex取出pojo包装对象的sex的值
${userQueryVo.username} 取出pojo包装对象的用户名称-->
<select  id = "findUserList" parameterType="UserQueryVo" resultType="UserQueryVo">
select * from user where user.sex=#{userQueryVo.sex} and user.username like '%${userQueryVo.username}%'
</select>
6.1.4 mapper.java
//用户信息的综合查询
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws IOException;
7.输出映射
7.1 resultType
已经使用过了,
使用resultType进行输出的映射,只有查询出来的列名和我们pojo的属性一致,该列才能映射成功
如果不一致,就没有创建pojo对象
只要查询出来的列名和属性名有一个一致,就会创建一个pojo对象
还能输出简单类型
7.1.1 需求
用户信息的综合查询列表总数,通过查询总数和上边用户综合查询列表才可以实现分页。
7.1.1.1 mapper.java
//用户信息的综合查询总数
public int findUserCount(UserQueryVo userQueryVo) throws IOException;
7.1.1.2 mapper.xml
<!-- 用户信息的综合查询总数 
parameterType:指定的输入类型,和上面的综合查询是一样的
resultType:输出的结果类型-->
<select id = "findUserCount" parameterType="UserQueryVo" resultType="int">
select count(*) from user where user.sex=#{userCustom.sex} and user.username like '%${userCustom.username}%'
</select>
7.1.1.3 测试代码
@Test
public void userCount() throws Exception{
//需要通过会话工厂得到会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建一个UserMapper的对象,这一句是mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//在正式操作之前,需要创建一个pojo包装对象,同时设置查询条件
UserCustom userCustom = new UserCustom();
userCustom.setSex("男");
userCustom.setUsername("小明");
UserQueryVo userQueryVo = new UserQueryVo();
userQueryVo.setUserCustom(userCustom);
//调用userMapper的方法
int number = userMapper.findUserCount(userQueryVo);
System.out.println(number);
}
7.1.1.4 总结
查询出来的结果集,只有一行,且只有一列,这个时候可以使用简单类型来做输出的映射。
不管是输出的pojo是单个对象,还是一个列表(list包括pojo),在mapper.xml中resultType指定的类型是一样的。
在mapper.java指定的方法返回值类型不一样:
1.输出单个pojo对象,方法返回值是一个单个对象类型
2.输出pojo对象列表List,方法返回值为List<pojo>
动态代理的对象中生成的是根据mapper方法的返回值类型来确定是调用selectOne(单个对象)还是selectList(集合对象调用)
7.2 resultMap
mybatis可以使用resultMap来完成高级输出结果的映射
7.2.1 resultMap使用方法
如果查询出来的列名和pojo属性名不一致,这个时候可以通过定义resultMap来对列名和属性名之间做一个映射关系
1.定义resultMap
2.使用resultMap作为statement的输出映射类型
7.2.2 需求
将下边的sql使用UserCustomer完成映射
select id id_,username username_ from user where id = #{id}
user类中的属性名和上面查询的列名不一致
7.2.2.1 定义resultMap
<resultMap type="user" id="userreusltMap">
<!-- id标识查询结果集中唯一的标识
conlumn查询出来的列名 
property:typez指定的pojo类型中的属性名
最终resultMap对我们的conlumn和property做一个映射关系-->
<id column="id_" property="id"/>
<!-- result:对普通名的映射定义
column:查询出来的列名
property:type指定的pojo类型的类型名
最终resultMap对column和property作一个映射关系(对应关系)-->
<result column="username_" property="username"/>
</resultMap>
7.2.2.2 使用resultMap作为输出类型
<!-- 使用resultMap来进行输出的映射 
resultMap:指定定义的resultMap的id,如果这个resultMap在其他的mapper文件中,前边需要加
namespace-->
<select id = "findUserByIdResultMap" parameterType="java.lang.String" resultMap="">
select id id_,username username_ from user where id = #{id}
</select>
7.2.2.3 mapper.java
//根据ID查询用户信息,使用resultMap输出
public User findUserByIdResultMap(String id) throws IOException;
7.2.2.4 测试
@Test
public void resultMap() throws Exception{
//需要通过会话工厂得到会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建一个UserMapper的对象,这一句是mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用mapper方法
User user = userMapper.findUserByIdResultMap("10");
System.out.println(user);
}
7.3 小结
resultType进行映射,必须列明和属性名一致才能成功
不一致,使用resultMap
8.动态sql
8.1 什么是动态sql
mybatis的核心 对sql语句进行灵活的操作,通过一些表达式,来对我们的sql进行判断,从而对sql进行灵活的拼接、组装。
8.2 需求
用户信息综合查询列表和用户信息查询列表总数这两个statement的定义使用动态sql
对查询条件进行判断,如果输入的参数不为空,才进行查询条件的拼接
8.3 mapper.xml
<!-- 用户信息综合查询 
userQueryVo.sex取出pojo包装对象的sex的值
${userQueryVo.username} 取出pojo包装对象的用户名称-->
<select  id = "findUserList" parameterType="UserQueryVo" resultType="UserCustom">
select * from user 
<!-- 可以自动的去掉条件中的第一个and -->
<where>
<if test = "userCustom != null">
<if test ="userCustom.sex!=null and userCustom.sex!=''">
and user.sex = #{userCustom.sex}
</if>
<if test ="userCustom.username!=null and userCustom.username!=''">
and user.username = #{userCustom.username}
</if>
</if>
</where>
</select>
8.4 测试代码

@Test
public void userList() throws Exception{
//需要通过会话工厂得到会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建一个UserMapper的对象,这一句是mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//在正式操作之前,需要创建一个pojo包装对象,同时设置查询条件
UserCustom userCustom = new UserCustom();
UserQueryVo userQueryVo = new UserQueryVo();
//由于这里写了动态sql,所以说这里不设置某一个值,条件是不会拼接在SQL中,
// userCustom.setSex("男");
// userCustom.setUsername("张三");
userQueryVo.setUserCustom(userCustom);
//调用userMapper的方法
List<UserCustom> list = userMapper.findUserList(null);
System.out.println(list);
}

8.5 sql片段
8.5.1 需求
将上面实现的动态sql的判断代码块,抽取出来,组成一个sql片段。其他的statement中就可以来引用这个sql片段,方便程序员开发
8.5.2 动态sql书写
<!-- 定义sql片段 
id:sql片段的唯一标识
经验:
1.一般是基于单表来定义sql片段,可重用性才高
2.在sql片段中不要包括where-->
<sql id="queryUserWhere">
<where>
<if test = "userCustom != null">
<if test ="userCustom.sex!=null and userCustom.sex!=''">
and user.sex = #{userCustom.sex}
</if>
<if test ="userCustom.username!=null and userCustom.username!=''">
and user.username = #{userCustom.username}
</if>
</if>
</where>
</sql>
8.5.3 使用SQL片段
<!-- 用户信息综合查询 
userQueryVo.sex取出pojo包装对象的sex的值
${userQueryVo.username} 取出pojo包装对象的用户名称-->
<select  id = "findUserList" parameterType="UserQueryVo" resultType="UserCustom">
select * from user 
<!-- 可以自动的去掉条件中的第一个and -->
<where>
<include refid="queryUserWhere"></include>
<!-- 如果不在本包里面,需要在namespace -->
<!-- 还要引用其他的sql片段 -->
</where>
</select>
8.5.4 测试sql片段
8.6 foreach
如果向sql中传递了一个list(数组),mybatis使用foreach进行解析
8.6.1 需求
在用户查询列表和查询总数的statement中,增加多个id的输入查询,
sql语句如下:
两种方法
select * user where id = 1 or id = 10 or id = 16;
select * user id in(1,10,16);
8.6.2 在输入的参数类型中要添加List<Integer>这个属性,来传入多个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 = 10 or id = 16) -->
<foreach collection="ids" item = "user_id" open="and(" close=")" separator="or">
<!-- 每次遍历需要拼接的串 -->
id = #{user_id}
</foreach>
</if>
8.6.4 测试代码
@Test
public void userList() throws Exception{
//需要通过会话工厂得到会话
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建一个UserMapper的对象,这一句是mybatis自动生成mapper代理对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//在正式操作之前,需要创建一个pojo包装对象,同时设置查询条件
UserCustom userCustom = new UserCustom();
UserQueryVo userQueryVo = new UserQueryVo();
//由于这里写了动态sql,所以说这里不设置某一个值,条件是不会拼接在SQL中,
/*这里需要传入多个id*/
List<Integer> ids = new ArrayList<Integer>();
ids.add(1);
ids.add(10);
ids.add(16);
userCustom.setSex("男");
// userCustom.setUsername("张三");
userQueryVo.setUserCustom(userCustom);
userQueryVo.setIds(ids);
//调用userMapper的方法
List<UserCustom> list = userMapper.findUserList(userQueryVo);
System.out.println(list);
}

路过

鸡蛋

鲜花

握手

雷人

评论 (0 个评论)

facelist

doodle 涂鸦板

您需要登录后才可以评论 登录 | 立即注册

Copyright;  ©2015-2017  知了堂学习社区  Powered by  知了堂Edu!     ( 蜀ICP备16011312号-1 )