Giter VIP home page Giter VIP logo

book's People

Contributors

abel533 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

book's Issues

第11章,SimpleTest執行時報錯

照著書上的說明寫好了SimpleTest這支程式,但在執行時出現下列的錯誤:
org.apache.ibatis.plugin.PluginException: Could not find method on interface java.util.concurrent.Executor named query. Cause: java.lang.NoSuchMethodException: java.util.concurrent.Executor.query(org.apache.ibatis.mapping.MappedStatement, java.lang.Object, org.apache.ibatis.session.RowBounds, org.apache.ibatis.session.ResultHandler)...(下略)

我很確定我程式內import的是org.apache.ibatis.executor.Executor,不知道錯誤訊息的java.util.concurrent.Executor哪來的,將範例程式整個貼上去執行也是出現一樣的錯誤

我的junit版本用的是4.12,mybatis版本是3.3.1,eclipse用的是Oxygen 2

常量枚举失效

常量枚举mybatis-config.xml 全局配置后 利用mapper insert后,发现对应的枚举字段没有插入

《MyBatis 从入门到精通》转发送书参与人员名单

参与总人数:36 人

虽然人数没达到之前设定的目标,但是会送出两本书。

抽奖代码也没有多复杂,对参与人员乱序后,抽取两位幸运的朋友。

没有中奖的朋友也没有关系,凡是参与本次活动的朋友,如果自己购买了本书,可以和我联系,我个人单独发个3块钱的红包当作参与奖,谢谢大家的参与!

抽奖时间

2017年7月6日,12点整,在斗鱼进行直播。

房间号:2451707,在线观看

直播时间 1 分钟左右。。

参与人员名单,中奖人员名字加粗显示

  • lzysuqianqiu
  • changhe626
  • nanzhang237420759
  • BruceKellan
  • usermanewhy
  • jackmanwu
  • xty805007911
  • tianranll
  • qq383264679
  • AchaoMarver
  • drtrang
  • lvtao320
  • song-song
  • raodoudou321
  • OrangesHuang
  • litttlefisher
  • arvinsir
  • iHelin
  • penelopeWu
  • anjingdemutou
  • tjj006
  • JavaerZJM
  • zhenggaojia
  • yang1018679
  • LeeAfei0
  • JoeyBling
  • ChanceZhaoquanfeng
  • wang3shi
  • LuckyWind2157
  • 1543453892
  • huangfengyi
  • EchoXml
  • luodonger
  • vanlin
  • easyfeng
  • GitHubBling

抽奖代码

import java.util.*;

/**
 * @author liuzh
 * @since 2017/7/5.
 */
public class Lottery {

    public static void main(String[] args) {
        int nums = 2;
        String[] users = new String[]{
                "test0", "test1", "test2", "test3", "test4", "test5", "test6", "test7", "test8", "test9",
                "test10", "test11", "test12", "test13", "test14", "test15", "test16", "test17", "test18", "test19",
                "test20", "test21", "test22", "test23", "test24", "test25", "test26", "test27", "test28", "test29",
                "test30", "test31", "test32", "test33", "test34", "test35", "test36", "test37", "test38", "test39",
                "test40", "test41", "test42", "test43", "test44", "test45", "test46", "test47", "test48", "test49",
        };
        lottery(users, nums);
    }

    public static void lottery(String[] users, int nums){
        List<String> userList = Arrays.asList(users);
        //乱序
        Collections.shuffle(userList);
        Random random = new Random();
        int i = 0;
        Set<Integer> set = new HashSet<>(nums);
        do {
            int nextInt = random.nextInt(userList.size());
            if(!set.contains(nextInt)){
                set.add(nextInt);
                i++;
            }
        } while (i < nums);
        System.out.println("============中奖名单============");
        for (Integer num : set) {
            System.out.println(userList.get(num));
        }
    }

}

主键回显问题

我使用数据库是MYSQL,实体类代码中的主键注解配置如下:
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;

数据库表注解如下 : id int(11) NOT NULL AUTO_INCREMENT COMMENT '编号',

在调用mapper新增方法后,偶尔会出现如下错误(机率挺高的,偶尔又能新增成功,很奇怪),日志如下:

SELECT LAST_INSERT_ID() LIMIT ?
Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml] SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana]
Error selecting key or setting result to parameter object. Cause: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '?' at line 1

关于mybatis中的二级缓存

