Mybatis用法心得
程序员文章站
2022-05-09 22:33:09
...
随着互联网企业的发展,现在越来越多的企业选择用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...