栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

MyBatis详解

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

MyBatis详解

MyBatis 一、Mybatis概述 1.1 什么是Mybatis

  mybatis是一个优秀的基于java的持久层框架,它内部封装了jdbc,使开发者只需要关注sql语句本身,而不需要花费精力去处理加载驱动、创建连接、创建statement等繁杂的过程。

1.2 Mybatis的特点
  • 简单易学:本身就很小且简单。没有任何第三方依赖,最简单安装只要两个jar文件+配置几个sql映射文件易于学习,易于使用,通过文档和源代码,可以比较完全的掌握它的设计思路和实现。
  • 灵活:mybatis不会对应用程序或者数据库的现有设计强加任何影响。
  • sql写在xml里,便于统一管理和优化。通过sql语句可以满足操作数据库的所有需求。
  • 解除sql与程序代码的耦合:通过提供DAO层,将业务逻辑和数据访问逻辑分离,使系统的设计更清晰,更易维护,更易单元测试。sql和代码的分离,提高了可维护性。
  • 提供映射标签,支持对象与数据库的orm字段关系映射 提供对象关系映射标签,支持对象关系组建维护 提供xml标签,支持编写动态sql。
二、MyBatis快速入门 2.1 MyBatis开发步骤

①添加MyBatis的坐标

②创建user数据表

③编写User实体类

④编写映射文件UserMapper.xml

⑤编写核心文件SqlMapConfig.xml

⑥编写测试类

2.2 环境搭建

1)导入MyBatis的坐标和其他相关坐标

   

    org.mybatis
    mybatis
    3.4.5


    
    mysql   
    mysql-connector-java    
    5.1.6    
    runtime


    
    junit    
    junit    
    4.12    
    test


    
    log4j    
    log4j    
    1.2.12

2)创建user数据表
3) 编写User实体

public class User {    
	private int id;    
	private String username;    
	private String password;
    //省略get个set方法
}

4)编写UserMapper映射文件



    
	        
		select * from User    
	

5) 编写MyBatis核心文件


    
	        
		            
			            
			                
				
				                
				
				            
			        
		    
	    
	
	 
		 
	


2.3 编写测试代码
//加载核心配置文件
InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//获得sqlSession工厂对象
SqlSessionFactory sqlSessionFactory = new            
                           SqlSessionFactoryBuilder().build(resourceAsStream);
//获得sqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
//执行sql语句
List userList = sqlSession.selectList("userMapper.findAll");
//打印结果
System.out.println(userList);
//释放资源
sqlSession.close();
三、MyBatis的映射文件概述

3.1 映射文件的DTD约束头

3.2 根标签

3.3 字标签
    
    select * from User
    
        
            and id=#{id}
        
        
            and username=#{username}
        
    


 当查询条件id和username都存在时,控制台打印的sql语句如下:

     … … …
     //获得MyBatis框架生成的UserMapper接口的实现类
  UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
    User condition = new User();
    condition.setId(1);
    condition.setUsername("lucy");
    User user = userMapper.findByCondition(condition);
    … … …

  当查询条件只有id存在时,控制台打印的sql语句如下:

 … … …
 //获得MyBatis框架生成的UserMapper接口的实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
User condition = new User();
condition.setId(1);
User user = userMapper.findByCondition(condition);
… … …

3.4.2、动态SQL之

  循环执行sql的拼接操作,例如:SELECT * FROM USER WHERe id IN (1,2,5)。


    select * from User
    
        
            #{id}
        
    

  测试代码片段如下:

 … … …
 //获得MyBatis框架生成的UserMapper接口的实现类
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
int[] ids = new int[]{2,5};
List userList = userMapper.findByIds(ids);
System.out.println(userList);
… … …

标签用于遍历集合,它的属性:

•collection:代表要遍历的集合元素,注意编写时不要写#{}

•open:代表语句的开始部分

•close:代表结束部分

•item:代表遍历集合的每个元素,生成的变量名

•sperator:代表分隔符

3.5 SQL片段抽取

  Sql 中可将重复的 sql 提取出来,使用时用 include 引用即可,最终达到 sql 重用的目的




     where id=#{id}