在第七章的本章小节中,书中提到了,为了避免脏读,在任何情况中,都可以考虑在业务层中使用可控制的缓存来代替二级缓存。请问这里所谓的可控制的缓存是指通过哪些手段来控制呢?是否可以指点一二,谢谢

交流群加不上

image

加交流群的时候会显示让我输入最新的版本但是我输入了最新版本还是显示错误 请问如何才能加入交流群

我qq 1396781292

mybatis添加分页拦截器后出现的取值问题

问题代码如下:

#{item}

由于项目中用到了分页拦截器,一旦有分页的sql中,用#{}获取值都会报错( org.apache.ibatis.binding.BindingException: Parameter '__frch_item_0' not found.),换成${}这种方式就好了,请问什么原因?

SqlServer2008使用pagehelper报错

SqlServer2008数据库使用pagehelper报错:

nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.RuntimeException: 请您在sql中包含order by语句! ### The error may exist in com/free/test4/mapper/TestMapper.java (best guess) ### The error may involve com.free.test4.mapper.TestMapper.selectByExample_COUNT ### The error occurred while handling results ### SQL: SELECT count(*) FROM test ### Cause: java.lang.RuntimeException: 请您在sql中包含order by语句!

查询代码
`@RequestMapping(value = "/queryPage", method = { RequestMethod.GET })
@responsebody
public PageResultSet queryPage(Model model) {
PageHelper.startPage(1, 10);
TestModel setuser = new TestModel();
List list = service.query(setuser);
return new PageResultSet(list);

}`

用下面这种方式就不会报错,能拿到正确的结果:
`@RequestMapping(value = "/queryPage", method = { RequestMethod.GET })
@responsebody
public PageResultSet queryPage(Model model) {
PageHelper.startPage(1, 10);
Example example = new Example(BasketconfigCLssModel.class);
example.setOrderByClause("bkserialno");
return new PageResultSet( service.selectByExample(example));

}`

SQLServer2008数据库使用pagehelper报错

SQLServer2008的数据库使用pagehelper报错:
nested exception is org.apache.ibatis.exceptions.PersistenceException: ### Error querying database. Cause: java.lang.RuntimeException: 请您在sql中包含order by语句! ### The error may exist in com/free/test4/mapper/TestMapper.java (best guess) ### The error may involve com.free.test4.mapper.TestMapper.selectByExample_COUNT ### The error occurred while handling results ### SQL: SELECT count(*) FROM test ### Cause: java.lang.RuntimeException: 请您在sql中包含order by语句!
代码如下:
`@requestmapping(value =“/ queryPage”,method = {RequestMethod.GET})
@responsebody
public PageResultSet queryPage(Model model){
PageHelper.startPage(1,10);
TestModel setuser = new TestModel();
List list = service.query(setuser);
返回的的PageResultSet(列表);

}用下面这种方式就不会报错,能拿到正确的结果:@RequestMapping(value =“/ queryPage”,method = {RequestMethod.GET})
@responsebody
public PageResultSet queryPage(Model model){
PageHelper.startPage 1 ,10);
示例示例= new示例(BasketconfigCLssModel.class);
example.setOrderByClause(“bkserialno”);
返回新的PageResultSet(service.selectByExample(example));

}`

一直报这个错,导致的原因是什么?哪位大神知道啊?帮帮忙!

org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.builder.BuilderException: Error invoking SqlProvider method (tk.mybatis.mapper.provider.base.BaseSelectProvider.dynamicSQL). Cause: java.lang.InstantiationException: tk.mybatis.mapper.provider.base.BaseSelectProvider

at org.mybatis.spring.MyBatisExceptionTranslator.translateExceptionIfPossible(MyBatisExceptionTranslator.java:77)
at org.mybatis.spring.SqlSessionTemplate$SqlSessionInterceptor.invoke(SqlSessionTemplate.java:446)
at com.sun.proxy.$Proxy130.selectList(Unknown Source)
at org.mybatis.spring.SqlSessionTemplate.selectList(SqlSessionTemplate.java:230)
at org.apache.ibatis.binding.MapperMethod.executeForMany(MapperMethod.java:137)
at org.apache.ibatis.binding.MapperMethod.execute(MapperMethod.java:75)
at org.apache.ibatis.binding.MapperProxy.invoke(MapperProxy.java:59)
at com.sun.proxy.$Proxy165.selectAll(Unknown Source)

