mybatis入门(三):mybatis的基础特性
mybatis的知识点:
1.mybatis和hibernate本质区别和应用场景
hibernate:是一个标准的ORM框架(Ojbect relation mapper对象关系映射).入门门槛较高的,不需要程序员写sql,
sql语句自动生成了。对sql语句进行优化,修改比较困难。
应用场景:
适用于需求变化不多的中小型项目.比如后台管理,erp,orm,oa..
mybatis:专注于sql本身,需要程序员自己编写sql语句,sql修改,优化比较方便,mybatis是一个不完全的ORM框架,
虽然程序员自己写sql,mybatis也可以实现映射(输入映射,输出映射)
应用场景:
适用于需求变化较多的项目,比如:互联网项目
2.sqlSession:是一个面向用户(程序员)的接口
sqlSession中提供了很多操作数据的方法.如:selectOne(返回单个对象),selectList(返回单个或多个对象)
sqlSession是线程不安全的,在sqlSession实现了除了接口有的方法(操作数据库的方法)还有数据域属性
sqlSession最佳应用场合在方法体内,定义成局部变量使用。
3.总结原始dao开发的问题(User.xml)
1.dao接口实现类方法中存在大量模板方法,设想能否将这些代码提取出来,大大减轻程序员的工作量
2.调用sqlsession方法是将statement的id硬编码了 3.调用sqlsession方法是传入的变量,由于sqlsession方法使用泛型,即使变量传入错误,在编译阶段也不报错。
不利于程序员开发
4.mapper代理方法(程序员只需要mapper接口(相当于dao接口))
1.还需要编写mapper.xml映射文件(同时切记要在sqlMapConfig.xml里面加上这个)
2.程序员只需要开发mapper接口需要遵循一些开发规范,mybatis可以自动生成mapper接口实现类的代理对象
开发规范:
1.在mapper.xml中namespace等于mapper接口地址
<!-- namespace命名空间,作用就是对sql进行分类化管理,理解sql隔离-->
<!--注意:使用mapper代理方法开发,namespace有特殊重要的作用-->
<mapper namespace="cn.wj.test.mybatis.mapper.UserMapper">
2.mapper.java接口中的方法名和mapper.xml中statement的id一致 3.mapper.java接口中的方法输入参数类型和mapper.xml中parameterType指定的类型一致 4.mapper.java接口中方法的返回值的类型和mapper.xml中statement中resultType的类型一致
例如:
mapper.java接口方法:
//根据id查询查询用户(此时这个方法名要和statement的id保持一致)
public User findUserById(int id) throws Exception;
UserMapper.xml:
<select id="findUserById" parameterType="int" resultType="cn.wj.test.mybatis.pojo.User">
select * from user where id = #{id}
</select>
在sqlMapper.xml添加UserMapper.xml映射
总结:以上的开发规范主要是对下边代码进行统一的生成
3.代理对象内部调用selectOne或selectList
如果mapper方法返回单个pojo对象(非集合对象),代理对象内部通过selectOne查询数据库
如果mapper方法返回集合对象,代理对象内部通过selectList查询数据库
4.mapper接口方法参数只能有一个是否影响系统开发
mapper接口方法参数只有一个,系统是否不利于扩展维护?
答:系统框架中,dao层的代码是被业务员公用的
即使mapper接口中只有一个参数,也可以使用包装类型的pojo满足不同的业务方法的需求 注意:持久层方法的参数可以是包装类型,
map...,service方法中建议不要使用包装类型(不利于业务层的可扩展)
5.sqlMapConfig.xml中配置文件的内容和顺序如下:
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
1.properties(属性)
需求: 将数据库连接参数单独配置在db.properties中,只需要在sqlMapConfig.xml中加载dp.properties的属性值,
在sqlMapperConfig.xml就不需要对数据库的连接参数进行编码了
properties特性:
注意:mybatis将按照下面的顺序加载属性
1.在properties元素体内定义的属性首先挥别读取
2.然后会读取properties元素中resource或url加载的属性,他会覆盖已读取的同名属性
3.最后读取parameterType传递的属性,他会覆盖已读取的同名属性
建议:
不要在properties元素体内添加任何属性值,只将属性值定义在prperties中,在properties文件中属性名一定有一定的特性:如xxxx.xxx.xx
例子:
1.db.properties(这个里面就是属性名就是比较特殊,例如jdbc.driver,jdbc。url)
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatisData?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
sqlMapConfig文件中:
<!-- 加载属性文件 -->
<properties resource="db.properties">
<!--properties中可以配置一些属性名和属性值-->
<!--<property name="" value=""/>-->
</properties>
<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>
(其中加载这个文件properties,则底下dataSource里面的参数则是property)
2.settings(配置)
mybatis全局配置参数,全局参数将会影响mybatis运行行为
3.typeAliases(别名)
需求:
在mapper.xml中定义了很多的statement,statement需要指定参数的类型,需要resultMap指定输出结果的映射类型
如果在指定类型时输入类型全路径,不方便进行开发,可以针对parameterType或resultType指定的类型定义的一些别名,在mapper.xml通过别名定义,方便开发。
<typeAliases>
<!--
针对单个别名的定义
type:类型的路径
alias:别名
-->
<typeAlias type="cn.wj.test.mybatis.pojo.User" alias="user"/>
<!--
批量定义别名(较为常用)
指定包名,mybatis自动扫描包中的po类,自动定义别名,别名就是类名(首字母大小写都可)
-->
<package name="cn.wj.test.mybatis.pojo"/>
</typeAliases>
引用别名:
<select id="findUserById" parameterType="int" resultType="user">
select * from user where id = #{id}
</select>
4.typeHandlers(类型处理器)
mybatis中通过typeHandlers完成jdbc类型和java类型的转换。
通常情况下,mybatis提供的类型处理器满足日常的需要,不需要我们自定义转换
5.mappers(mapper的映射配置)
1.通过resource来加载单个的映射文件
<!--通过resource方法一次加载一个映射文件-->
<mapper resource="mapper/UserMapper.xml"/>
2.通过mapper接口加载映射文件
<!--
通过mapper接口加载映射文件
遵循一些规范:需要将mapper接口类名和mapper.xml映射文件保持一致,且在一个目录中
上边的规范是mapper接口加载映射文件
-->
<mapper class="cn.wj.test.mybatis.mapper.UserMapper"/>
3.批量添加mapper(包名,推荐使用)
<!--
批量加载mapper
指定mapper接口的包名,mybatis自动扫描包下面所有的mapper接口进行加载
上边的规范是mapper接口加载映射文件
-->
<package name="cn.wj.test.mybatis.mapper"/>
6.输入映射
通过parameterType指定输入参数的类型,类型可以是简单类型,hashmap,poji的包装对象
需求:
完成用户信息的综合查询,需要传入的查询条件很复杂(可能包括用户信息,其他信息,比如商品,订单)
针对
UserMapper.xml
<!--
用户的综合查询
#{userCustom.sex}:取出包装类型的值
${userCustom.username}:取出pojo包装类型对象的名称
-->
<select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'
</select>
UserMapper.java
//用户信息的综合查询
public List<UserCustom> findUserList(UserQueryVo userQueryVo) throws Exception; 测试代码:
@Test
public void testfindUserList()throws Exception{
SqlSession sqlSession = sqlSessionFactory.openSession();
//创建UserMapper对象,mybatis自动生成mapper对象
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用userMapper的方法
UserCustom userCustom = new UserCustom();
userCustom.setSex("m");
userCustom.setUsername("123");
UserQueryVo userQueryVo = new UserQueryVo();
userQueryVo.setUserCustom(userCustom);
List<UserCustom> userList = userMapper.findUserList(userQueryVo);
System.out.println(userList);
}
7.输出映射
1.resultType:
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名保持一致,该列才可以映射成功。
如果查询出来的列名和pojo中的属性名全部不一致,没有创建pojo对象
只要查询出来的列名和pojo中的属性有一个一致,就会创建pojo对象。
输出简单类型:切记:输出简单类型只有一行一列的数据
2.resultMap:
mybatis中使用resultMap完成高级输出结果映射
resultMap使用方法:
如果查询出来的列名和pojo的属性名不一致,通过定义一个resultMap列名和pojo属性名做一个映射关系
1.定义resultMap
UserMapper.xml
<!--
定义resultMap
将select id id_,username username_和User中的属性作为一个映射关系
type:resultMap最终映射的java对象类型,可以使用别名
id:对resultMap的唯一标识
-->
<resultMap id="userResultMap" type="cn.wj.test.mybatis.pojo.User">
<!--
id表示查询结果集中唯一标识
column:查询出来的列名
property:type指定的pojo类型中的属性名
最终resultMap对column和property做一个映射关系(对应关系)
-->
<id column="id_" property="id"/>
<!--
result:标识对于普通名的映射
column:查询出来的列名
property:type指定的pojo类型中的属性名
最终resultMap对column和property做一个映射关系(对应关系)
-->
<result column="username_" property="username"></result>
</resultMap>
2.使用resultMap作为statement的输出映射类型(返回参数使用resultMap)
<!--
使用resultMap来进行输出的映射
resultMap:指定定义的resultMap的id,如果这个resultMap在其他mapper文件中,前边需要加namespace
-->
<select id="findUserByIdResultMap" parameterType="int" resultMap="userResultMap">
select id id_,username username_ from user where id = #{id}
</select>
userMapper.java中的接口调用
//根据用户信息查询用户列表,根据resultMap输出
public User findUserByIdResultMap(int id) throws Exception;
小节:
使用resultType进行输出映射,只有查询出来的列名和pojo中的属性名一致,该列才可以映射成功。
如果查询出来的列名和pojo属性名不一致,通过定义一个resultMap队列名和pojo属性名之间做一个映射关系。
8.动态sql
1.什么是动态sql:
mybatis核心:对sql语句进行灵活的操作,通过表达式进行判断,对sql进行灵活的拼接,组装。
原来的查询语句:
<select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'
</select>
现在的查询语句
理由:由于原来的查询语句可能userCustom是null或者里面的参数为‘’,所以我们可以使用动态sql来进行判断
<select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
<!--
where可以自动去掉条件中的第一个add
-->
<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 username like '%${userCustom.username}%'
</if>
</if>
</where>
</select>
9.动态sql代码段
将上边实现的动态sql判断代码块抽取出来,组成一个sql片段,其他的statement就可以引用sql片段
1.定义sql片段
<!--
定义sql片段
id:sql片段的唯一标识
经验:是基于单表来定义sql片段,这样的话sql片段的可重用性才高
在slq片段中不要包括where
-->
sql片段定义:
<sql id="query_user_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 username like '%${userCustom.username}%'
</if>
</if>
</sql>
sql片段引用:
<select id="findUserList" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.UserCustom">
<!--select * from user where user.sex = #{userCustom.sex} and username like '%${userCustom.username}%'username-->
select * from user
<!--
where可以自动去掉条件中的第一个add
-->
<where>
<!--引用sql片段的id,如果refid指定的id不在本mapper文件中,需要前边加namespace-->
<include refid="query_user_where"></include>
</where>
</select>
foreach标签
向sql传递数据或List,mybatis使用foreach解析
两种方法:
select * from user where (id = 1 or id =2)
select * from user where id in (1 , 2)
foreach的sql片段:
<sql id="query_user_where">
<if test="userCustom != null">
<if test="ids != null">
<!--
使用foreach遍历ids
collection:指定输入对象中集合属性
item:每个遍历生成的对象中
open:开始遍历时拼接的串
close:结束遍历时拼接的串
separator:遍历中两个对象需要拼接的串
-->
<!--
方法一:
使用实现下边的sql拼接:
AND (id = 1 OF id = 10)
-->
<foreach collection="ids" item="item_id" open="and (" close=")" separator="or">
<!--每个遍历需要拼接的串-->
id = #{item_id}
</foreach> 或者我们也可以才去这种方法
<!--
方法二:
使用实现下边的sql拼接:
And id in (1,10)
-->
<foreach collection="ids" item="item_id" open="and id in (" close=")" separator=",">
<!--每个遍历需要拼接的串-->
#{item_id}
</foreach>
</if>
</if>
</sql>
UserMapper.xml的sql片段的调用
<select id="selectUserByForeach" parameterType="cn.wj.test.mybatis.pojo.UserQueryVo" resultType="cn.wj.test.mybatis.pojo.User">
select * from user
<where>
<include refid="query_user_foreach"/>
</where>
</select>
mybatis入门(三):mybatis的基础特性的更多相关文章
- Mybatis入门之MyBatis基础
一.MyBatis概述 1.ORM模型简介 ORM:对象关系映射(Object Relation Mapping) 1)传统JDBC程序的设计缺陷(实际项目不使用) a.大量配置信息硬编码 b.大量的 ...
- mybatis入门--初识mybatis
初识mybatis 今天,一起来说说mybits这个框架吧.这是一个持久层的框架.之前叫做ibatis.所以,在它的代码中出现ibatis这个词的时候,不要感到惊讶.不是写错了,它确实就是这个样子的. ...
- <MyBatis>入门三 sqlMapper文件
增加 1.增删改在接口中的返回值 Integer.Long.Boolean.void 返回影响多少行 或 true | false 2.mapper 中 增删改没有返回值 (resultType或re ...
- Mybatis入门三
一.连接数据库的配置单独放在一个properties文件中 之前,我们是直接将数据库的连接配置信息写在了MyBatis的conf.xml文件中,如下: <?xml version="1 ...
- Mybatis入门之MyBatis项目案例
一.项目案例演示 后台管理系统用户数据维护平台 所有用户数据查询 单个用户数据查询 用户数据修改(完善资料) 锁定用户账号 删除用户账号 彻底删除用户账号 二.数据库数据准备工作 数据库:mysql ...
- MyBatis学习(三)---MyBatis和Spring整合
想要了解MyBatis基础的朋友可以通过传送门: MyBatis学习(一)---配置文件,Mapper接口和动态SQL http://www.cnblogs.com/ghq120/p/8322302. ...
- mybatis入门案例自定义实现
mybatis入门案例自定义实现 一.需要实现的类和接口 public static void main(String[] args) throws Exception{ //1.读取配置文件 Inp ...
- MyBatis入门使用
MyBatis入门使用 MyBatis简介 MyBatis是支持普通SQL查询.存储过程和高级映射的持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及结果集的检索.MyBati ...
- mybatis入门基础(二)----原始dao的开发和mapper代理开发
承接上一篇 mybatis入门基础(一) 看过上一篇的朋友,肯定可以看出,里面的MybatisService中存在大量的重复代码,看起来不是很清楚,但第一次那样写,是为了解mybatis的执行步骤,先 ...
随机推荐
- Oracle查看每小时日志切换量脚本
---- Show the Number of Redo Log Switches Per Hour-- SET PAUSE ONSET PAUSE 'Press Return to Continue ...
- MapReduce过程详解(基于hadoop2.x架构)
本文基于hadoop2.x架构详细描述了mapreduce的执行过程,包括partition,combiner,shuffle等组件以及yarn平台与mapreduce编程模型的关系. mapredu ...
- Json.Net 中Linq to JSON的操作
Linq to JSON是用来操作JSON对象的.可以用于快速查询,修改和创建JSON对象.当JSON对象内容比较复杂,而我们仅仅需要其中的一小部分数据时,可以考虑使用Linq to JSON来读取和 ...
- linux 上部署tomcat的java web项目,会出现post提交request.request.getParameter()的得不到值的情况
有时候明明在windows上非常的正常,而在linux上就不正常了,在windows上post提交request.request.getParameter()有值,而在liunx上没有值. 我开始以为 ...
- 20145223 杨梦云 《网络对抗》shellcode实验+return-to-libc实验
20145223 杨梦云 <网络对抗>shellcode实验+return-to-libc实验 shellcode注入实践 Shellcode基础知识 ·Shellcode实际是一段代码( ...
- 一张图解释 implicit
- win7 xampp php7 yii2 配置sqlserver
第一步: https://www.microsoft.com/en-us/download/details.aspx?id=20098 下载 如下图 php7 版本 放到 xampp\php ...
- VC++ MFC工程中中如何将一个工程的资源(如对话框)复制到另外一个工程
问题的提出:在工程1中用到的资源,在工程2中已有现成的.即工程1中要用到的对话框和工程2的完全相同,而工程2中对该对话框的布局已设计好.控件变量都绑定好了.但由于该对话框的控件特别多,如果在工程1中再 ...
- java线程安全单例
public class MySingleton { // 使用volatile关键字保其可见性 volatile private static MySingleton instance = null ...
- 使用单例模式来打造ActivityManager类
单例(Singleton)模式 定义 单例模式是一种对象创建型模式,使用单例模式,可以保证为一个类只生成唯一的实例对象.也就是说,在整个程序空间中,该类只存在一个实例对象. GoF对单例模式的定义是: ...