四、MyBatis核心配置文件深入 4.1 typeHandlers标签

  无论是 MyBatis 在预处理语句(PreparedStatement)中设置一个参数时,还是从结果集中取出一个值时, 都会用类型处理器将获取的值以合适的方式转换成 Java 类型。下表描述了一些默认的类型处理器(截取部分)。

开发步骤:

①定义转换类继承类BaseTypeHandler

②覆盖4个未实现的方法,其中setNonNullParameter为java程序设置数据到数据库的回调方法,getNullableResult为查询时
mysql的字符串类型转换成 java的Type类型的方法

③在MyBatis核心配置文件中进行注册

测试转换是否正确

public class MyDateTypeHandler extends BaseTypeHandler {
    public void setNonNullParameter(PreparedStatement preparedStatement, int i, Date date, JdbcType type) {
        preparedStatement.setString(i,date.getTime()+"");
    }
    public Date getNullableResult(ResultSet resultSet, String s) throws SQLException {
        return new Date(resultSet.getLong(s));
    }
    public Date getNullableResult(ResultSet resultSet, int i) throws SQLException {
        return new Date(resultSet.getLong(i));
    }
    public Date getNullableResult(CallableStatement callableStatement, int i) throws SQLException {
        return callableStatement.getDate(i);
    }
}


    

测试添加操作:

user.setBirthday(new Date());
userMapper.add2(user);

数据库数据

测试查询操作

4.2 plugins标签

  MyBatis可以使用第三方的插件来对功能进行扩展,分页助手PageHelper是将分页的复杂操作进行封装,使用简单的方式即可获得分页的相关数据

开发步骤:

①导入通用PageHelper的坐标

②在mybatis核心配置文件中配置PageHelper插件

③测试分页数据获取

①导入通用PageHelper坐标



    com.github.pagehelper
    pagehelper
    3.7.5


    com.github.jsqlparser
    jsqlparser
    0.9.1


②在mybatis核心配置文件中配置PageHelper插件



    
    

③测试分页代码实现

@Test
public void testPageHelper(){
    //设置分页参数
    PageHelper.startPage(1,2);

    List select = userMapper2.select(null);
    for(User user : select){
        System.out.println(user);
    }
}

获得分页相关的其他参数

//其他分页的数据
PageInfo pageInfo = new PageInfo(select);
System.out.println("总条数:"+pageInfo.getTotal());
System.out.println("总页数:"+pageInfo.getPages());
System.out.println("当前页:"+pageInfo.getPageNum());
System.out.println("每页显示长度:"+pageInfo.getPageSize());
System.out.println("是否第一页:"+pageInfo.isIsFirstPage());
System.out.println("是否最后一页:"+pageInfo.isIsLastPage());

五、 Mybatis多表查询 5.1 一对一查询 5.1.1 一对一查询的模型

  用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户

  一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户

5.1.2一对一查询的语句

  对应的sql语句:select * from orders o,user u where o.uid=u.id;

查询的结果如下:

5.1.3 创建Order和User实体
public class Order {

    private int id;
    private Date ordertime;
    private double total;

    //代表当前订单从属于哪一个客户
    private User user;
}

public class User {
    
    private int id;
    private String username;
    private String password;
    private Date birthday;

}
5.1.4 创建OrderMapper接口
public interface OrderMapper {
    List findAll();
}
5.1.5 配置OrderMapper.xml

    
        
        
        
        
    
    
        select * from orders o,user u where o.uid=u.id
    

其中还可以配置如下:


    
    
    
    
        
        
        
        
    

5.1.6 测试结果
OrderMapper mapper = sqlSession.getMapper(OrderMapper.class);
List all = mapper.findAll();
for(Order order : all){
    System.out.println(order);
}

5.2 一对多查询 5.2.1 一对多查询的模型

  用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单

5.2.2 一对多查询的语句

  对应的sql语句:select *,o.id oid from user u left join orders o on u.id=o.uid;

查询的结果如下:

5.2.3 修改User实体
public class Order {

    private int id;
    private Date ordertime;
    private double total;

    //代表当前订单从属于哪一个客户
    private User user;
}

public class User {
    
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //代表当前用户具备哪些订单
    private List orderList;
}

5.2.4 创建UserMapper接口
public interface UserMapper {
    List findAll();
}
5.2.5 配置UserMapper.xml

    
        
        
        
        
        
            
            
            
        
    
    
        select *,o.id oid from user u left join orders o on u.id=o.uid
    