第六章,selectAllUserAndRoles 方法2层嵌套查询一个用户对应的角色和权限

问题来自:http://blog.csdn.net/qq_20906083
源地址:http://blog.csdn.net/isea533/article/details/73555400#comments

第六章,selectAllUserAndRoles 方法2层嵌套查询一个用户对应的角色和权限。

按你所说,Myabtis都会按层比较,先比较顶层对象,相同,再比较下一层(SysUser 顶层,SysRole 下一层,SysPrivilage 最底层),那么在该查询中 SysUser 总会查询出5个角色,因为查到 SysPrivilage 时总会不一样,所以将用户相同角色的不同权限会当做不同的角色?和书里面给出的结果不符?

老哥,在update的时候出现条件是全部字段,这是什么原因呢?

2018/03/21-17:53:55 [http-nio-80-exec-4] DEBUG com.wwy.mapper.LevelInfoMapper.updateByPrimaryKey- ==> Preparing: UPDATE level_info SET id = ?,group_id = ?,level_name = ?,level_mini_score = ?,level_max_score = ?,create_date = ?,update_date = ? WHERE id = ? AND group_id = ? AND level_name = ? AND level_mini_score = ? AND level_max_score = ? AND create_date = ? AND update_date = ?
2018/03/21-17:53:55 [http-nio-80-exec-4] DEBUG com.wwy.mapper.LevelInfoMapper.updateByPrimaryKey- ==> Parameters: 1(Integer), 1(String), 访客(String), 1(Integer), 0(Integer), 0(String), 0(String), 1(Integer), 1(String), 访客(String), 1(Integer), 0(Integer), 0(String), 0(String)
2018/03/21-17:53:55 [http-nio-80-exec-4] DEBUG com.wwy.mapper.LevelInfoMapper.updateByPrimaryKey- <== Updates: 0


        LevelInfoModel levelInfoModel = new LevelInfoModel();
        levelInfoModel.setId(1);
        levelInfoModel  = levelInfoMapper.selectOne(levelInfoModel);
        levelInfoModel.setLevelMiniScore(levelInfoModel.getLevelMiniScore()+1);
        int flag = levelInfoMapper.updateByPrimaryKey(levelInfoModel);

使用spring boot集成通用mapper1.1.1,在查询和添加是正常的,唯独在更新的时候出现问题;


找到问题了,原因是我的实体类是使用hibernate生成的,id注解不在变量,而在方法上,能否修改这个bug或者机制

数据库兼容

当下,我国国家单位软件国产化正在开展,数据库方面达梦数据库为国产最优选择,分页插件pageHelper目前无法自动识别达梦数据源,达梦数据库同时支持SqlServer和Oracle两种标准。查看了PageHelper 5.1.2中page文件夹下PageAutoDialect 类,其中dialectAliasMap中缺少达梦数据库url解析dm对应的值。基于当下的形式以及本人正在学习使用PageHelper插件的情况特向您提出是否能更新jar包从而达到支持达梦数据库的效果。在此拜谢,多有打扰,敬请海涵!

【Mapper】关于自定义的Mapper无法注入的问题

1.DataScopeMapper

public interface DataScopeMapper<T> { 
	
	@SelectProvider(type = DataScopeProvider.class, method = "dynamicSQL")
	List<T> selectDataScope(@Param("entity") T object, @Param("offset") int offset, @Param("limit") int limit);
}
  1. DataScopeProvider

public class DataScopeProvider extends MapperTemplate {

	public DataScopeProvider(Class<?> mapperClass, MapperHelper mapperHelper) {
		super(mapperClass, mapperHelper); 
	}
	
	
	public String  selectDataScope(MappedStatement ms) {
		 StringBuilder sql = new StringBuilder();
		Class<?> entityClass = getEntityClass(ms); 
		//修改返回值类型为实体类型
		setResultType(ms, entityClass);
		Set<EntityColumn> columnList = EntityHelper.getColumns(entityClass);  
        sql.append(SqlHelper.selectAllColumns(entityClass));
        sql.append(SqlHelper.fromTable(entityClass, tableName(entityClass)));  
        return sql.toString();
	}

}

3.扫描


bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.nxu.modules.*.mapper"/> 
        <!-- 通用Mapper通过属性注入进行配置,默认不配置时会注册Mapper<T>接口  -->
        <property name="properties">
            <value>
                mappers=tk.mybatis.mapper.common.Mapper,com.nxu.core.persistence.mybatis.DataScopeMapper
                IDENTITY=MYSQL 
            </value>
        </property>
       
    </bean>

4.注入

   @Autowired
   private DataScopeMapper<Org> dataScopeMapper;

5.报错

No qualifying bean of type [com.nxu.core.persistence.mybatis.DataScopeMapper] found for dependency: expected at least 1 bean which qualifies as autowire candidate for this dependency. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

求解答,在线等,谢谢~

mybatis自带扫描器无法初始化所有的Provider

原项目使用spring和tk.mybatis结合的时候没有问题。
但是另外一个项目未使用spring,直接使用mybatis自带的扫描器加载所有mapper。这时候,执行到mapper中的基类方法时,总是出现以下错误:
Caused by: java.lang.NoSuchMethodException: tk.mybatis.mapper.provider.base.BaseSelectProvider.()
at java.lang.Class.getConstructor0(Class.java:3082)
at java.lang.Class.newInstance(Class.java:412)
... 11 more
调试发现是因为无法初始化Provider造成的。
请问有解决的办法吗?

利用mybatis插件自动生成代码问题

你好,使用mybatis的插件自动生成代码,可以自动生成dao、xml等等。有自动生成功能,是很方便,但是第一次生成之后,随着开发的深入,必然会在xml里面添加特有的方法,这个时候,如果要增加字段,就无法再使用mybatis的插件自动生成,因为自动生成会覆盖特有的方法,就必须要手动去添加,如果涉及的表很多,这个将会是个工作量比较大的地方,有什么好的解决方案呢?

关于自定义类型处理器

在31页中,根据用户id获取角色信息,由于上下文中没有提及EnabledTypeHandler,导致出现异常:
org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'enabled' from result set
对于初学者来说是比较难解决这个问题的。

MyBatis XML 标签类型说明

MyBatis XML 标签类型说明

  • resultMap 标签的类型属性为 type(必填)。

  • id, result 标签的类型属性为javaType(可选)。

  • idArg, arg 标签和上面两个类似,也都是 javaType(可选)。

  • association 标签的类型属性为 javaType(可选)。

  • discriminator 标签的类型属性为 javaType(可选)。

  • collection 这个标签最特殊,有两个类型属性,分别为 javaType(可选) 和 ofType(结果映射时必填)。

上面除collection外都只有一个类型的属性,所以设置他们的类型时没有任何问题。

可以看到上面所有的 javaType 属性都是可选的,这是因为在resultMap标签typecollection标签ofType)类型已知的情况下是可以推断该类型中其他字段的javaType。自动推断类型的代码如下:

private Class<?> resolveResultJavaType(Class<?> resultType, String property, Class<?> javaType) {
    if (javaType == null && property != null) {
        try {
            MetaClass metaResultType = MetaClass.forClass(resultType,
                    configuration.getReflectorFactory());
            javaType = metaResultType.getSetterType(property);
        } catch (Exception e) {
            //ignore, following null check statement will deal with the situation
        }
    }
    if (javaType == null) {
        javaType = Object.class;
    }
    return javaType;
}

点击查看完整源码

上面通过反射获取到该属性的 setterType,如果属性没有对应的 setter,会直接通过属性名查找字段得到该类型。

例如 resultType="User" property="userName"

如果设置了 javaType,就返回该值。

如果没有设置,就会通过反射获取到 userName 的属性为 java.lang.String。

了解javaType后,还剩下 resultMaptypecollectionofType 属性。

这两个属性是意义相同的两个属性,并且都是必填项。使用嵌套的时候,collection 只会推断出 javaType,可能是个List类型,但是无法推断出这个集合的泛型类型是什么,因此 ofType 需要手动设置。在使用嵌套结果映射时,这个值必填,因为 MyBatis 映射结果时,需要知道collection的类型,后续还会根据这个类型推断 collectionid,result等标签的javaType

其他注意事项

对于 association,collection,case 标签,select 属性优先级最高。

同时配置时,嵌套查询优先级高于结果映射。

勘误

在《MyBatis 从入门到精通》第141页中,由于直接从association直接替换为了collection,这里的javaType没有修改为ofType,因此会导致SysRole无法转换为List类型的错误。

这里应该将javaType修改为ofType,如下图。

