官网:MyBatis中文网
MyBatis核心配置文件(mybatis-config.xml)
environments:配置数据库连接环境信息,可以配置多个environment,通过default属性切换不同的(指向id) development:测试环境 test:开发环境
起别名:
给包中所有实体类起了别名,别名默认情况下是类名不区分大小写,也可以不用带包的名称了
<typeAliases>
<package name="pojo"/>
</typeAliases>
使用:
<select id="selectAll" resultType="user">
细节:配置各个标签时,需要遵先后顺序(官网)
- configuration(配置)
- properties(属性)
- settings(设置)
- typeAliases(类型别名)
- typeHandlers(类型处理器)
- objectFactory(对象工厂)
- plugins(插件)
- environments(环境配置)
- environment(环境变量)
- transactionManager(事务管理器)
- dataSource(数据源)
- environment(环境变量)
- databaseIdProvider(数据库厂商标识)
- mappers(映射器)
MyBatis案例
1.查询
1.查询所有数据
数据库表的字段名称和实体类的属性名称不一样,则不能自动封装数据
解决方法:1.在sql语句里起别名(as),对不一样的列名起别名,让别名和实体类的属性名一样 2.sql片段 不需要每次都起别名了,但还是不太灵活 <sql></sql>
<sql id="brand_column">
id,brand_name as brandName,company_name as companyName,orderd,description,status
</sql>
<select id="selectAll" resultType="pojo.Brand">
select
<include refid="brand_column"></include>
from tb_brand;
</select>
3.resultMap做映射(id完成主键字段的映射,result完成一般字段的映射)
<!--
id:唯一标识
type:映射的类型,类的绝对路径/起别名
-->
<resultMap id="brandResultMap" type="pojo.Brand">
<!--
id:完成主键字段的映射
result:完成一般字段的映射
column:表的别名
property:实体类的属性名
-->
<result column="brand_name" property="brandName"/>
<result column="company_name" property="companyName"/>
</resultMap>
<select id="selectAll" resultMap="brandResultMap">
select
*
from tb_brand;
</select>
2.查看详情
参数占位符
1.#{}:会将其替换为? 放止sql注入
2.${}:拼sql,会存在sql注入问题
使用时机:正常参数传递的时候#{} 表名或列名不固定的情况下:${}(少用,会存在sql注入问题)
特殊字符的处理:1.转义字符 eg:< < 2.CDATA区:一个区域中可以任意输入字符型文本
<![CDTAT[ 内容 ]]>
3.条件查询
多条件查询
条件表达式(精准查询= 条件查询like) 如何连接
<select id="selectByCondition" resultMap="brandResultMap">
select *
from tb_brand
where status=#{status}
and company_name like #{companyName}
and brand_name like #{brandName}
</select>
1.散装参数 如果方法中有多个参数,需要使用@Param("SQL参数占位符名称")
List<Brand> selectByCondition(@Param("status")int status,@Param("companyName")String companyName, @Param("brandName")String brandName);
//接收参数
int status=1;
String companyName="华为";
String brandName="华为";
//处理参数
companyName="%"+companyName+"%";
brandName="%"+companyName+"%";
List<Brand> brands = brandMapper.selectByCondition(status, companyName, brandName);
System.out.println(brands);
2.对象参数 对象的属性名称要和参数占位符名称一致
List<Brand> selectByCondition(Brand brand);
//接收参数
int status=1;
String companyName="华为";
String brandName="华为";
//处理参数
companyName="%"+companyName+"%";
brandName="%"+companyName+"%";
//封装对象
Brand brand = new Brand();
brand.setStatus(status);
brand.setCompanyName(companyName);
brand.setBrandName(brandName);
List<Brand> brands = brandMapper.selectByCondition(brand);
System.out.println(brands);
3.map集合参数 sql中的参数名和map集合的键的名称对应
List<Brand> selectByCondition(Map map);
//接收参数
int status=1;
String companyName="华为";
String brandName="华为";
//处理参数
companyName="%"+companyName+"%";
brandName="%"+companyName+"%";
//封装对象
Map map = new HashMap();
map.put("status",status);
map.put("companyName",companyName);
map.put("brandName",brandName);
多条件动态条件查询(如果用户只想判断三个条件中的一个或两个)
1.<if>标签
问题:.第一个为空时,sql语句为 and status,不符合sql语法
1.在前面加where 1=1,这样就变成了1 and status
where 1=1
<if test="status!=null">
status=#{status}
</if>
<if test="companyName!=null and companyName!=''">
and company_name like #{companyName}
</if>
2.加<where>标签
<where>
<if test="status!=null">
status=#{status}
</if>
<if test="companyName!=null and companyName!=''">
and company_name like #{companyName}
</if>
</where>
单条件动态查询(从多个条件中选择一个条件从中查询)
choose(when,otherwise) 选择:类似于java中的switch语句
<select id="selectByConditionSingle" resultType="pojo.Brand">
select *
from tb_brand
where
<choose>
<when test="status !=null">
status=#{status}
</when>
<when test="companyName !=null and companyName!=''">
company_name like #{companyName}
</when>
<when test="brandName !=null and brandName !=''">
brand_name like #{brandName}
</when>
<otherwise>
where 1=1
</otherwise>
</choose>
</select>
2.添加
默认开启事务提交,idea执行后数据库中查不到,需要自己手动提交或者开启自动提交
手动提交
//4.执行方法
brandMapper.add(brand);
//提交事务
sqlSession.commit();
自动提交(关闭事务)
SqlSession sqlSession = sqlSessionFactory.openSession(true);
<insert id="add">
insert into tb_brand(brand_name, company_name, ordered, description, status)
values (#{brandName},#{companyName},#{ordered},#{description},#{status});
</insert>
主键返回
数据添加成功后,需要获取插入数据库数据的主键的值
eg:添加订单和订单项
1.添加订单 2.添加订单项,订单项中需要设置所属订单的id
(一个用户可以下多个订单,一个订单可以包含一个或多个订单项,一个订单项可以对应一个或多个商品)
<insert id="add" useGeneratedKeys="true" keyProperty="id">
//useGeneratedKeys默认为false,keyProperty为指向主键的名称
3.修改
1.修改全部字段
<update id="update">
update tb_brand
set brand_name = #{brandName},
company_name = #{companyName},
ordered = #{ordered},
description = #{description},
status = #{status}
where id=#{id};
</update>
2.修改动态字段(只修改某几个数据)
加上<if>判断
用<set>标签规避问题
<update id="update">
update tb_brand
<set>
<if test="brandName!=null and brandName !=''">
brand_name = #{brandName},
</if>
<if test="companyName !=null and companyName !=''">
company_name = #{companyName},
</if>
<if test="ordered !=null">
ordered = #{ordered},
</if>
<if test="description !=null and description !=''">
description = #{description},
</if>
<if test="status !=null">
status = #{status}
</if>
</set>
where id=#{id};
</update>
4.删除
1.删除一个
<delete id="deleteById">
delete
from tb_brand
where id=#{id};
</delete>
2.删除多个
void deleteByIds(@Param("ids") int []ids);
<!--
mybatis会将数组参数,封装为一个Map集合
默认: array =任何数组名
可以使用@Param注解改变map集合的默认key的名称
-->
<!-- separator设定分隔符为 -->
<!-- open="(" close=")" open左边给拼个啥,close右边给拼个啥-->
<delete id="deleteByIds">
delete
from tb_brand
where id
in (
<foreach collection="ids" item="id" separator="," open="(" close=")">
#{id}
</foreach>
);
</delete>
MyBatis参数传递
pojo类型,Map集合:直接使用
Collection,List,Array,多个参数:用@Param注解,替换键名
MyBatis注解开发
比配置文件开发更加方便
注解:查询 @Select 添加 @Insert 修改 @Update 删除 @Delete
提示:注解完成简单的功能,配置文件完成复杂的功能
@Select("select * from tb_user where id=#{id}")
public User selectById(int id);