5.2.6 测试结果
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List all = mapper.findAll();
for(User user : all){
    System.out.println(user.getUsername());
    List orderList = user.getOrderList();
    for(Order order : orderList){
        System.out.println(order);
    }
    System.out.println("----------------------------------");
}

5.3 多对多查询 5.3.1 多对多查询模型

  用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用多对多查询的需求:查询用户同时查询出该用户的所有角色。

5.3.2 多对多查询的语句

  对应的sql语句:select u.,r.,r.id rid from user u left join user_role ur on u.id=ur.user_id inner join role r on ur.role_id=r.id;

查询的结果如下:

5.3.3创建Role实体,修改User实体
public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //代表当前用户具备哪些订单
    private List orderList;
    //代表当前用户具备哪些角色
    private List roleList;
}

public class Role {

    private int id;
    private String rolename;

}

5.3.4 添加UserMapper接口方法
List findAllUserAndRole();
5.3.5 配置UserMapper.xml

    
    
    
    
    
        
        
    


    select u.*,r.*,r.id rid from user u left join user_role ur on u.id=ur.user_id
    inner join role r on ur.role_id=r.id

5.3.6 测试结果
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List all = mapper.findAllUserAndRole();
for(User user : all){
    System.out.println(user.getUsername());
    List roleList = user.getRoleList();
    for(Role role : roleList){
        System.out.println(role);
    }
    System.out.println("----------------------------------");
}

六、Mybatis的注解开发 6.1 MyBatis的常用注解

  这几年来注解开发越来越流行,Mybatis也可以使用注解开发方式,这样我们就可以减少编写Mapper

  映射文件了。我们先围绕一些基本的CRUD来学习,再学习复杂映射多表操作。

@Insert:实现新增

@Update:实现更新

@Delete:实现删除

@Select:实现查询

@Result:实现结果集封装

@Results:可以与@Result 一起使用,封装多个结果集

@One:实现一对一结果集封装

@Many:实现一对多结果集封装

6.2 MyBatis的增删改查

我们完成简单的user表的增删改查的操作

private UserMapper userMapper;

@Before
public void before() throws IOException {
    InputStream resourceAsStream = Resources.getResourceAsStream("SqlMapConfig.xml");
    SqlSessionFactory sqlSessionFactory = new 
                 SqlSessionFactoryBuilder().build(resourceAsStream);
    SqlSession sqlSession = sqlSessionFactory.openSession(true);
    userMapper = sqlSession.getMapper(UserMapper.class);
}

@Test
public void testAdd() {
    User user = new User();
    user.setUsername("测试数据");
    user.setPassword("123");
    user.setBirthday(new Date());
    userMapper.add(user);
}
@Test
public void testUpdate() throws IOException {
    User user = new User();
    user.setId(16);
    user.setUsername("测试数据修改");
    user.setPassword("abc");
    user.setBirthday(new Date());
    userMapper.update(user);
}

@Test
public void testDelete() throws IOException {
    userMapper.delete(16);
}
@Test
public void testFindById() throws IOException {
    User user = userMapper.findById(1);
    System.out.println(user);
}
@Test
public void testFindAll() throws IOException {
    List all = userMapper.findAll();
    for(User user : all){
        System.out.println(user);
    }
}

  修改MyBatis的核心配置文件,我们使用了注解替代的映射文件,所以我们只需要加载使用了注解的Mapper接口即可


    
    

或者指定扫描包含映射关系的接口所在的包也可以


    
    

6.3 MyBatis的注解实现复杂映射开发

  实现复杂关系映射之前我们可以在映射文件中通过配置来实现,使用注解开发后,我们可以使用@Results注解,@Result注解,@One注解,@Many注解组合完成复杂关系的配置

6.4 一对一查询 6.4.1 一对一查询的模型

  用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户一对一查询的需求:查询一个订单,与此同时查询出该订单所属的用户

6.4.2 一对一查询的语句

对应的sql语句:

select * from orders;

select * from user where id=查询出订单的uid;

查询的结果如下:

6.4.3 创建Order和User实体
public class Order {

    private int id;
    private Date ordertime;
    private double total;