141

通用mapper,自定义mapper,NoSuchBeanDefinitionException 异常

@逆流而上
1.自定义 MyMapper 继承 BaseUpdateMapper,实现 logicalDelete 方法

public interface MyMapper<T>{

    /**
     * 根据主键进行逻辑删除
     * @param id
     * @return
     */
    @UpdateProvider(type = ABaseProvider.class,method = "dynamicSQL")
    @Options(useCache = false, useGeneratedKeys = false)
    int logicalDelete(String id);

}

2.在spring中配置mapper configurer,保留原来的 Mapper

    <!-- 配置mybatis通用mapper -->
    <bean class="tk.mybatis.spring.mapper.MapperScannerConfigurer">
        <property name="basePackage" value="com.well.module.**.mapper" />
        <property name="properties">
            <value>
                mappers=tk.mybatis.mapper.common.Mapper,com.well.kernel.mybatis.mapper.MyMapper
            </value>
        </property>
    </bean>

3.在ABaseService中注入MyMapper

public abstract class ABaseService<T extends ABaseEntity> extends AbstractService<T>
{
    private static Logger logger=Logger.getLogger(ABaseService.class);

    @Autowired
    private MyMapper<T> aBaseMapper;
}

抛出 org.springframework.beans.factory.NoSuchBeanDefinitionException 异常

【书籍勘误】

在第六章,135页。
在UserMapperTest中编写测试之前,缺少了”在UserMapper接口中声明相应的方法”这一段的说明,否则无法调用selectUserAndRoleByIdSelect 方法。

使用Example方法报错

你好,前辈,在你的博客上下载的最新代码,

default

仍然有org.apache.ibatis.reflection.ReflectionException: There is no getter for property named 'distinct' in 'class tk.mybatis.springboot.model.UserInfo'
这个错误,实在是不知道怎么解决

通用mapper如何支持日期类型的条件查询呢

比如使用andEqualTo方法,而我的数据库的该字段是日期类型
public Example.Criteria andEqualTo(String property, Object value) {
this.addCriterion(this.column(property) + " =", value, this.property(property));
return (Example.Criteria)this;
}

《MyBatis 从入门到精通》mybatis-config.xml 配置文件补充内容

关于完整的 mybatis-config.xml 配置项,因为官方文档很详细,所以书中只是在需要用到什么配置的时候,才会增加相应的配置,不想在官方文档很完善的基础上涉及太多,因此,如果想要详细了解这部分内容,建议看完全书后再看这部分内容。

文档地址:http://www.mybatis.org/mybatis-3/zh/configuration.html

XML 映射配置文件

MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息。文档的顶层结构如下:

  • configuration 配置
  • properties 属性
  • settings 设置
  • typeAliases 类型命名
  • typeHandlers 类型处理器
  • objectFactory 对象工厂
  • plugins 插件
  • environments 环境
    • environment 环境变量
      • transactionManager 事务管理器
      • dataSource 数据源
  • databaseIdProvider 数据库厂商标识
  • mappers 映射器

在配置 mybatis-config.xml 配置文件的时候,最关键的一点就是,必须按照上面标签的顺序进行配置。

实现mybatis插件接口分页问题

您好,我在项目中需要用到mybatis分页,但是处理过程中遇到了__frch_*_0 字段不存在的问题,由于我对mybatis源码不太了解,鼓捣了半天也没改好,所以想请教一下。我用的mybatis版本是3.4.1

【勘误】第五章 Mybatis代码生成器

感谢杨阳通过邮件反馈的这个问题。

问题如下:

书中第五章 Mybatis代码生成器
中P107使用

<generatedKey column="id" sqlStatement="MySql"/>

生成的对应代码为:

<selectKey keyProperty="empId" order="BEFORE" resultType="java.lang.Integer">
  SELECT LAST_INSERT_ID()
</selectKey>

这令我很不解,因为书中说生成的order应该为AFTER,我是用的是MySQL数据库

我自己也进行了测试,代码生成器生成的方法可以正确使用。


这里确实有问题,如果字段是自增的,还需要设置一个额外的属性。上述配置修改如下:

<generatedKey column="id" sqlStatement="MySql" identity="true"/>

增加的 identity="true",该属性默认 false,这个参数不仅会影响 selectKey 代码的位置(前后),对 order 属性也有影响,generatedKey 完整介绍看这里: http://mbg.cndocs.ml/configreference/generatedKey.html

