mybatis-book / book Goto Github PK
View Code? Open in Web Editor NEWMyBatis 从入门到精通
MyBatis 从入门到精通
照著書上的說明寫好了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后,发现对应的枚举字段没有插入
虽然人数没达到之前设定的目标,但是会送出两本书。
抽奖代码也没有多复杂,对参与人员乱序后,抽取两位幸运的朋友。
没有中奖的朋友也没有关系,凡是参与本次活动的朋友,如果自己购买了本书,可以和我联系,我个人单独发个3块钱的红包当作参与奖,谢谢大家的参与!
2017年7月6日,12点整,在斗鱼进行直播。
房间号:2451707,在线观看
直播时间 1 分钟左右。。
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
在第七章的本章小节中,书中提到了,为了避免脏读,在任何情况中,都可以考虑在业务层中使用可控制的缓存来代替二级缓存。请问这里所谓的可控制的缓存是指通过哪些手段来控制呢?是否可以指点一二,谢谢
此处应该去掉 extends="userMapper"
如题,建议支持方法级别注解,有些场景需要注解到getter方法上,谢谢!
问题代码如下:
#{item}
由于项目中用到了分页拦截器,一旦有分页的sql中,用#{}获取值都会报错( org.apache.ibatis.binding.BindingException: Parameter '__frch_item_0' not found.),换成${}这种方式就好了,请问什么原因?
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报错:
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));
}`
书上25页倒数几行的 这个id只能是主键吗?
和 这种写法的区别或者性能区别在哪里呢?没看明白
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)
一对多的关联分页怎么做到只对主表分页,再拿到对应的关联结果集?
问题来自:http://blog.csdn.net/qq_20906083
源地址:http://blog.csdn.net/isea533/article/details/73555400#comments
第六章,selectAllUserAndRoles
方法2层嵌套查询一个用户对应的角色和权限。
按你所说,Myabtis都会按层比较,先比较顶层对象,相同,再比较下一层(SysUser
顶层,SysRole
下一层,SysPrivilage
最底层),那么在该查询中 SysUser
总会查询出5个角色,因为查到 SysPrivilage
时总会不一样,所以将用户相同角色的不同权限会当做不同的角色?和书里面给出的结果不符?
大师兄麻烦帮看下下这mybatis 插件问题
https://github.com/LuanLouis/mybatis-enhanced-cache/blob/master/src/main/java/org/luanlouis/mybatis/plugin/cache/EnhancedCachingExecutor.java
private synchronized void clearSessionData()
{
queryCacheOnCommit.clear();
updateStatementOnCommit.clear();
}
要是存在两个会话,第一个执行这方法,那么此不是会影响到第二个会话?
这处是否存在并发问题
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包从而达到支持达梦数据库的效果。在此拜谢,多有打扰,敬请海涵!
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);
}
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)}
求解答,在线等,谢谢~
原项目使用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造成的。
请问有解决的办法吗?
插件类:tk.mybatis.mapper.generator.MapperPlugin
生成的注释示例:
<!-- WARNING - @mbg.generated --> /** * @return USER_ID */
这些注释并不是对所有人都有用,能不能关掉呢?
你好,使用mybatis的插件自动生成代码,可以自动生成dao、xml等等。有自动生成功能,是很方便,但是第一次生成之后,随着开发的深入,必然会在xml里面添加特有的方法,这个时候,如果要增加字段,就无法再使用mybatis的插件自动生成,因为自动生成会覆盖特有的方法,就必须要手动去添加,如果涉及的表很多,这个将会是个工作量比较大的地方,有什么好的解决方案呢?
在31页中,根据用户id获取角色信息,由于上下文中没有提及EnabledTypeHandler
,导致出现异常:
org.apache.ibatis.executor.result.ResultMapException: Error attempting to get column 'enabled' from result set
对于初学者来说是比较难解决这个问题的。
resultMap
标签的类型属性为 type
(必填)。
id
, result
标签的类型属性为javaType
(可选)。
idArg
, arg
标签和上面两个类似,也都是 javaType
(可选)。
association
标签的类型属性为 javaType
(可选)。
discriminator
标签的类型属性为 javaType
(可选)。
collection
这个标签最特殊,有两个类型属性,分别为 javaType
(可选) 和 ofType
(结果映射时必填)。
上面除collection
外都只有一个类型的属性,所以设置他们的类型时没有任何问题。
可以看到上面所有的 javaType
属性都是可选的,这是因为在resultMap
标签type
(collection
标签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
后,还剩下 resultMap
的 type
和 collection
的 ofType
属性。
这两个属性是意义相同的两个属性,并且都是必填项。使用嵌套的时候,collection
只会推断出 javaType
,可能是个List
类型,但是无法推断出这个集合的泛型类型是什么,因此 ofType
需要手动设置。在使用嵌套结果映射时,这个值必填,因为 MyBatis 映射结果时,需要知道collection
的类型,后续还会根据这个类型推断 collection
中id
,result
等标签的javaType
。
对于 association
,collection
,case
标签,select
属性优先级最高。
同时配置时,嵌套查询优先级高于结果映射。
在《MyBatis 从入门到精通》第141页中,由于直接从association
直接替换为了collection
,这里的javaType
没有修改为ofType
,因此会导致SysRole
无法转换为List
类型的错误。
这里应该将javaType
修改为ofType
,如下图。
@逆流而上
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
方法。
通用Mapper 为什么使用jpa注解特性呢, 集成时可以不使用么
欢迎大家通过回复留下 MyBatis 插件/拦截器 项目的地址~
如题,谢谢。
比如使用andEqualTo方法,而我的数据库的该字段是日期类型
public Example.Criteria andEqualTo(String property, Object value) {
this.addCriterion(this.column(property) + " =", value, this.property(property));
return (Example.Criteria)this;
}
关于完整的 mybatis-config.xml 配置项,因为官方文档很详细,所以书中只是在需要用到什么配置的时候,才会增加相应的配置,不想在官方文档很完善的基础上涉及太多,因此,如果想要详细了解这部分内容,建议看完全书后再看这部分内容。
文档地址:http://www.mybatis.org/mybatis-3/zh/configuration.html
MyBatis 的配置文件包含了影响 MyBatis 行为甚深的设置(settings)和属性(properties)信息。文档的顶层结构如下:
在配置 mybatis-config.xml 配置文件的时候,最关键的一点就是,必须按照上面标签的顺序进行配置。
您好,我在项目中需要用到mybatis分页,但是处理过程中遇到了__frch_*_0 字段不存在的问题,由于我对mybatis源码不太了解,鼓捣了半天也没改好,所以想请教一下。我用的mybatis版本是3.4.1
感谢杨阳通过邮件反馈的这个问题。
问题如下:
书中第五章 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
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) {
}
}
图片传不上来呢
在第六章,150页。
原文底部:
修改
RoleMapper.xml
的roleMap
配置,代码如下。
...
...
<association property="createInfo">...
在<association property="createInfo">
这一句,应该需要补加声明其javaType="xxxx.CreateInfo"
,否则测试代码会报错,无法进行Debug
查看createInfo
变量的值。
第六章,138-138页。
书中提到mybatis中,aggressiveLazyLoading
属性默认值是true
,需要手动设置为false
。
但是现在的版本:mybatis-3.4.5
,该属性默认值为false
。因而无需设置了。
京东已经可以直接购买:https://item.jd.com/12103309.html
根据参与人数进行送书,随机从所有参与人员中抽取几位朋友送书。
当前页面有效参与人数每超过100人,就增加一个送书名额。
活动时间:2017年6月30日 至 2017年7月5日(23点59分),当人数超出300人时提前结束。
结束后会通过直播或者其他方式进行抽奖,抽奖结束后我会联系中奖的朋友。
为了便于统计,我会删除重复无效的回复,谢谢理解!
为了防止图片太大太卡,我稍后会对图片进行处理。
提示: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-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
最早开始排版时因为按照正常代码换行写的,所以排版效果出来后,由于宽度限制,代码换行很乱。
为了方便阅读,因此对书中全部代码(包括日志)重新设置换行,因为需要在排版后的基础上进行修改,因此由于自动换行(在变成一行时)导致代码中出现了许多不应该出现的空格,重新设置换行后,大部分空白都去掉了。但是现在发现仍然存在一些多余的空格,电子版中有些空格显示的不是很明显,在纸上可以明显辨别出来。
有没有电子版本?或者提供电子版的购买地址,thx!
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.