    //代表当前订单从属于哪一个客户
    private User user;
}

public class User {
    
    private int id;
    private String username;
    private String password;
    private Date birthday;

}
6.4.4 创建OrderMapper接口
public interface OrderMapper {
    List findAll();
}
6.4.5 使用注解配置Mapper
public interface OrderMapper {
    @Select("select * from orders")
    @Results({
            @Result(id=true,property = "id",column = "id"),
            @Result(property = "ordertime",column = "ordertime"),
            @Result(property = "total",column = "total"),
            @Result(property = "user",column = "uid",
                    javaType = User.class,
                    one = @One(select = "com.itheima.mapper.UserMapper.findById"))
    })
    List findAll();
}
public interface UserMapper {

    @Select("select * from user where id=#{id}")
    User findById(int id);
    
}
6.4.6 测试结果
@Test
public void testSelectOrderAndUser() {
    List all = orderMapper.findAll();
    for(Order order : all){
        System.out.println(order);
    }
}

6.5 一对多查询 6.5.1 一对多查询的模型

  用户表和订单表的关系为,一个用户有多个订单,一个订单只从属于一个用户一对多查询的需求:查询一个用户,与此同时查询出该用户具有的订单。

6.5.2 一对多查询的语句

对应的sql语句:

select * from user;

select * from orders where uid=查询出用户的id;

查询的结果如下:

6.5.3 修改User实体
public class Order {

    private int id;
    private Date ordertime;
    private double total;

    //代表当前订单从属于哪一个客户
    private User user;
}

public class User {
    
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //代表当前用户具备哪些订单
    private List orderList;
}
6.5.4 创建UserMapper接口
List findAllUserAndOrder();
6.5.5 使用注解配置Mapper
public interface UserMapper {
    @Select("select * from user")
    @Results({
            @Result(id = true,property = "id",column = "id"),
            @Result(property = "username",column = "username"),
            @Result(property = "password",column = "password"),
            @Result(property = "birthday",column = "birthday"),
            @Result(property = "orderList",column = "id",
                    javaType = List.class,
                    many = @Many(select = "com.itheima.mapper.OrderMapper.findByUid"))
    })
    List findAllUserAndOrder();
}

public interface OrderMapper {
    @Select("select * from orders where uid=#{uid}")
    List findByUid(int uid);

}
6.5.6 测试结果
List all = userMapper.findAllUserAndOrder();
for(User user : all){
    System.out.println(user.getUsername());
    List orderList = user.getOrderList();
    for(Order order : orderList){
        System.out.println(order);
    }
    System.out.println("-----------------------------");
}

6.6 多对多查询 6.6.1 多对多查询的模型

  用户表和角色表的关系为,一个用户有多个角色,一个角色被多个用户使用多对多查询的需求:查询用户同时查询出该用户的所有角色

6.6.2 多对多查询的语句

对应的sql语句:

select * from user;

select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=用户的id

查询的结果如下:

6.6.3 创建Role实体,修改User实体
public class User {
    private int id;
    private String username;
    private String password;
    private Date birthday;
    //代表当前用户具备哪些订单
    private List orderList;
    //代表当前用户具备哪些角色
    private List roleList;
}

public class Role {

    private int id;
    private String rolename;

}
6.6.4 添加UserMapper接口方法
List findAllUserAndRole();
6.6.5 使用注解配置Mapper
public interface UserMapper {
    @Select("select * from user")
    @Results({
        @Result(id = true,property = "id",column = "id"),
        @Result(property = "username",column = "username"),
        @Result(property = "password",column = "password"),
        @Result(property = "birthday",column = "birthday"),
        @Result(property = "roleList",column = "id",
                javaType = List.class,
                many = @Many(select = "com.itheima.mapper.RoleMapper.findByUid"))
})
List findAllUserAndRole();}



public interface RoleMapper {
    @Select("select * from role r,user_role ur where r.id=ur.role_id and ur.user_id=#{uid}")
    List findByUid(int uid);
}

6.6.6 测试结果
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
List all = mapper.findAllUserAndRole();
for(User user : all){
    System.out.println(user.getUsername());
    List roleList = user.getRoleList();
    for(Role role : roleList){
        System.out.println(role);
    }
    System.out.println("----------------------------------");
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/888557.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号