New Chinese technical book: MyBatis 从入门到精通

中文版

MyBatis 从入门到精通

This is a Chinese version of the technical book.

I wrote a lot of blogs related to MyBatis in the CSDN blog, because I found that writing is not systematic enough, so I created an open source ebook called MyBatis Best Practices at GitBook.

At that time I wrote the directory outline, due to the maintenance of several open source projects, spare time is almost occupied, and ultimately only write MyBatis Generator part.

In March 2016, Sun Qiqiao editor contacted me, and then I began to write a book of MyBatis.


In the last chapter of this book, I introduced the MyBatis open source project.

This chapter is a gateway to the open source world, is also a gateway to MyBatis source of learning the door.

Starting with Git and GitHub Getting Started, readers can learn to use the most popular distributed version control systems and source code hosting services.

Through a section of code(the following code) so that we understand some of the key classes in MyBatis.

Through the code package to understand the contents of each package MyBatis included.

And finally through MyBatis rich test cases for readers to provide more useful learning content.

This chapter also describes how to collect and Fork MyBatis. How to use git to download MyBatis.

I hope that through this book can let more people know MyBatis, and promote the development of MyBatis.


The following code will let you know more about MyBatis.

package tk.mybatis.simple;

import java.io.IOException;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

import org.apache.ibatis.binding.MapperProxyFactory;
import org.apache.ibatis.builder.StaticSqlSource;
import org.apache.ibatis.cache.Cache;
import org.apache.ibatis.cache.decorators.LoggingCache;
import org.apache.ibatis.cache.decorators.LruCache;
import org.apache.ibatis.cache.decorators.SerializedCache;
import org.apache.ibatis.cache.decorators.SynchronizedCache;
import org.apache.ibatis.cache.impl.PerpetualCache;
import org.apache.ibatis.datasource.unpooled.UnpooledDataSource;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.logging.LogFactory;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.mapping.ParameterMap;
import org.apache.ibatis.mapping.ParameterMapping;
import org.apache.ibatis.mapping.ResultMap;
import org.apache.ibatis.mapping.ResultMapping;
import org.apache.ibatis.mapping.SqlCommandType;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.defaults.DefaultSqlSession;
import org.apache.ibatis.transaction.Transaction;
import org.apache.ibatis.transaction.jdbc.JdbcTransaction;
import org.apache.ibatis.type.TypeHandlerRegistry;
import org.junit.Test;

import tk.mybatis.simple.model.Country;

public class SimpleMyBatis {

