MyBatis
1.mybatis简介
MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。
2.mybatis入门
-
安装
使用Maven来构建项目,讲下面依赖代码置于pom.xml中
<dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>x.x.x</version> </dependency>
-
从xml中构建SqlSessionFactory
每个基于 MyBatis 的应用都是以一个 SqlSessionFactory 的实例为核心的。SqlSessionFactory 的实例可以通过 SqlSessionFactoryBuilder 获得。而 SqlSessionFactoryBuilder 则可以从 XML 配置文件或一个预先配置的 Configuration 实例来构建出 SqlSessionFactory 实例
String resource = "org/mybatis/example/mybatis-config.xml"; InputStream inputStream = Resources.getResourceAsStream(resource); SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
-
配置核心文件
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <environments default="development"> <environment id="development"> <transactionManager type="JDBC"/> <dataSource type="POOLED"> <property name="driver" value="${driver}"/> <property name="url" value="${url}"/> <property name="username" value="${username}"/> <property name="password" value="${password}"/> </dataSource> </environment> </environments> <mappers> <mapper resource="org/mybatis/example/BlogMapper.xml"/> </mappers> </configuration>
3.Mapper代理开发
-
开发方法
使用Mybatis开发Dao,通常有两个方法,即原始Dao开发方法和Mapper接口开发方法。mybatis在进行dao开发的时候,涉及到三姐妹,分别是SqlSessionFactoryBuilder、SqlSessionFactroy、SqlSession。
SqlSessionFactoryBuilder-->创建SqlSessionFactory-->创建-->SqlSession
-
开发过程
-
编写mybatis的配置文件SqlMapConfig.xml
-
编写mybatis的映射文件mapper.xml(主要定义了SqlSession和sql语句) 3. 编程通过配置文件创建SqlSessionFactory
-
通过SqlSessionFactory获取SqlSession 5. 通过SqlSession操作数据库(如果执行添加、更新、删除、需要调用SqlSession.commit())
-
SqlSession使用完成要关闭
-
-
-
-
开发规范
-
mapper接口的全限定名药和mapper映射文件的namespace值一致
-
mapper接口的方法参数类型要和mapper映射文件的statement的parameterType的值一致
-
mapper接口的方法返回值类型要和mapper映射文件的statement的resultType的值一致
-
-
4.resultMap完成不一致的属性名和列名的映射
-
定义<resultMap>标签
-
在<select>标签中,使用resultMap属性替换resultType属性
<resultMap id="studentResultMap" type="student"> <result column="数据库列名" property="对象类属性名"/> </resultMap>
5.mybatis 参数占位符
-
#{} : 会将其替换为 ?,为了防止SQL注入
-
¥{}:拼sql。会存在Sql注入的问题
-
参数传递时:使用#{}
6.Sql语句中特殊字符处理
1. 转义字符 如(< 用<代替)
-
<!CDATA[内容]>
7. 条件查询
mapper.xml
<select id="selectByCondition" resultMap="brandResultMap"> select * from tb_brand where status=#{status} and company_name like #{companyName} and brand_name like #{brandName}; </select>-->
mapper接口方法
//1.散装参数 List<Brand> selectByCondition(@Param("status") int status,@Param("companyName") String companyName,@Param("brandName") String brandName); //2.对象参数 List<Brand> selectByCondition(Brand brand); //3.map集合参数 List<Brand> selectByCondition(Map map);
-
散装参数
如果方法中有多个参数,需要使用@Param("sql语句中的参数占位符")
-
对象参数
对象属性名和参数参数占位名一致
-
map参数
键的名称和占位符的名称一致
测试main()方法
条件查询1 散装参数 int status=1; String companyName="小米"; String brandName="小米"; companyName="%"+companyName+"%"; brandName="%"+brandName+"%"; List<Brand> list1 = mapper.selectByCondition(status, companyName, brandName); //对象参数 Brand brand1 = new Brand(); brand1.setStatus(status); brand1.setBrandName(brandName); brand1.setCompanyName(companyName); List<Brand> list1 = mapper.selectByCondition(brand1); //map参数 Map map = new HashMap(); map.put("status",status); map.put("companyName",companyName); map.put("brandName",brandName); List<Brand> list1 = mapper.selectByCondition(map);
8.动态条件查询
提供<if>标签判断语句
<if>条件判断
test:逻辑表达式
存在的问题:第一个条件不需要逻辑运算符
解决问题的方法:
+ 恒等式:在where 后加上1=1 用于接上后面的 and + <where>标签替换where关键字
<!--动态条件查询--> <select id="selectByCondition" resultMap="brandResultMap"> select * from tb_brand where 1=1 <if test="status !=null"> and status=#{status} </if> <if test="companyName !=null and companyName != ''"> and company_name like #{companyName} </if> <if test="brandName !=null and brandName != ''"> and brand_name like #{brandName}; </if> </select>
9.单个条件动态查询
-
使用choose (when,otherwise):选择,类似于java中的switch语句
<select id="selectByConditionSingle" resultMap="brandResultMap"> 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> 1=1 </otherwise> </choose> </where> </select>
若条件为空:
+ 在otherwise中加入恒等式 + 使用<where>标签替换where
11. 添加数据
-
编写mapper.xml
使用占位符编写sql
-
自动开启事务,默认为手动提交--->sqlSession.commit()
------SqlSession sqlSession = sqlSessionFactory.openSession(true);----->设为自动提交
-
主键返回
某些时候,数据添加成功后,需要获取插入数据库数据的主键的值
-
修改mapper.xml
<insert id="add" useGeneratedKeys="true" keyProperty="主键字段">
-
12. 修改数据
-
使用<set>标签避免动态字段(或许为空)产生的问题
<update id="update"> select 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> <where> id=#{id}; </where> </set> </update>
13.删除数据
删除单个
-
定义mapper接口
void deteById(int id)
-
定义mapper.xml sql语句
<delete id="deleteById"> delete from tb_brand where id=#{id}; </delete>
删除多个
-
定义mapper接口
void deleteByIds(int[] ids)
myBatis会将参数数组参数,封装成一个map集合。集合默认:key值为 array ----><foreach>标签中collection="array"
或者: 使用@param注解改变map集合的key值----->void deleteByIds(@Param("ids")int[] ids)
-
定义mapper.xml sql语句
<delete id="deleteByIds"> delete from tb_brand where id in( <foreach collection="ids" item="id" separator=","> #{id} </foreach> ) </delete>
14.参数封装
多个参数
封装为map集合,可以使用@param注解,替换集合中默认的arg键名
多个参数,每个参数会有两个key对应
map.put("arg0",参数1);map.put("param1",参数1);map.put("arg1",参数2);map.put("param2",参数2);
-------------------------------------使用(@param("username")String 参数1)
map.put("username",参数1);map.put("param1",参数1);map.put("arg1",参数2);map.put("param2",参数2);
单个参数
-
对象类型:直接使用->属性名 和 参数占位符名称 一致
-
Map集合:直接使用->键名 和 参数占位符名称 一致
-
Collection:封装成Map集合
map.put("arg0",collection集合);
map.put("collection",collection集合);
-
List:封装成Map集合
map.put("arg0",list集合);
map.put("collection",list集合);
map.put("list",list集合);
-
Array:封装为Map集合
map.put("arg0",数组);
map.put("array",数组);
-
其他类型:如int String 等 直接使用