Mybatis核心技术
来源:互联网 发布:牧场系统源码 编辑:程序博客网 时间:2024/06/08 06:43
介绍
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation迁移到了google code,并且改名为MyBatis 。2013年11月迁移到Github。 MyBatis是一个优秀的持久层框架,它对jdbc的操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatement、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
使用原生jdbc出现的问题
1、 数据库链接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题。
2、 Sql语句在代码中硬编码,造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。
3、 使用preparedStatement向占有位符号传参数存在硬编码,因为sql语句的where条件不一定,可能多也可能少,修改sql还要修改代码,系统不易维护。
4、 对结果集解析存在硬编码(查询列名),sql变化导致解析代码变化,系统不易维护,如果能将数据库记录封装成pojo对象解析比较方便。
Mybatis架构
Mybatis配置
SqlMapConfig.xml: mybatis的全局配置文件,配置了mybatis的运行环境等信息。Mapper.xml: sql映射文件,文件中配置了操作数据库的sql语句。此文件需要在sqlMapConfig.xml中加载。
#{}占位符:占位
如果传入的是基本类型,那么#{}中的变量名称可以随意写
如果传入的参数是pojo类型,那么#{}中的变量名称必须是pojo中的属性.属性名(user.username)
${}拼接符:字符串原样拼接(有sql注入的风险)
如果传入的是基本类型,那么${}中的变量名必须是value
如果传入的参数是pojo类型,那么${}中的变量名称必须是pojo中的属性.属性名(user.username)
注意:使用拼接符有可能造成sql注入,在页面输入的时候可以加入校验,不可输入sql关键字,不可输入空格
注意:如果是取简单数量类型的参数,括号中的值必须为value
例: select * from user where username like '%${value}%'
可以这样写来解决sql注入:select * from user where username like '%’ #{name}’%'(开发经常使用)
入门
SqlMapConfig.xml配置:
<?xml version="1.0" encoding="UTF-8" ?><!DOCTYPE configurationPUBLIC "-//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.mysql.jdbc.Driver" /><property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" /><property name="username" value="root" /><property name="password" value="root" /></dataSource></environment></environments><!—关联映射--><mappers><mapper resource="sqlmap/User.xml"/></mappers></configuration>
经测验映射文件最好和核心配置文件在一个文件夹下
properties(属性)
settings(全局配置参数)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境集合属性对象)
environment(环境子属性对象)
transactionManager(事务管理)
dataSource(数据源)
mappers(映射器)
Mapper配置文件
配表与pojo关系,以及sql<!-- 根据id获取用户信息 --><select id="findUserById" parameterType="int " resultType="cn.itcast.mybatis.po.User" > select * from user where id = #{id}</select>
resultType:定义结果映射类型(返回值)。
mybatis支持别名:
别名 映射的类型_byte byte
_long long
_short short
_int int
_integer int
_double double
_float float
_boolean boolean
string String
byte Byte
long Long
short Short
int Integer
integer Integer
double Double
float Float
boolean Boolean
date Date
decimal BigDecimal
bigdecimal BigDecimal
map Map
动态Sql
If
通过mybatis提供的各种标签方法实现动态拼接sql原始sql语句:
Mybatis中简单的sql语句:
<select id="findUserByNameAndSex" parameterType="user" resultType="user"> SELECT * FROM USER WHERE username LIKE '%${username}%' AND sex=#{sex}</select>
trim
<trim prefix="(" suffix=")" prefixOverrides="and" ></trim>
prefix:前缀覆盖并增加其内容 不写的话默认替换为空
suffix:后缀覆盖并增加其内容 不写的话默认替换为空
prefixOverrides:前缀判断的条件
suffixOverrides:后缀判断的条件
使用动态sql语句:
where
<select id="findUserByNameAndSex" parameterType="user" resultType="user"> SELECT * FROM USER <where><!-- 他能自动判断将where关键字后的and去掉 --> <if test="username!=null and username!=''"> AND username LIKE '%${username}%' </if> <if test="sex!=null and sex!=''"> AND sex=#{sex} </if> </where></select>
<where> 可以自动去除sql语句where关键字后的and关键字
Foreach
向sql传递数组或List, mybatis使用foreach解析,可以做批量处理Sql语句:
使用foreach赋值:
<select id="findUserByIds" parameterType="queryVo" resultType="user"> SELECT * FROM USER <where> <foreach collection="ids" open="id IN (" close=")" item="id" separator=","> #{id} </foreach> </where></select>
collection:传入的集合的变量名称(要遍历的值)
item:每次循环将循环出的数据放入这个变量中
open:循环开始拼接的字符串
close:循环结束拼接的字符串
separator:循环中拼接的分隔符
批量修改实例:
sql:
<!-- 批量修改 --><update id="updateByList" parameterType="java.util.List" > UPDATE rc_notify_queue SET queue_status = 'E',execute_time=NOW() <where> <foreach collection="list" open="notify_queue_Id IN (" close=")" item="notify" separator=","> #{notify.notifyQueueId} </foreach> </where></update>
choose
sql片段
Sql中可将重复的sql提取出来,使用时用include引用即可,最终达到sql重用的目的将where条件抽取出来:
<sql id="user_where"> <where> <if test="username!=null and username!=''"> AND username LIKE '%${username}%' </if> </where></sql>
引用:
<select id="findUserByNameAndSex" parameterType="user" resultType="user"> SELECT * FROM USER <include refid="user_where"/></select>
注意:也可在sql标签中也可以只放if标签
关联查询:
解决方案一:创建一个有两个表的数据类
<!-- 一对一:自动映射 -->
<!-- 一对一:自动映射 --><select id="findOrdersAndUser" resultType="customOrders"> SELECT * FROM USER a , orders b WHERE a.id = b.user_id</select>和普通方法是一样的,只是要多创建一个po类
<resultMap type="orders" id="orderAndUserResultMap"> <id column="id" property="id"/> <result column="userId" property="user_id"/> <result column="number" property="number"/> <result column="createtime" property="createtime"/> <result column="note" property="note"/> <!-- 封装对象属性 --> <association property="user" javaType="com.itheima.pojo.User"> <id column="id" property="id"/> <result column="username" property="username"/> <result column="sex" property="sex"/> <result column="address" property="address"/> <result column="birthday" property="birthday"/> </association></resultMap>
使用:
<select id="findOrdersAndUser2" resultMap="orderAndUserResultMap"> SELECT * FROM USER a , orders b WHERE a.id = b.user_id</select>
Type: po类的权限定名,这里使用的是别名
Id: 主键
Result: 普通属性
Column: po类属性
Property: 表字段名
Association: 引用数据类型
Property: 在po类中的名称
JavaType: 全限定名
分两块,第一块使用resultMap标签封装数据,第二块在select中使用resultMap引用封装好的数据;
封装map集合:
返回结果集类型: resultType="java.util.Map"查询后返回的结果:List<Map>
将数据库中每条数据:字段和值按照 key(字段名),value(字段值) 封装到hashMap集合中
然后在把Map集合封装到Llist集合中
将一条数据封装成map集合:
<resultMap type="java.util.Map" id="orderAndUserResultMap"> <id column="cid" property="cid"/> <result column="cust_name" property="cust_name"/> <result column="cust_type" property="cust_type"/> <result column="cust_phone" property="cust_phone"/> <result column="cust_address" property="cust_address"/> <result column="custlink_user" property="custlink_user"/></resultMap><select id="findCustList" parameterType="cn.itheima.pojo.QueryVo" resultMap="orderAndUserResultMap"> SELECT * FROM s_cust </select>
Column就是map集合的key Property数据库传来的数据注意:property值对应数据库中的字段值这种方式只能获取一条数据
Spring整合mybatis
SqlMapConfig.xml配置:<typeAliases><!-- 包扫描 --><package name="com.mybatis.pojo"/></typeAliases><!-- 关联映射 --><mappers> <mapper resource="User.xml"/> <!-- 包扫描 --> <package name="com.mybatis.dao"/></mappers>
其余交个spring管理
ApplicationContext.xml
配置dataSource
配置sqlSessionFactory
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <!-- 指定mybatis核心配置文件 --> <property name="configLocation" value="classpath:SqlMapConfig.xml"></property> <!-- 指定会话工厂使用的数据源 --> <property name="dataSource" ref="dataSource"></property></bean>
原生Dao实现:原生Dao实现和普通类的配置一样
Mapper接口代理:
方式一:
<bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean"> <!-- 配置mapper接口的全路径名称 --> <property name="mapperInterface" value="com.mybatis.dao.UserMapper"></property> <property name="sqlSessionFactory" ref="sqlSessionFactory"></property> </bean>
注意:
Bean标签中class属性是mybatis提供的接口代理对象所以是固定的
name="mapperInterface"和name="sqlSessionFactory" 代理对象中的属性也是固定的
方式二:包扫描
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="cn.mybatis.dao"></property></bean>
注意:
使用包扫描的方式批量引入Mapper扫描后引用的时候可以使用类名,首字母小写.
指定要扫描的包的全路径名称,如果有多个包用英文状态下的逗号分隔
- Mybatis核心技术
- mybatis框架(六)——核心技术与原理
- Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis+KafKa j2ee分布式架构核心技术
- Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis+KafKa j2ee分布式架构核心技术
- Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis+KafKa j2ee分布式架构核心技术
- Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis+KafKa j2ee分布式架构核心技术
- Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis+KafKa j2ee分布式架构核心技术
- Springmvc+mybatis+shiro+Dubbo+ZooKeeper+Redis+KafKa j2ee分布式架构核心技术
- Spring核心技术
- J2EE 核心技术
- liferay核心技术
- J2EE核心技术
- Spring核心技术
- Spring核心技术
- WCF核心技术
- Google核心技术
- 《JavaScript核心技术》
- NVS核心技术
- SPOJ
- (九)redis GEO地理位置
- JS总结——DOM事件
- 使用IDEA 总结
- 5、redis的两大持久化方式
- Mybatis核心技术
- STM32采集多路ADC到DMA的方法
- mybatis初步学习
- HDU6198-number number number
- jQuery :eq(注意是从零开始的index哦)
- ssh client 报 algorithm negotiation failed的解决方法之一
- redis学习笔记整理
- springboot与mybatis的整合
- notePad++插件的强大