`
dwj147258
  • 浏览: 195895 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

Mybatis用法心得

阅读更多

随着互联网企业的发展,现在越来越多的企业选择用Mybatis而不是Hibernate,那是因为Mybatis能够通过自定义sql来优化查询,而全映射的Hibernate的性能在高并发,高关联的数据库查询中堪忧,但是用Mybatis最大的烦恼就是写一些非常基础的查询更新语句以及创建xml 了,这里说一下心得‘

 

一、通过Mybatis-Generator自动生成Dao,Model、Mapping相关文件

 

这个工具使Mybatis的一个插件就是为了解决频繁写文件和Mapper的问题,他有一个配置文件,配置文件的详细讲解   这里提供一个通过java来生成的文件的代码

 

public class PaginationPlugin extends PluginAdapter {

	/**
	 * Validate boolean.
	 *
	 * @param warnings the warnings
	 *
	 * @return the boolean
	 */
	@Override
	public boolean validate(List<String> warnings) {
		return true;
	}

	private static void generate() {
		String config = PaginationPlugin.class.getClassLoader().getResource("generator/generatorConfig-B.xml").getFile();
		String[] arg = {"-configfile", config, "-overwrite"};
		ShellRunner.main(arg);
	}

	/**
	 * The entry point of application.
	 *
	 * @param args the input arguments
	 */
	public static void main(String[] args) {
		generate();
	}
}

 这里的generatorConfig-B.xml即是generator的配置文件

 

二、使用Mapper接口

Mybatis有一个泛型接口Mapper<T> ,跟踪它的源码可以发现,它继承了BaseSelectMapper<T> , BaseInsertMapper<T>,BaseUpdateMapper<T>,BaseDeleteMapper<T>,他们都有各自的实现,这里提供一个解决方案

 

首先:写一个自己的接口,包括基本的数据库操作,如下

public interface IService<T> {
	/**
	 * 根据实体中的属性值进行查询, 查询条件使用等号  @param record the record
	 *
	 * @param record the record
	 *
	 * @return the list
	 */
	List<T> select(T record);

	/**
	 * 根据主键字段进行查询, 方法参数必须包含完整的主键属性, 查询条件使用等号  @param key the key
	 *
	 * @param key the key
	 *
	 * @return the t
	 */
	T selectByKey(Object key);

	/**
	 * 查询全部结果, select(null)方法能达到同样的效果  @return the list
	 *
	 * @return the list
	 */
	List<T> selectAll();

	/**
	 * 根据实体中的属性进行查询, 只能有一个返回值, 有多个结果是抛出异常, 查询条件使用等号  @param record the record
	 *
	 * @param record the record
	 *
	 * @return the t
	 */
	T selectOne(T record);

	/**
	 * 根据实体中的属性查询总数, 查询条件使用等号  @param record the record
	 *
	 * @param record the record
	 *
	 * @return the int
	 */
	int selectCount(T record);

	/**
	 * 保存一个实体, null的属性不会保存, 会使用数据库默认值  @param record the record
	 *
	 * @param record the record
	 *
	 * @return the int
	 */
	int save(T record);

	/**
	 * 批量保存  @param list the list
	 *
	 * @param list the list
	 *
	 * @return the int
	 */
	@Transactional(rollbackFor = Exception.class)
	int batchSave(List<T> list);

	/**
	 * 根据主键更新属性不为null的值  @param entity the entity
	 *
	 * @param entity the entity
	 *
	 * @return the int
	 */
	int update(T entity);

	/**
	 * 根据实体属性作为条件进行删除, 查询条件使用等号  @param record the record
	 *
	 * @param record the record
	 *
	 * @return the int
	 */
	int delete(T record);

	/**
	 * 批量删除  @param list the list
	 *
	 * @param list the list
	 *
	 * @return the int
	 */
	@Transactional(rollbackFor = Exception.class)
	int batchDelete(List<T> list);

	/**
	 * 根据主键字段进行删除, 方法参数必须包含完整的主键属性  @param key the key
	 *
	 * @param key the key
	 *
	 * @return the int
	 */
	int deleteByKey(Object key);

	/**
	 * 这个查询支持通过Example类指定查询列, 通过selectProperties方法指定查询列  @param example the example
	 *
	 * @param example the example
	 *
	 * @return the list
	 */
	List<T> selectByExample(Object example);

	/**
	 * 根据Example条件进行查询总数  @param example the example
	 *
	 * @param example the example
	 *
	 * @return the int
	 */
	int selectCountByExample(Object example);

	/**
	 * 根据Example条件更新实体record包含的不是null的属性值  @param record the record
	 *
	 * @param record  the record
	 * @param example the example
	 *
	 * @return the int
	 */
	int updateByExample(@Param("record") T record, @Param("example") Object example);

	/**
	 * 根据Example条件删除数据  @param example the example
	 *
	 * @param example the example
	 *
	 * @return the int
	 */
	int deleteByExample(Object example);

	/**
	 * 根据实体属性和RowBounds进行分页查询  @param record the record
	 *
	 * @param record    the record
	 * @param rowBounds the row bounds
	 *
	 * @return the list
	 */
	List<T> selectByRowBounds(T record, RowBounds rowBounds);

	/**
	 * 根据example条件和RowBounds进行分页查询  @param example the example
	 *
	 * @param example   the example
	 * @param rowBounds the row bounds
	 *
	 * @return the list
	 */
	List<T> selectByExampleAndRowBounds(Object example, RowBounds rowBounds);

}

 然后写一个接口的实现抽象类

public abstract class BaseService<T> implements IService<T> {

	/**
	 * The Logger.
	 */
	protected final Logger logger = LoggerFactory.getLogger(this.getClass());

	/**
	 * The Mapper.
	 */
	@Autowired
	protected Mapper<T> mapper;

	/**
	 * Gets mapper.
	 *
	 * @return the mapper
	 */
	public Mapper<T> getMapper() {
		return mapper;
	}

	/**
	 * Select list.
	 *
	 * @param record the record
	 *
	 * @return the list
	 */
	@Override
	public List<T> select(T record) {
		return mapper.select(record);
	}

	/**
	 * Select by key t.
	 *
	 * @param key the key
	 *
	 * @return the t
	 */
	@Override
	public T selectByKey(Object key) {
		return mapper.selectByPrimaryKey(key);
	}

	/**
	 * Select all list.
	 *
	 * @return the list
	 */
	@Override
	public List<T> selectAll() {
		return mapper.selectAll();
	}

	/**
	 * Select one t.
	 *
	 * @param record the record
	 *
	 * @return the t
	 */
	@Override
	public T selectOne(T record) {
		return mapper.selectOne(record);
	}

	/**
	 * Select count int.
	 *
	 * @param record the record
	 *
	 * @return the int
	 */
	@Override
	public int selectCount(T record) {
		return mapper.selectCount(record);
	}

	/**
	 * Select by example list.
	 *
	 * @param example the example
	 *
	 * @return the list
	 */
	@Override
	public List<T> selectByExample(Object example) {
		return mapper.selectByExample(example);
	}

	/**
	 * Save int.
	 *
	 * @param record the record
	 *
	 * @return the int
	 */
	@Override
	public int save(T record) {
		return mapper.insertSelective(record);
	}

	/**
	 * Batch save int.
	 *
	 * @param list the list
	 *
	 * @return the int
	 */
	@Override
	public int batchSave(List<T> list) {
		int result = 0;
		for (T record : list) {
			int count = mapper.insertSelective(record);
			result += count;
		}
		return result;
	}

	/**
	 * Update int.
	 *
	 * @param entity the entity
	 *
	 * @return the int
	 */
	@Override
	public int update(T entity) {
		return mapper.updateByPrimaryKeySelective(entity);
	}

	/**
	 * Delete int.
	 *
	 * @param record the record
	 *
	 * @return the int
	 */
	@Override
	public int delete(T record) {
		return mapper.delete(record);
	}

	/**
	 * Delete by key int.
	 *
	 * @param key the key
	 *
	 * @return the int
	 */
	@Override
	public int deleteByKey(Object key) {
		return mapper.deleteByPrimaryKey(key);
	}

	/**
	 * Batch delete int.
	 *
	 * @param list the list
	 *
	 * @return the int
	 */
	@Override
	public int batchDelete(List<T> list) {
		int result = 0;
		for (T record : list) {
			int count = mapper.delete(record);
			if (count < 1) {
				logger.error("删除数据失败");
				throw new BusinessException("删除数据失败!");
			}
			result += count;
		}
		return result;
	}

	/**
	 * Select count by example int.
	 *
	 * @param example the example
	 *
	 * @return the int
	 */
	@Override
	public int selectCountByExample(Object example) {
		return mapper.selectCountByExample(example);
	}

	/**
	 * Update by example int.
	 *
	 * @param record  the record
	 * @param example the example
	 *
	 * @return the int
	 */
	@Override
	public int updateByExample(T record, Object example) {
		return mapper.updateByExampleSelective(record, example);
	}

	/**
	 * Delete by example int.
	 *
	 * @param example the example
	 *
	 * @return the int
	 */
	@Override
	public int deleteByExample(Object example) {
		return mapper.deleteByPrimaryKey(example);
	}

	/**
	 * Select by row bounds list.
	 *
	 * @param record    the record
	 * @param rowBounds the row bounds
	 *
	 * @return the list
	 */
	@Override
	public List<T> selectByRowBounds(T record, RowBounds rowBounds) {
		return mapper.selectByRowBounds(record, rowBounds);
	}

	/**
	 * Select by example and row bounds list.
	 *
	 * @param example   the example
	 * @param rowBounds the row bounds
	 *
	 * @return the list
	 */
	@Override
	public List<T> selectByExampleAndRowBounds(Object example, RowBounds rowBounds) {
		return mapper.selectByExampleAndRowBounds(example, rowBounds);
	}

	protected long generateId() {
		return UniqueIdGenerator.getInstance(IncrementIdGenerator.getServiceId()).nextId();
	}
}

 这里有个@Autowired修饰的Mapper<T> ,在继承该抽象类的bean初始化后,它会把Mybatis的Mapper注入进来,这样就可以不用在Mapper的xml中写一些基本的sql语句而可以使用这些基本的查询更新修改以及删除的操作。

 

三、结合以上可以使用@Mapper注解来去除xml文件

 

四、使用插件也就是Mybatis拦截器

 

在初始化SqlSessionFactoryBean的时候,可以添加分页插件

 

@Bean
	public SqlSessionFactory sqlSessionFactory() throws Exception {
		SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
		sessionFactory.setDataSource(dataSource());
		sessionFactory.setFailFast(true);

		sessionFactory.setTypeAliasesPackage("com.wufumall.example.b.model");
		
		// 分页插件,插件无非是设置mybatis的拦截器
		PageHelper pageHelper = new PageHelper();
		Properties properties = new Properties();
		properties.setProperty("reasonable", "true");
		properties.setProperty("supportMethodsArguments", "true");
		properties.setProperty("returnPageInfo", "check");
		properties.setProperty("params", "count=countSql");
		pageHelper.setProperties(properties);
		sessionFactory.setPlugins(new Interceptor[] { pageHelper });
		// sessionFactory.setMapperLocations(new
		// PathMatchingResourcePatternResolver().getResources("classpath*:com/wufumall/**/*Mapper.xml"));
		sessionFactory
				.setMapperLocations(new PathMatchingResourcePatternResolver().getResources("classpath:mapping/*.xml"));
		sessionFactory.setConfigLocation(new ClassPathResource("mybatis-config.xml"));
		return sessionFactory.getObject();
	}

 

continue...

 

 

分享到:
评论

相关推荐

    MyBatis基本使用总结

    为了实现接口方法与映射文件中定义的SQL的关联,MyBatis使用了动态代理机制。在运行时,MyBatis会为每个Mapper接口生成一个实现了该接口的代理类,当调用接口方法时,实际上执行的是代理类中的方法,这个方法会解析...

    mybatis框架

    当调用`SqlSession`的增删改查方法时,MyBatis会根据传入的参数动态构建SQL语句,并使用`PreparedStatement`来执行SQL语句。 ##### 4. 结果集映射 执行完SQL语句后,MyBatis会将结果集映射成Java对象。这个过程主要...

    关于Mybatis使用原生接口开发的心得以及示例代码.docx

    在使用 MyBatis 的原生接口开发时,虽然相对于其他高级封装如 MyBatis-Plus 或者 Spring Data JPA,可能会显得较为繁琐,但其核心优势在于灵活度和控制力度。下面将详细阐述 MyBatis 原生接口开发的关键步骤和注意...

    mybatis学习总结:annotation与xml结合示例

    本篇文章将聚焦于MyBatis中的注解(Annotation)与XML配置的结合使用,旨在帮助开发者更深入地理解这一关键特性。 首先,MyBatis允许我们使用注解来简化Mapper接口的定义,无需编写XML映射文件。例如,我们可以在...

    mybatis详细介绍,特点,特性,用途,使用方法,学习方法文档

    ### 使用方法详解 1. **配置数据源**:首先需要在配置文件中设置数据库连接信息,包括 URL、用户名、密码等。 2. **编写 SQL 映射文件**:通过 XML 文件或 Java 注解定义 SQL 语句及其参数映射规则。 3. **定义...

    有用的东西 mybatis

    在描述中提到的博客链接(由于实际无法访问,这里仅做理论性分析),可能讲解了作者使用MyBatis的心得体会,可能包括最佳实践、常见问题及其解决方案。 标签中的“源码”意味着可能涉及到MyBatis的源代码解析,理解...

    Java EE企业级应用开发教程(Spring+Spring MVC+MyBatis)所有实验及实验报告.zip

    本教程专注于使用Spring、Spring MVC和MyBatis这三个关键组件进行实战教学。这三者构成了Java EE开发中的重要支柱,为开发者提供了强大的功能和灵活性。 Spring框架是Java EE开发的核心,它是一个全功能的容器,...

    mybatis.rar

    MyBatis 是一款优秀的持久层框架,它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和...记得在学习过程中多做笔记,记录下自己的练习和心得,这将有助于巩固和深化对 MyBatis 的理解。

    Mybatis学习笔记

    关于`mybatis_basic_test`这个文件,通常这可能包含了一些基本的测试用例或者示例代码,用于展示Mybatis的基本使用方法,例如: 1. **SqlSessionFactory和SqlSession**:这两个是Mybatis的主要入口,...

    毕设-期末作业-基于SpringBoot+MyBatis前后端开发的博客网站.zip

    REST(Representational State Transfer)是一种网络应用程序的设计风格和开发方式,基于HTTP协议,通过URI来定位资源,使用标准的HTTP方法(GET、POST、PUT、DELETE等)来操作资源。在本项目中,Spring Boot提供的...

    从零搭建Spring Boot脚手架,手写Mybatis通用Mapper.docx

    虽然Spring Data JDBC本身支持Mybatis,但在整合过程中需要遵守诸多规则,例如Mybatis上下文的参数管理、接口命名规范等,增加了学习和使用的难度。因此,我决定尝试独立实现一种简单的通用Mapper方案。 **一些尝试...

    Springboot配置文件心得体会

    在本文档中,作者从标题“Springboot配置文件心得体会”出发,重点探讨了Spring Boot项目中application.properties配置文件的使用方法及其重要性。针对MyBatis的整合,MVC页面模板的配置以及项目数据库、访问端口等...

    得到某个数据库的详细数据表结构

    一次性生成某个数据库的...最主要是不需要每次有结构变动都要人工编辑相应的数据库结构文档,为程序开发人员提供一点偷懒的方法。 &lt;br/&gt;使用心得: 在数据表设计时,为每个表加上表描述,为每个字段加上说明

    spring使用心得 java ssh

    SSH(Spring、Struts、Hibernate)是Java Web开发的经典组合,这个压缩包中包含了一些关于Spring在实际使用过程中的心得和常见问题的解决方案。 首先,"spring的事务代理.txt"可能涉及到Spring的事务管理。Spring...

    Jfinal使用心得以及架构

    **JFinal 使用心得与架构解析** JFinal 是一个基于 Java 的轻量级 Web 开发框架,它以 MVC(Model-View-Controller)架构为基础,强调“简洁高效”的设计理念,为开发者提供了一个快速开发项目的平台。在本文中,...

    Spring学习心得(一)

    此外,Spring还支持ORM(Object-Relational Mapping)框架,如Hibernate和MyBatis,通过这些框架,开发者可以更方便地操作数据库,进行对象与关系数据的映射。 在事务管理方面,Spring提供了编程式和声明式两种事务...

    ssh框架总结_ ssm心得体会-Java文档类资源

    此外,随着技术的发展,Spring Boot和MyBatis等新型框架逐渐成为主流,了解它们与SSH框架的区别和优劣也是必要的。对于Java开发者来说,熟练掌握SSH框架能增强解决问题的能力,但也要保持对新技术的关注和学习。

    基于Mybaits映射的一点心得(分享)

    在MyBatis中,我们可以使用XML映射文件或者注解来定义这种映射关系。这里我们展示的是XML映射文件的方式。在BlocMapper.xml中,你需要定义一个查询方法,如 `getBlocWithCompany`,该方法通过`bloc`表的 `id` 查询到...

    Java的实训心得体会范文.doc

    对于不熟悉的API,需要通过查阅文档,编写和运行示例代码来逐步熟悉它们的功能和使用方法。 在编程实践中,良好的编码习惯至关重要。保持代码整洁,注意括号匹配,区分字母大小写,确保单词拼写正确,这些都是避免...

Global site tag (gtag.js) - Google Analytics