    @Test
    public void test() throws IOException, SQLException {
        LogFactory.useLog4JLogging();
        //Create a configuration object
        final Configuration config = new Configuration();
        //Configure some of the properties in settings
        config.setCacheEnabled(true);
        config.setLazyLoadingEnabled(false);
        config.setAggressiveLazyLoading(true);
        
        //add interceptor
        SimpleInterceptor interceptor1 = new SimpleInterceptor("Interceptor 1");
        SimpleInterceptor interceptor2 = new SimpleInterceptor("Interceptor 2");
        config.addInterceptor(interceptor1);
        config.addInterceptor(interceptor2);

        //Create a DataSource
        UnpooledDataSource dataSource = new UnpooledDataSource();
        dataSource.setDriver("com.mysql.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mybatis");
        dataSource.setUsername("root");
        dataSource.setPassword("");

        //Use JDBC transactions
        Transaction transaction = new JdbcTransaction(dataSource, null, false);

        //Create an Executor
        final Executor executor = config.newExecutor(transaction);
        
        //Type handle registry
        final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();

        /*
         The following steps correspond to parsing XML or 
         parsing the interface annotation method to generate MappedStatement
        */

        //The simplest, equivalent to getting SQL from xml or interface annotations
        StaticSqlSource sqlSource = new StaticSqlSource(
        		config, "SELECT * FROM country WHERE id = ?");

        //Because the above SQL has a parameter id, where the need to provide ParameterMapping
        List<ParameterMapping> parameterMappings = new ArrayList<ParameterMapping>();
        //Create ParameterMapping via ParameterMapping.Builder
        parameterMappings.add(new ParameterMapping.Builder(
        		config, "id", registry.getTypeHandler(Long.class)).build());
        ParameterMap.Builder paramBuilder = new ParameterMap.Builder(
        		config, "defaultParameterMap", Country.class, parameterMappings);

        //Create a result mapping
        @SuppressWarnings("serial")
		ResultMap resultMap = new ResultMap.Builder(config, "defaultResultMap", Country.class,
                new ArrayList<ResultMapping>() {
					{
                        add(new ResultMapping.Builder(config, "id", "id", Long.class).build());
                        add(new ResultMapping.Builder(config, "countryname", "countryname", String.class).build());
                        add(new ResultMapping.Builder(config, "countrycode", "countrycode", registry.getTypeHandler(String.class)
                        ).build());
                    }
                }).build();

        //Cache is a cache object that uses decor mode
        final Cache countryCache =
                new SynchronizedCache(
                        new SerializedCache(
                                new LoggingCache(
                                        new LruCache(
                                                new PerpetualCache("country_cache")
                                        ))));
        //Create a MappedStatement
        MappedStatement.Builder msBuilder = new MappedStatement.Builder(
        		config, "tk.mybatis.simple.SimpleMapper.selectCountry", sqlSource, SqlCommandType.SELECT);
        msBuilder.parameterMap(paramBuilder.build());
        List<ResultMap> resultMaps = new ArrayList<ResultMap>();
        resultMaps.add(resultMap);
        //Set the resultMap of the return value
        msBuilder.resultMaps(resultMaps);
        //Set the cache
        msBuilder.cache(countryCache);
        
        MappedStatement ms = msBuilder.build();

        //First, use executor to execute
        List<Country> countries = executor.query(ms, 1L, RowBounds.DEFAULT, Executor.NO_RESULT_HANDLER);

        for (Country country : countries) {
        	System.out.println(country.getCountryname());
        }

        //Second, add ms to config
        config.addMappedStatement(ms);
        //Create SqlSession
        SqlSession sqlSession = new DefaultSqlSession(config, executor, false);
        //query
        Country country = sqlSession.selectOne("selectCountry", 2L);
    	System.out.println(country.getCountryname());

        //Third, interface mode, create interface agent factory class
        MapperProxyFactory<SimpleMapper> mapperProxyFactory = new MapperProxyFactory<SimpleMapper>(SimpleMapper.class);
        //Create a proxy interface
        SimpleMapper simpleMapper = mapperProxyFactory.newInstance(sqlSession);
        //execute
        country = simpleMapper.selectCountry(3L);
    	System.out.println(country.getCountryname());
        //Close the Session
        sqlSession.close();
    }
}

SimpleInterceptor:

package tk.mybatis.simple;

import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

@Intercepts(@Signature(type = Executor.class, method = "query",
			args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}))
public class SimpleInterceptor implements Interceptor {
	private String name;
	
	public SimpleInterceptor(String name) {
		this.name = name;
	}

	@Override
	public Object intercept(Invocation invocation) throws Throwable {
		System.out.println("Into the interceptor:" + name);
		Object result = invocation.proceed();
		System.out.println("Jump out of interceptor:" + name);
		return result;
	}

	@Override
	public Object plugin(Object target) {
		return Plugin.wrap(target, this);
	}

	@Override
	public void setProperties(Properties properties) {
	}

}

Create the database information you need to use in the above code

11


Fork MyBatis

22

求书

图片传不上来呢

【书籍勘误】

在第六章,150页。
原文底部:

修改RoleMapper.xmlroleMap 配置,代码如下。
...
...
<association property="createInfo">...

<association property="createInfo"> 这一句,应该需要补加声明其javaType="xxxx.CreateInfo" ,否则测试代码会报错,无法进行Debug 查看createInfo 变量的值。

【书籍勘误】

第六章,138-138页。
书中提到mybatis中,aggressiveLazyLoading 属性默认值是true ,需要手动设置为false
但是现在的版本:mybatis-3.4.5 ,该属性默认值为false 。因而无需设置了。

《MyBatis 从入门到精通》转发送书~~~

《MyBatis 从入门到精通》转发送书~~~

京东已经可以直接购买:https://item.jd.com/12103309.html

活动说明

根据参与人数进行送书,随机从所有参与人员中抽取几位朋友送书。

当前页面有效参与人数每超过100人,就增加一个送书名额。

活动时间:2017年6月30日 至 2017年7月5日(23点59分),当人数超出300人时提前结束。

