mybatis 进阶笔记

简单使用mybatis的增删改查

通过id查找到用户

使用的sql:

SELECT * FROM `user` WHERE id = 1

在user.xml中添加select标签,编写sql:









    

    

    

    

    

测试程序步骤:

 1. 创建SqlSessionFactoryBuilder对象

 2. 加载SqlMapConfig.xml配置文件

 3. 创建SqlSessionFactory对象

 4. 创建SqlSession对象

 5. 执行SqlSession对象执行查询,获取结果User

 6. 打印结果

 7. 释放资源

public class MybatisTest {
	private SqlSessionFactory sqlSessionFactory;

	@Before
	public void before() throws Exception {
		// 1. 创建SqlSessionFactoryBuilder对象
		SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();

		// 2. 加载SqlMapConfig.xml配置文件
		InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");

		// 3. 创建SqlSessionFactory对象
		this.sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
	}

	@Test
	public void testQueryUserById() throws Exception {
		// 4. 创建SqlSession对象
		SqlSession sqlSession = sqlSessionFactory.openSession();

		// 5. 执行SqlSession对象执行查询,获取结果User
		// 第一个参数是User.xml的statement的id,第二个参数是执行sql需要的参数;
		Object user = sqlSession.selectOne("test.queryUserById", 1);

		// 6. 打印结果
		System.out.println(user);

		// 7. 释放资源
		sqlSession.close();
	}
}

通过名字模糊查询

查询sql:

SELECT * FROM `user` WHERE username LIKE '%马%'

user.xml配置


测试

	@Test
	public void testQueryUserByUsername() throws Exception {
		// 4. 创建SqlSession对象
		SqlSession sqlSession = sqlSessionFactory.openSession();

		// 5. 执行SqlSession对象执行查询,获取结果User
		// 查询多条数据使用selectList方法
		List list = sqlSession.selectList("test.queryUserByUsername1", "马");

		// 6. 打印结果
		for (Object user : list) {
			System.out.println(user);
		}

		// 7. 释放资源
		sqlSession.close();
	}
 
  

#{}和${}

#{}表示一个占位符号,通过#{}可以实现preparedStatement向占位符中设置值,自动进行java类型和jdbc类型转换。#{}可以有效防止sql注入。 #{}可以接收简单类型值或pojo属性值。 如果parameterType传输单个简单类型值,#{}括号中可以是value或其它名称。

${}表示拼接sql串,通过${}可以将parameterType 传入的内容拼接在sql中且不进行jdbc类型转换, ${}可以接收简单类型值或pojo属性值,如果parameterType传输单个简单类型值,${}括号中只能是value

parameterType和resultType

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。

resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。如果有多条数据,则分别进行映射,并把对象放到容器List中

 

selectOne和selectList

selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常

若是增删改的操作必须提交事务

增加用户


      insert into t_user (name,sex,address,balance)
