
持久层
框架
1.硬编码
2.操作繁琐
MyBatis免除了几乎所有的JDBC代码以及设置参数和获取结果集的工作
MyBatis快速入门创建表mybatisdemo数据库,创建user表,添加数据
创建模块,导入坐标
//pro.xml4.0.0 org.jihua mavendemo 1.0-SNAPSHOT 17 17 mysql mysql-connector-java 5.1.34 com.alibaba druid 1.1.12 junit junit 4.13 test org.mybatis mybatis 3.5.5 org.slf4j slf4j-api 1.7.20 ch.qos.logback logback-classic 1.2.3 ch.qos.logback logback-core 1.2.3
编写MyBatis核心配置文件---->替换连接信息解决硬编码问题
//mybatis-config.xml
编写SQL映射文件---->统一管理sql语句,解决硬编码问题
//UserMapper.xmlselect * from tb_user
编码
(1) 定义POJO类
//User类
package com.jihua.pojo;
public class User {
private Integer id;
private String username;
private String password;
private String gender;
private String addr;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + ''' +
", password='" + password + ''' +
", gender='" + gender + ''' +
", addr='" + addr + ''' +
'}';
}
}
(2) main方法内
//mybatisDemo类
package com.demo;
import com.jihua.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.util.List;
public class mybatisDemo {
public static void main(String[] args) throws Exception {
//1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 执行sql
List users = sqlSession.selectList("demo.selectAll");
System.out.println(users);
//4. 释放资源
sqlSession.close();
}
}
目的
使用Mapper 代理方式完成入门案例
定义与SQL映射文件同名的Mapper接口,并且将Mapper接口和SQL映射文件放置
同—目录下
新建UserMapper接口,放在src/main/java/com/jihua/Mapper下
将UserMapper.xml文件放在src/main/resources/com/jihua/Mapper下
- 注意:在resources目录下创建多级目录不能用.,要用/,例如创建包时可以使用com.jihua.Mapper,但是resources目录只能使用com/jihua/Mapper
设置SQL映射文件的namespace属性为Mapper接口全限定名
//UserMapper.xml
在 Mapper接口中定义方法,方法名就是SQL映射文件中sql语句的id,并保持参数类型和返回值类型一致
//UserMapper接口
package com.jihua.Mapper;
import com.jihua.pojo.User;
import java.util.List;
public interface UserMapper {
List selectAll();
}
main方法中
//mybatisDemo类
package com.demo;
import com.jihua.Mapper.UserMapper;
import com.jihua.pojo.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import java.io.InputStream;
import java.util.List;
public class mybatisDemo {
public static void main(String[] args) throws Exception {
//1.加载mybatis的核心配置文件,获取SqlSessionFactory
String resource = "mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
//2.获取SqlSession对象,用它来执行sql
SqlSession sqlSession = sqlSessionFactory.openSession();
//3. 执行sql
//3.1 通过SqlSession的getMapper方法获取Mapper接口的代理对象
UserMapper UserMapper = sqlSession.getMapper(UserMapper.class);
//3.2 调用对应方法完成sql的执行
List users = UserMapper.selectAll();
System.out.println(users);
//4. 释放资源
sqlSession.close();
}
}
细节:如果Mapper接口名称和SQL映射文件名称相同,并在同一目录下,则可以使用包扫描的方式简化SQL映射文件的加载
//mybatis-config.xml文件下的mappers修改为MyBatis核心配置文件
MyBatis核心配置文件的顶层结构如下:.
类型别名(typeAliases)
细节:配置各个标签时,需要遵守前后顺序
配置文件完成增删改查数据库表的字段名称和实体类的属性名称不一样,则不能自动封装数据
起别名:对不一样的列名起别名,让别名和实体类的属性名一样
缺点:每次查询都要定义一次别名
select id, use_name as useName from tb_use;
sql片段
缺点:不灵活
id, use_name as neme select from tb_user;
resultMap
1.定义标签
2.在标签中,使用resultMap属性替换resultType属性
resultMap属性:
resultMap内部:
id:完成主键字段的映射
result:完成一般字段的映射
参数占位符:
参数类型: parameterType:可以省略
使用方法:
//4.执行方法 User user = userMapper.selectById(id); system.out.println(user);
同时接口里应该有方法:
User selectById(int id);
特殊字符处理:
转义字符:例如<表示<
CDATA区:IDEA中敲CD直接回车
sql语句:
参数接收
散装参数:
如果方法中有多个参数,需要使用@Param( “SQL参数占位符名称”)
ListselectByCondition(@Param("status") int status, @Param("companyName") String companyName, @Param("brandName") String brandName);
对象参数:
接收前端传入的数据后,封装为一个对象,其中对象的属性名称要和参数占位符名称一致
ListselectByCondition(Brand brand);
map集合参数:
接收前端传入的数据后,封装为一个map集合,其中键的名称要和参数占位符名称一致
ListselectByCondition(Map map) ;
当用户查询时并没有用到所有条件限制时,要采用动态SQL
SQL语句会随着用户的输入或外部条件的变化而变化,我们称为动态SQL
MyBatis 对动态SQL有很强大的支撑:
上面的代码如果第一个参数也没有传入,会导致拼接的sql语法错误
解决方法:
恒等式
添加一个1=1条件
替换where关键字
mybatis自带的条件处理
从多个条件中选择一个
choose (when, otherwise):选择,类似于Java中的switch语句
MyBatis事务:
在获取sqlSession对象时
//2.获取SqlSession对象,用它来执行sql SqlSession sqlSession = sqlSessionFactory.openSession();
openSession():默认开启事务,进行增删改操作后需要使用sqlSession.commit();手动提交事务
openSession(true):可以设置为自动提交事务(关闭事务)
在数据添加成功后,需要获取插入数据库数据的主键的值
只需要添加两个属性:
useGeneratedKeys:开启主键返回
keyProperty:指向对应主键名称
修改insert into tb_order (payment,paymlent_type,status) values (#{payment},#{paymentType},#{status});
:
使用set标签处理参数个数导致的sql语法问题
删除update tb_brand where id = #{id}; brand_name = #{brandName}, company_name = #{companyName}, ordered = #{ordered}, description = #{description}, status = #{status},
delete from tb_brand where id =#{id}; delete>
批量删除
传入一个id的数组
delete from tb_brandwhere id in (?,?,?)
mybatis会将数组参数,封装为一个Map集合
默认::array =数组
或者:使用@Param注解改变map集合的默认key的名称
//定义接口方法时
void deleteByIds (@Param("ids") int[] ids);
in(?, ?, ?)中具体有多少个?,需要遍历数组,需要使用标签
delete from tb_brand where id in #{id}
separator属性表示自动添加分隔符,open和close属性会加在开始和结束的位置
MyBatis 接口方法中可以接收各种各样的参数,MyBatis底层对于这些参数进行不同的封装处理方式
MyBatis参数封装:
MyBatis提供了ParamNameResolver类来进行参数封装
POJO(数据结构)类型:直接使用,属性名和参数占位符名称一致
Map集合:直接使用,键名和参数占位符名称一致
Collection:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map .put( "arg0" ,list集合); map.put( "collection " ,list集合);
List:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map .put( "arg0" ,list集合); map .put( "collection " ,list集合); map.put( "list",list集合);
Array:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map. put ( " arg0",数组); map. put( " array ",数组);
多个参数:封装为Map集合,可以使用@Param注解,替换Map集合中默认的arg键名
map.put ("arg0",参数值1);
map.put("param1",参数值1);
map.put("agr1",参数值2);
map.put("param2",参数值2);
/设置@Param ( "username " )
map.put("username",参数值1);
map.put("param1",参数值1);
map.put("agr1",参数值2);
map.put("param2",参数值2);
建议:将来都使用@Param注解来修改Map集合中默认的键名,并使用修改后的名称来获取值,这样可读性更高!
注解完成增删改查使用注解开发会比配置文件开发更加方便
@Select("select * from tb_user where id = #{id}")
public User selectByld(int id);
提示:
注解完成简单功能
配置文件完成复杂功能
使用注解来映射简单语句会使代码显得更加简洁,但对于稍微复杂一点的语句,Java注解不仅力不从心,还会让你本就复杂的SOL语句更加是盟不堪。因此,如果你需要做一些很复杂的操作,最好用XML来映射语句。
选择何种方式来配置映射,以及认为是否应该要统一映射语句定义的形式,完全取决于你和你的团队。换句话说,永远不要拘况于一种方式。你可以很轻松的在基于注解和XML的涯句缺射舫j方式睚自由移植和切换。