结束后会通过直播或者其他方式进行抽奖,抽奖结束后我会联系中奖的朋友。

为了便于统计,我会删除重复无效的回复,谢谢理解!

为了防止图片太大太卡,我稍后会对图片进行处理。

首先关注下方微信公众号。

default

进入公众号后,点击菜单【新书购买】

点击进入图文消息,转发到朋友圈或QQ空间

转发到朋友圈后,在当前页面发截图即可。

提示:GitHub 的 issue 的可以编辑,上传图片时可以直接将图片拖拽到编辑框中进行上传。

如果上传遇到问题,还可以使用外链,markdown 图片格式如下:

![随便写](http://图片地址.jpg)

还可以使用<img/>标签,可以控制图片大小:

<img src="http://图片地址.jpg" width="50%"/>

大家在参与活动同时,还可以收藏下面几个项目

简单的抽奖代码

import java.util.*;

/**
 * @author liuzh
 * @since 2017/7/5.
 */
public class Lottery {

    public static void main(String[] args) {
        int nums = 2;
        String[] users = new String[]{
                "test0", "test1", "test2", "test3", "test4", "test5", "test6", "test7", "test8", "test9",
                "test10", "test11", "test12", "test13", "test14", "test15", "test16", "test17", "test18", "test19",
                "test20", "test21", "test22", "test23", "test24", "test25", "test26", "test27", "test28", "test29",
                "test30", "test31", "test32", "test33", "test34", "test35", "test36", "test37", "test38", "test39",
                "test40", "test41", "test42", "test43", "test44", "test45", "test46", "test47", "test48", "test49",
        };
        lottery(users, nums);
    }

    public static void lottery(String[] users, int nums){
        List<String> userList = Arrays.asList(users);
        //乱序
        Collections.shuffle(userList);
        Random random = new Random();
        int i = 0;
        Set<Integer> set = new HashSet<>(nums);
        do {
            int nextInt = random.nextInt(userList.size());
            if(!set.contains(nextInt)){
                set.add(nextInt);
                i++;
            }
        } while (i < nums);
        System.out.println("============中奖名单============");
        for (Integer num : set) {
            System.out.println(userList.get(num));
        }
    }

}

《MyBatis 从入门到精通》23页第1点,没有问题

书中内容如下:

1

好多人都认为“如果存在,才应该抛出异常”。

为什么是存在才会抛出异常

MyBatis 这种策略是为了防止同一个命名空间(所在的接口或者XML)配置多次导致重复读取。所以如果存在,就说明已经读取过了,不能再次读取。这里的逻辑是没有问题的。

验证的方法很简单,就是将同一个mapper配置两次就能看到效果。

spring boot 配置 databaseIdProvider 报org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.joinsun.XX.mapper.UserMapper.findById

mybatis-config.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
    <settings>
        <!-- 打印SQL语句到控制台 -->
        <setting name="logImpl" value="STDOUT_LOGGING"/>
    </settings>
    <databaseIdProvider type="DB_VENDOR">
    <property name="MySQL" value="mysql"/>
    <property name="Oracle" value="oracle"/>
    </databaseIdProvider>
</configuration>

*Mapper.xml

<select id="findByPassword" resultMap="userMap" databaseId="mysql">
        SELECT * FROM t_sys_user WHERE account=#{0} and password= #{1}
    </select>

application.properties

spring.datasource.driverClassName = com.mysql.jdbc.Driver
spring.datasource.url = jdbc:mysql://localhost:3306/dd?useUnicode=true&characterEncoding=utf-8
spring.datasource.username = root
spring.datasource.password = admin
mybatis.config-location=classpath:/mybatis-config.xml
mybatis.mapper-locations=classpath:mapper/*.xml
logging.config=classpath:logging-config.xml

《MyBatis 从入门到精通》多空格的错误

最早开始排版时因为按照正常代码换行写的,所以排版效果出来后,由于宽度限制,代码换行很乱。

为了方便阅读,因此对书中全部代码(包括日志)重新设置换行,因为需要在排版后的基础上进行修改,因此由于自动换行(在变成一行时)导致代码中出现了许多不应该出现的空格,重新设置换行后,大部分空白都去掉了。但是现在发现仍然存在一些多余的空格,电子版中有些空格显示的不是很明显,在纸上可以明显辨别出来。

书籍购买

有没有电子版本?或者提供电子版的购买地址,thx!

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.