MyBatis工作在数据访问层,此时的数据访问层就可以只编写 映射器接口 和 映射xml文件
使用场景:JavaSE、JavaEE(JavaWeb)
ProductMapper
ProductMapper.xml
通过API类加载配置文件和映射器接口类,最后就可以在MyBatis中使用实例化的接口对象
对象 | 重量级 | 使用 |
---|---|---|
SqlSessionFactory对象 | 重量级对象 | 创建一次 |
SqlSession对象 | 轻量级对象 | 可多次创建 |
.pom
配置文件中的dependencies
元素下添加以下内容:
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.4.6version>
dependency>
package com.MyBatis.demo.Dao;
import com.MyBatis.demo.bean.ProductInfo;
import java.util.List;
import java.util.Map;
public interface ProductMapper {
/**
* 根据商品Id查找商品信息
* @param productId
* @return
*/
ProductInfo getInfoById(Integer productId);
/**
* 查找所有商品信息
* @return
*/
List<ProductInfo> findAllProducts(Map<String,String> map);
/**
* 保存商品信息
* @param productInfo
* @return
*/
int saveInfo(ProductInfo productInfo);
/**
* 根据条件检索商品信息
* @param condition(Name lowPrice highPrice typeid)
* @return
*/
List<ProductInfo> findByCondition(Map<String,Object> condition);
/**
* 更新商品类别编号
* @param ids
* @return
*/
int updatePrdInfo(int[] ids);
/**
* 调用存储过程执行商品信息的查询
* @param map
*/
void findInfoByProcedure(Map<String,Object> map);
}
namespace
属性值为 映射器接口 的完整类名mapper
的子元素select
、update
、insert
、delete
的id
属性是映射xml文件对应的映射器接口的某个具体方法名mapper
的子元素update
、insert
、delete
不使用resultType
属性,默认返回整数,代表该语句影响的记录条数insert
的子元素selectKey
表示查询主键,具有keyColumn
、keyProperty
、order
、resultType
属性,能将查询结果存进keyProperty
指明的java对象属性中
属性 | 说明 |
---|---|
keyColumn |
主键对应的数据库列名 |
keyProperty |
主键对应的java对象属性名 |
order |
1.AFTER 父元素的SQL语句执行后执行2. BEFORE 父元素的SQL语句执行前执行 |
resultType |
主键返回的结果类型 |
<selectKey keyColumn="product_id" keyProperty="productId" resultType="int" order="BEFORE">
select ifnull(max(product_id)+1,1)
from products p
selectKey>
insert
可使用如下属性:<insert id="saveInfo" parameterType="ProductInfo" useGeneratedKeys="true" keyProperty="productId">
···
insert>
sql
元素可定义可重用的sql片段,其中的id
属性可唯一标识被引用的片段。引用语句如下:<include refid="id">include>
parameterType
、resultType
属性分别表示参数类型、返回类型,resultMap
属性表示结果类型映射(可重用)。resultType
属性和resultMap
属性不能同时存在parameterType
、resultType
属性取值为自定义类的完整限定名或MyBatis预定义别名。
resultType
属性设置为列表或集合中的元素类型别名 | java类型 | 别名 | java类型 | 别名 | java类型 |
---|---|---|---|---|---|
_byte | byte | byte | Byte | decimal | BigDecimal |
_long | long | long | Long | bigdecimal | BigDecimal |
_short | short | short | Short | object | Object |
_int | int | int | Integer | map | Map |
_integer | int | integer | Integer | hashmap | HashMap |
_double | double | double | Double | list | List |
_float | float | float | Float | arraylist | ArrayList |
_boolean | boolean | boolean | Boolean | collection | Collection |
string | String | date | Date | iterator | Iterator |
<
或>
在xml文件中的特殊语法,将包含<
或>
的SQL语句包含在
语句的空白处#{ }
#{ }
与${ }
区别
mapper
的子元素select
、update
、insert
、delete
中的SQL语句对应于映射器接口中的方法
#{id}
#{productId}
null
,则在占位符中添加指明jdbc
数据类型,例如:#{price,jdbcType=DECIMAL}
jdbc
数据类型与java
数据类型对应关系如下:
jdbcTyppe | javaType |
---|---|
TINYINT | byte |
SMALLINT | short |
INTEGER | int |
INTEGER | INTEGER |
INTEGER | long |
BIGINT | long |
FLOAT | float |
ERAL | float |
NUMERIC | double |
DOUBLE | double |
FLOAT | double |
VARCHAR | string |
CHAR | string |
LONGVARCHAR | string |
CLOB | string |
BINARY | byte[] |
VARBINARY | byte[] |
LONGVARBINARY | byte[] |
ARRAY | array |
BIT | boolean |
BOOLEAN | boolean |
NUMERIC | java.math.BigDecimal |
DECIMAL | java.math.BigDecimal |
DATE | java.sql.Date |
TIME | java.sql.Time |
TIMESTAMP | java.sql.Timestamp |
BLOB | Blob |
CLOB | Clob |
DISTINCT | mapping of underlying type |
STRUCT | struct |
REF | Ref |
DATALINK | java.net.URL[color=red][/color] |
tinyint
长度为1,即类型为:tinyint(1)
查询时,该字段对应的Java类型为boolean
;tinyInt1isBit=false
(默认为true
)tinyint
类型字段存储数字格式的数据resultMap
元素的type
属性使用类的完整限定名,也可以使用在核心配置文件Configuration.xml
中已定义过的简单别名resultMap
元素的子元素result
、id
(映射数据库主键)的column
属性表示SQL语句在数据库中对应的列名,而property
属性则表示的是java对象中的字段属性
<mapper namespace="com.MyBatis.demo.Dao.ProductMapper">
<sql id="sql1">
SELECT p.`product_id`,p.`name`,p.`product_type_id`,p.`price`,p.`description`
FROM products p
sql>
<select id="getInfoById" parameterType="int" resultMap="mp1">
select>
<select id="findAllProducts" parameterType="map" resultMap="mp1">
<include refid="sql1">include>
ORDER BY ${colName}
select>
<select id="findByCondition" parameterType="map" resultMap="mp1">
<include refid="sql1">include>
<where>
<if test="prdName!=null">p.`name` like CONCAT('%',#{prdName},'%')if>
<if test="lowPrice!=null">=#{lowPrice}]]>if>
<if test="highPrice!=null">if>
<if test="typeId!=null">AND p.`product_type_id`=#{typeId}if>
where>
select>
<update id="updatePrdInfo" parameterType="_int[]">
UPDATE products p SET p.`product_type_id`=3 WHERE p.`product_id` IN
<foreach collection="array" item="prdId" open="(" close=")" separator=",">
#{prdId}
foreach>
update>
<insert id="saveInfo" parameterType="productInfo">
<selectKey keyColumn="product_id" keyProperty="productId" resultType="int" order="BEFORE">
select ifnull(max(product_id)+1,1)
from products p
selectKey>
INSERT INTO products
VALUE(
#{productId},
#{proTypeId,jdbcType=INTEGER},
#{productName},
#{proDescription,jdbcType=VARCHAR},
#{price,jdbcType=DECIMAL})
insert>
<select id="findInfoByProcedure" parameterType="map" statementType="CALLABLE">
CALL pr_get_prd_info(#{prdId},
#{prdName,mode=OUT,jdbcType=VARCHAR},
#{typeId,mode=OUT,jdbcType=INTEGER},
#{desc,mode=OUT,jdbcType=VARCHAR},
#{price,mode=OUT,jdbcType=FLOAT})
select>
<resultMap type="productInfo" id="mp1">
<id column="product_id" property="productId">id>
<result column="product_type_id" property="proTypeId">result>
<result column="name" property="productName">result>
<result column="description" property="proDescription">result>
<result column="price" property="price">result>
resultMap>
mapper>
使用typeAliases
元素设置类的简单名(仅首字母小写)取代类的全限定名,如下:
<typeAliases>
<typeAlias type="com.MyBatis.demo.bean.ProductInfo" alias="productInfo">typeAlias>
<typeAlias type="com.MyBatis.demo.bean.ProductTypeInfo" alias="productTypeInfo">typeAlias>
typeAliases>
transactionManager : 事务管理器
类型 | 描述 |
---|---|
JDBC | MyBatis默认使用的提交和回滚管理事务 |
MANAGED | 由容器管理事务 如:Spring |
dataSource :配置数据源
三种数据源 UNPOOLED
、POOLED
、JNDI
UNPOOLED : 非池化 不采用连接池 的数据源
仅需配置driver url username password|
POOLED : 采用连接池的数据源
除配置driver url username password外
还可配置以下属性:
poolMaximumActiveConnections 最大活动连接数。默认值:10
poolMaximumIdleConnections 最大空闲连接数
poolMaximumCheckoutTime 池中连接的检查时间。默认值 20000毫秒(20秒)
JNDI : 从环境中获取数据源
<configuration>
<typeAliases>
<typeAlias type="com.MyBatis.demo.bean.ProductInfo" alias="productInfo">typeAlias>
<typeAlias type="com.MyBatis.demo.bean.ProductTypeInfo" alias="productTypeInfo">typeAlias>
typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/store?useSSL=false"/>
<property name="username" value="root"/>
<property name="password" value="root"/>
<property name="poolMaximumIdleConnections" value="1"/>
<property name="poolMaximumActiveConnections" value="5"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="com/MyBatis/demo/Dao/ProductMapper.xml">mapper>
mappers>
configuration>
SqlSessionFactoryBuilder().build(reader);
SqlSessionFactoryBuilder().build(Reader reader,String id);
String rs = "com/MyBatis/demo/Configuration.xml";
Reader reader = Resources.getResourceAsReader(rs);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(reader);
SqlSession session = sqlSessionFactory.openSession();
//手动提交
session.commit();
//设置自动提交
SqlSession openSession(boolean autoCommit);
//获取映射器接口Mapper实例
UserMapper productMapper = session.getMapper(ProductMapper.class);
ProductInfo productInfo = productMapper.getInfoById();
session.close();
关于映射xml文件的配置
在映射xml文件中,根元素
mapper
的子元素select
、update
、insert
、delete
都可使用动态SQL语句进行条件查询
元素
,以if
元素的test
属性内容作为判断条件动态的生成条件查询的SQL语句if
元素的test
属性的判断条件有一个是成立的,则在where
元素之前的SQL语句后面插入一个where
test
属性的判断条件成立,则将if
元素包含的SQL语句片段追加到已有的SQL语句片段上AND
或OR
开头,则将去掉AND
或OR
<where>
<if test="prdName!=null">p.`name` like CONCAT('%',#{prdName},'%')if>
<if test="lowPrice!=null">=#{lowPrice}]]>if>
<if test="highPrice!=null">if>
<if test="typeId!=null">AND p.`product_type_id`=#{typeId}if>
where>
元素还含有
子元素,
子元素下含有when
、otherwise
子元素
when
元素的test
属性判断条件成立,则仅将该when
元素包含的SQL语句片段追加到已有的SQL语句片段之后when
元素的test
属性判断条件都不成立,则将otherwise
元素中获得的SQL语句片段追加到已有的SQL语句片段之后
otherwise
元素下包含子元素if
<where>
<choose>
<when test="productId!=null">product_id=#{productId}when>
<otherwise>
<if test="productName!=null">and name like ···if>
<if test="typeId!=null">and ···if>
otherwise>
choose>
where>
元素
collection
属性表示取值参数的数据类型,可以是集合或数组(array)、列表(list)item
属性表示用来指定迭代元素的变量名open
属性表示迭代元素在SQL语句中的起始符号close
属性表示迭代元素在SQL语句中的结束符号separator
属性表示迭代元素之间的分隔符<update id="updatePrdInfo" parameterType="_int[]">
UPDATE products p SET p.`product_type_id`=3 WHERE p.`product_id` IN
<foreach collection="array" item="prdId" open="(" close=")" separator=",">
#{prdId}
foreach>
update>
查询时同时读取关联数据,只能使用
元素和
resultMap
属性进行配置,不能使用resultType
属性
resultMap
元素中与关联查询相的子元素有:association
、collection
association
元素
property
属性表示关联数据对象在结果映射对象中的属性名javaType
属性表示关联数据对象在java中的数据类型名id
、result
子元素<resultMap id="map2" type="productInfo">
<id column="product_id" property="productId">id>
<result column="name" property="productName">result>
<result column="description" property="proDescription">result>
<result column="price" property="price">result>
<association property="typeInfo" javaType="productTypeInfo">
<id column="product_type_id" property="typeId">id>
<result column="type_name" property="typeName">result>
association>
resultMap>
collection
元素
property
属性表示关联集合在结果映射对象中的属性名javaType
属性表示关联集合在java中的数据类型名(简单名或全限定名)ofType
属性表示关联集合中的元素在java中的数据类型(简单名或全限定名)id
、result
子元素<resultMap id="mapl" type="productTypeInfo">
<id column="product_type_id" property="typeId">id>
<result column="type_name" property="typeName">result>
<collection property="products" javaType="java.util.Set" ofType="productInfo">
<id column="product_id" property="productId">id>
<result column="name" property="productName">result>
<result column="description" property="proDescription">result>
<result column="price" property="price">result>
collection>
resultMap>
resultMap
属性对关联集合的元素进行存放<collection property="products" resultMap="rm3"/>
映射器接口方法传递多个形参时在xml配置中无需使用
parameterType
属性
#{ }
进行形参传递#{arg0}
、#{arg1}
、#{arg2}
、#{arg3}
···表示
null
,则需指明jdbc
数据类型<insert id="saveInfo2">
INSERT INTO products
VALUE(
0,
#{arg1,jdbcType=INTEGER},
#{arg0},
#{arg2,jdbcType=VARCHAR},
#{arg3,jdbcType=DECIMAL})
insert>
#{ }
传递的是映射器接口方法中的形参?
${ }
传递的是以形参表示的数据库中的列名${ }
内传入一段SQL语句片段,例如:${ORDER BY p.price}
<select id="findAllProducts" parameterType="map" resultMap="mp1">
SELECT p.`product_id`,p.`name`,p.`product_type_id`,p.`price`,p.`description`
FROM products p
ORDER BY ${colName}
select>
根元素
mapper
下子元素insert
、select
、delete
、update
均可调用存储过程通过子元素
insert
、select
、delete
、update
的statementType
属性指明SQL语句的类型
statementType
属性值有:CALLABLE
、PREPARED
、STATEMENT
statementType
属性默认属性值为:PREPARED
CALLABLE
对应jdbcCallableStatement
语句对象类型,表示SQL语句为存储过程调用PREPARED
对应jdbcPreparedStatement
语句对象类型,表示SQL语句为预编译语句STATEMENT
对应jdbcStatement
语句对象类型,表示SQL语句MySQL
中存储过程的创建和使用
DELIMITER //
指明存储过程的结束符为//
DELIMITER ;
恢复为SQL语句的结束符为;
DELIMITER
用以声明当前语句的结束符BEGIN
表示存储过程的开始,END
表示存储过程的结束OUT
表示传出数据IN
表示传入数据INOUT
表示既传出也传入数据CALL
表示调用存储过程DELIMITER //
create procedure pr_get_prd_info(p_prd_id Int,OUT p_prd_name varchar(30),OUT p_type_id int,OUT p_desc varchar(50),OUT p_price Float)
BEGIN
select product_type_id,name,description,price
into p_type_id,p_prd_name,p_desc,p_price
from products p
where product_id=p_prd_id;
END
//
DELIMITER ;
CALL pr_get_prd_info(···)
void
Map
集合
mode
属性指明传递模式,jdbcType
指明jdbc
类型
mode
属性传递模式的属性值有:
OUT
表示传出数据IN
表示传入数据INOUT
表示既传出也传入数据<select id="findInfoByProcedure" parameterType="map" statementType="CALLABLE">
CALL pr_get_prd_info(#{prdId},
#{prdName,mode=OUT,jdbcType=VARCHAR},
#{typeId,mode=OUT,jdbcType=INTEGER},
#{desc,mode=OUT,jdbcType=VARCHAR},
#{price,mode=OUT,jdbcType=FLOAT})
select>
注意:
存储过程调用之前需确认是否授权
可在MySQL中授权
也可在SQLyog中的用户管理
->对象级别特权
中选择EXECUTE
、CREATE ROUTINE
、ALTER ROUTINE