values (#{name},#{sex},#{address},#{balance})
  

-测试

@Test
public void testSaveUser() {
	// 4. 创建SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession();

	// 5. 执行SqlSession对象执行保存
	// 创建需要保存的User
	User user = new User();
	user.setName("张飞");
	user.setSex("1");
	user.setAddress("蜀国");

	sqlSession.insert("test.addUser", user);
	System.out.println(user);

	// 需要进行事务提交
	sqlSession.commit();

	// 7. 释放资源
	sqlSession.close();
}

修改用户

  
      update t_user
set name = #{name},sex = #{sex},address = #{address},balance=#{balance},companyId=#{companyId}
where id = #{id}
  

测试

@Test
public void testUpdateUserById() {
	// 4. 创建SqlSession对象
	SqlSession sqlSession = sqlSessionFactory.openSession();

	// 5. 执行SqlSession对象执行更新
	// 创建需要更新的User
	User user = new User();
	user.setId(26);
	user.setName("关羽");
	user.setSex("1");
	user.setAddress("蜀国");

	sqlSession.update("test.updateUser", user);

	// 需要进行事务提交
	sqlSession.commit();

	// 7. 释放资源
	sqlSession.close();
}

删除用户

  
      delete from t_user
where id = #{superman}
  

    测试 

	@Test
	public void testDeleteUserById() {
		// 4. 创建SqlSession对象
		SqlSession sqlSession = sqlSessionFactory.openSession();

		// 5. 执行SqlSession对象执行删除
		sqlSession.delete("test.delUser", 48);

		// 需要进行事务提交
		sqlSession.commit();

		// 7. 释放资源
		sqlSession.close();
	}

 

Mybatis 与 hibernate 区别

Mybatis和hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句。mybatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。

 

Mybatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是mybatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。

 

Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。

总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。 

原始dao层开发

sqlSessionFactoryBuilder         读取配置文件  调用build方法

SqlSessionFactory                       创建 sqlsession

Sqlsession                  封装方法(每次都打开一个新的session)

Dao依赖于sqlSessionFactory

 

private SqlSessionFactory sqlSessionFactory;
public UserDaoImpl(SqlSessionFactory sqlSessionFactory) {
    this.sqlSessionFactory = sqlSessionFactory;
}
@Override
public User selectUserById(Integer id) {
    SqlSession sqlSession = sqlSessionFactory.openSession();
    return sqlSession.selectOne("test.selectUserById",id);
}

 

代理dao     (mapper接口) 开发

前提条件

  1. 接口方法名 == User.xm 的id名
  2. 返回值类型  与(Mapper.xm) 映射文件类型返回值类型一致
  3. 方法的入参类型与 映射文件中入参数类型一致
  4. 命名空间绑定此接口(namespace值与接口相对路径名一致)

接口名字 建议与 配置文件名字保持一致

注意事项:方法中的参数就只能有一个

       Selectone 与 selectList根据,mapper的返回值类型决定

SqlMapperConfig配置文件详解

mybatis 进阶笔记_第1张图片

    配置文件属性顺序必须如上图一致

TypeAliases   别名


   
   

 

Typehandlers 类型处理器

    实现jdbc(数据库中的类型)和java类型的转换,一般不用自己去改,特殊情况下需要自己手动映射。

 Properties   设置属性

Settings   mybatis功能的设置

 

输入类型 和 输出类型

输入类型

普通类型

使用#{}占位符,或者${}进行sql拼接。

使用pojo类型

Mybatis使用ognl表达式解析对象字段的值,#{}或者${}括号中的值为pojo属性名称。

Pojo包装类  既包含普通类型也包含其他类型

包装对象:Pojo类中的一个属性是另外一个pojo。

输出类型

ResultType

自动装换(属性名 与数据库字段名一致)

ResultMap

手动转换 ,如果名字不一致则需要手动映射


    

ResultMap: type 将要转换的类型

Id:主键      property实体类的属性名  column 数据库列的字段名

result     普通属性  

 

动态sql

If标签


  AND  id =#{id}


  AND name =#{name}

Test  使用ognl表达式的方式取值,可以if条件  并且and  或者 or

 

如果有多个条件,不知道是第一个成立and的位置不好放,放在任何一个位置都有可能有异常,使用where标签解决

Where标签     (自动去除前and)

 

若所有条件都不成立,那么where标签就去除

 

Foreach标签



    #{id}

Collection 识别数据类型

       数组:array          set集合:set

      List集合:list    封装类:必须是封装类的属性名

      

      

      

Index      下标

SQL片段




       id, username, birthday, sex, address



SELECT  FROM `user`

Include refid 属性对应的就是     SQL片段的id名

多表查询

一对一

实现一对一查询的结果集封装

两种办法:

         ResultType

         新建一个实体类,这个实体类包含所有转换的列名

         可以建一个类,让这个类去继承一个类


    

 

         resultMap

         在user实体类中增加一个引用类的属性,并添加get-set方法,在结果集处理时采用

resultMap


    
    
    
        
        
    

         若字段名和属性不写转换,就不会转化,要想将查询到的结果全部封装到实体类中,就必须全部都写

一对多

ResultType(不建议使用)

         新建一个实体类,这个实体类包含所有转换的列名

         可以建一个类,让这个类去继承一个类

 

ResultMap

添加属性 并添加get-set方法


    
    
    
        
        
        
        
    

Collection    property实体类的属性名,javaType(集合list set)

ofType     封装集合中每个元素的类型

 

(以下三种技术 可了解)

缓存(Redis   memache)

延迟加载                

逆向工程

逆向工程,通过一方生成另一方

 

你可能感兴趣的:(Java)