MyBatis从入门到熟悉

以下代码获取地址:

https://github.com/Jenyow/codelib/tree/master/codelib-parent/codelib-springboot-samples/codelib-springboot-sample-mybatis

对于代码中的不足,或者其他实现需要补充的,可以提出,我们共同探讨探讨

MyBatis Generator

MyBatis Generator 是一个可以生成 MyBatis 代码的工具。(当然不用也是可以的,只要你不怕麻烦( ╯▽╰))

以下是基于 Maven 的 MyBatis Generator 配置:

POM.xml:

  1. <build>
  2. <plugins>
  3. <plugin>
  4. <groupId>org.mybatis.generator</groupId>
  5. <artifactId>mybatis-generator-maven-plugin</artifactId>
  6. <version>1.3.5</version>
  7. <configuration>
  8. <!--执行过程会输出到控制台 -->
  9. <verbose>true</verbose>
  10. <!--不允许覆盖生成的文件 -->
  11. <!-- 如果设置为true,如果生成的java文件存在已经同名的文件,新生成的文件会覆盖原有的文件。 这个过程大概可以理解为:删除原来的,重新生成新的.对于自己写的、修改的内容没有了
  12. 如果设置为false,如果存在同名的文件,MBG会给新生成的代码文件生成一个唯一的名字 例如: MyClass.java.1, MyClass.java.2
  13. 等等 -->
  14. <overwrite>false</overwrite>
  15. <!-- 如果指定了该参数,逗号隔开的这个表会被运行, 这些表名必须和 <table> 配置中的表面完全一致。 只有指定的这些表会被执行。
  16. 如果没有指定该参数,所有的表都会被执行。 -->
  17. <!-- 对于修改、新增的表,指定该属性进行构建比较合理 -->
  18. <!-- <tableNames></tableNames> -->
  19. </configuration>
  20. <dependencies>
  21. <!-- 配置这个依赖主要是为了等下在配置MG的时候可以不用配置classPathEntry这样的一个属性,避免代码的耦合度太高 -->
  22. <dependency>
  23. <groupId>mysql</groupId>
  24. <artifactId>mysql-connector-java</artifactId>
  25. <version>5.1.42</version><!-- 必须指定版本号 -->
  26. </dependency>
  27. </dependencies>
  28. </plugin>
  29. </plugins>
  30. </build>

必须加入数据库驱动,我用的是 mysql ,所以加入如下依赖。

  1. <!-- mysql -->
  2. <dependency>
  3. <groupId>mysql</groupId>
  4. <artifactId>mysql-connector-java</artifactId>
  5. <scope>runtime</scope>
  6. </dependency>

generatorConfig.properties:

  1. driver=com.mysql.jdbc.Driver
  2. url=jdbc:mysql://localhost:3306/db_dbtest
  3. username=root
  4. password=******

generatorConfig.xml:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE generatorConfiguration
  3. PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
  4. "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
  5. <generatorConfiguration>
  6. <properties resource="generatorConfig.properties"/>
  7. <!--
  8. 元素类型为 "context" 的内容必须匹配 (注意顺序)
  9. "(property*,plugin*,commentGenerator?,(connectionFactory|jdbcConnection),
  10. javaTypeResolver?,javaModelGenerator,sqlMapGenerator?,javaClientGenerator?,table+)"。
  11. -->
  12. <context id="DB2Tables" targetRuntime="MyBatis3">
  13. <!-- 这个插件给由MBG生成的Java模型对象增加了equals和hashCode方法 -->
  14. <plugin type="org.mybatis.generator.plugins.EqualsHashCodePlugin" />
  15. <!-- 这个插件给由MBG生成的Javas添加了java.io.Serializable标记接口。这个插件给实体类增加了serialVersionUID字段。 -->
  16. <plugin type="org.mybatis.generator.plugins.SerializablePlugin" />
  17. <!-- 该插件给Example类添加方法(实际上是给Criteria内部类)来支持不区分大小写的LIKE搜索 -->
  18. <plugin type="org.mybatis.generator.plugins.CaseInsensitiveLikePlugin" />
  19. <!-- 该插件给实体类添加toString()方法。 -->
  20. <plugin type="org.mybatis.generator.plugins.ToStringPlugin" />
  21. <commentGenerator>
  22. <!-- 设置为flase,生成注释包含时间时间戳 -->
  23. <property name="suppressDate" value="true" />
  24. <!-- 用来指定MBG生成的代码中是否包含任何注释
  25. 设置为false,运行多次插件,不会生成重复的内容
  26. 在pom.xml插件配置中,配置不重写文件,所以不需要插件生成的注释 -->
  27. <property name="suppressAllComments" value="flase" />
  28. </commentGenerator>
  29. <!-- 元素定义如何连接目标数据库 -->
  30. <jdbcConnection driverClass="${driver}"
  31. connectionURL="${url}" userId="${username}" password="${password}">
  32. </jdbcConnection>
  33. <!--
  34. targetProject:被假定为一个已存在的目录结构。 如果目录结构不存在MBG将会失败.
  35. targetPackage:将会转换为 targetProject 适当的子目录结构。 如果有必要,MBG会创建这些子目录。
  36. enableSubPackages:Java模型生成器应该使用子包。
  37. 这意味着在这种情况下生成的模型对象将被放置在名为 test.model.db2admin 的包中(因为表在 DB2ADMIN schema中)。
  38. 如果 enableSubPackages 属性设置为 false, 那么包名将会是 test.model。
  39. Java模型生成器也应该对字符串进行trim操作。
  40. 这意味着任何字符串属性的setter方法将调用trim方法 - 如果您的数据库可能会在字符末尾返回空白符,这是非常有用的。
  41. -->
  42. <javaTypeResolver>
  43. <property name="forceBigDecimals" value="false" />
  44. </javaTypeResolver>
  45. <!-- 元素来指定生成 Java 模型对象所属的包 -->
  46. <javaModelGenerator targetPackage="com.codelib.springboot.sample.mybatis.pojo"
  47. targetProject="src/main/java">
  48. <property name="constructorBased" value="true" />
  49. <property name="enableSubPackages" value="true" />
  50. <property name="trimStrings" value="true" />
  51. </javaModelGenerator>
  52. <!-- 元素来指定生成 SQL 映射文件所属的包和的目标项目 -->
  53. <!-- 如果目标是MyBatis3,那么只有当您选择javaClientGenerator需要XML时,他才是 <context> 元素的一个必须的子元素。 -->
  54. <sqlMapGenerator targetPackage="mapper"
  55. targetProject="src/main/resources">
  56. <property name="enableSubPackages" value="true" />
  57. </sqlMapGenerator>
  58. <!-- 元素来指定目标包和目标项目生成的客户端接口和类 -->
  59. <javaClientGenerator type="XMLMAPPER"
  60. targetPackage="com.codelib.springboot.sample.mybatis.mapper" targetProject="src/main/java">
  61. <property name="enableSubPackages" value="true" />
  62. </javaClientGenerator>
  63. <!-- 配置表映射 -->
  64. <table tableName="courses" domainObjectName="Course">
  65. <property name="constructorBased" value="true" />
  66. <property name="ignoreQualifiersAtRuntime" value="true" />
  67. </table>
  68. <table tableName="students" domainObjectName="Student">
  69. <property name="constructorBased" value="true" />
  70. <property name="ignoreQualifiersAtRuntime" value="true" />
  71. </table>
  72. <table tableName="textbooks" domainObjectName="Textbook">
  73. <property name="constructorBased" value="true" />
  74. <property name="ignoreQualifiersAtRuntime" value="true" />
  75. </table>
  76. <table tableName="grades" domainObjectName="Grade">
  77. <property name="constructorBased" value="true" />
  78. <property name="ignoreQualifiersAtRuntime" value="true" />
  79. </table>
  80. <table tableName="student_courses" domainObjectName="StudentCourse">
  81. <property name="constructorBased" value="true" />
  82. <property name="ignoreQualifiersAtRuntime" value="true" />
  83. </table>
  84. </context>
  85. </generatorConfiguration>

我配置的是生成 xml 的映射。

基本配置可以复用,只需更改对应的包名和表信息即可。

配置好之后,通过 maven 执行 mybatis-generator:generate 命令,即可生成相应的代码。

对于上面的配置,如果执行两次 mybatis-generator:generate 命令,java 的代码会生成备份,xml的不会被覆盖,在xml 中新增的部分会被移到 xml 的尾部。但是值得注意的是,如果修改了代码生成的部分,再执行命令,修改的部分将会被覆盖掉。

影响这一行为的配置是 <commentGenerator> 。建议不要在注释里生成时间戳信息。

对于新增的表,可以在 pom.xml 中 <tableNames></tableNames> 指定本次执行 mybatis-generator:generate 命令生成表的代码,多个表名用逗号隔开。

MyBatis Generator 给每个表生成一个实体类、Example条件类、Mapper接口、xml映射。

MyBatis

MyBatis 配置:

  1. import java.util.Properties;
  2. import org.apache.ibatis.plugin.Interceptor;
  3. import org.apache.ibatis.session.SqlSessionFactory;
  4. import org.mybatis.spring.SqlSessionFactoryBean;
  5. import org.mybatis.spring.annotation.MapperScan;
  6. import org.springframework.beans.factory.annotation.Autowired;
  7. import org.springframework.context.annotation.Bean;
  8. import org.springframework.context.annotation.Configuration;
  9. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  10. import org.springframework.transaction.annotation.EnableTransactionManagement;
  11. import com.alibaba.druid.pool.DruidDataSource;
  12. import com.github.pagehelper.PageInterceptor;
  13. @Configuration
  14. @EnableTransactionManagement
  15. @MapperScan(value = "com.codelib.springboot.sample.mybatis.mapper")
  16. public class MyBatisConfig {
  17. @Autowired
  18. private DruidDataSource dataSource;
  19. @Bean
  20. public SqlSessionFactory sqlSessionFactory() throws Exception {
  21. SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
  22. sqlSessionFactoryBean.setDataSource(dataSource);
  23. // mybatis分页
  24. PageInterceptor pageHelper = new PageInterceptor();
  25. Properties props = new Properties();
  26. props.setProperty("reasonable", "true");
  27. props.setProperty("supportMethodsArguments", "true");
  28. props.setProperty("returnPageInfo", "check");
  29. props.setProperty("params", "count=countSql");
  30. pageHelper.setProperties(props); // 添加插件
  31. Interceptor[] plugins = new Interceptor[] { pageHelper };
  32. sqlSessionFactoryBean.setPlugins(plugins);
  33. PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  34. sqlSessionFactoryBean
  35. .setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
  36. // 在没有注解的情况下,会使用 Bean 的首字母小写的非限定类名来作为它的别名。
  37. sqlSessionFactoryBean.setTypeAliasesPackage("com.codelib.springboot.sample.mybatis.pojo");
  38. return sqlSessionFactoryBean.getObject();
  39. }
  40. }

java 配置和 xml 的配置是对应的。

MyBatis xml 映射配置文件详解,可以通过网址( http://www.mybatis.org/mybatis-3/zh/configuration.html)了解学习

查看 SqlSessionFactoryBean 源码,不难发现跟 xml 对应的 set 方法。

别名包的配置,感觉尤为有用,可以在 mapper xml 配置中省略对象的包名,可以使 xml 更加清晰简洁。

对于不声明别名的情况下,默认是类名(首字母小写)

测试

我的是配置内存数据库 H2 进行测试。

在 src/text/resources 下创建两个文件:application.yml、init_table.sql

application.yml:

  1. spring.datasource:
  2. type: com.alibaba.druid.pool.DruidDataSource
  3. name: mybatistest
  4. driverClassName: org.h2.Driver
  5. url: jdbc:h2:mem:db_users;MODE=MYSQL;INIT=RUNSCRIPT FROM './src/test/resources/init_table.sql'
  6. username:
  7. password:

init_table.sql:

  1. -- ----------------------------
  2. -- Table structure for grades
  3. -- ----------------------------
  4. DROP TABLE IF EXISTS `grades`;
  5. CREATE TABLE `grades` (
  6. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '年级ID',
  7. `name` varchar(255) NOT NULL COMMENT '年级名',
  8. PRIMARY KEY (`id`)
  9. );
  10. -- ----------------------------
  11. -- Records of grades
  12. -- ----------------------------
  13. INSERT INTO `grades` VALUES ('1', '大一');
  14. INSERT INTO `grades` VALUES ('2', '大二');
  15. INSERT INTO `grades` VALUES ('3', '大三');
  16. -- ----------------------------
  17. -- Table structure for students
  18. -- ----------------------------
  19. DROP TABLE IF EXISTS `students`;
  20. CREATE TABLE `students` (
  21. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '学生ID',
  22. `name` varchar(255) NOT NULL COMMENT '学生名',
  23. PRIMARY KEY (`id`)
  24. );
  25. -- ----------------------------
  26. -- Records of students
  27. -- ----------------------------
  28. INSERT INTO `students` VALUES ('1', '赵一');
  29. INSERT INTO `students` VALUES ('2', '钱二');
  30. INSERT INTO `students` VALUES ('3', '孙三');
  31. INSERT INTO `students` VALUES ('4', '李四');
  32. INSERT INTO `students` VALUES ('5', '王五');
  33. -- ----------------------------
  34. -- Table structure for textbooks
  35. -- ----------------------------
  36. DROP TABLE IF EXISTS `textbooks`;
  37. CREATE TABLE `textbooks` (
  38. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '教科书ID',
  39. `name` varchar(255) NOT NULL COMMENT '教科书名',
  40. PRIMARY KEY (`id`)
  41. );
  42. -- ----------------------------
  43. -- Records of textbooks
  44. -- ----------------------------
  45. INSERT INTO `textbooks` VALUES ('1', '《高等数学》');
  46. INSERT INTO `textbooks` VALUES ('2', '《Java编程基础》');
  47. INSERT INTO `textbooks` VALUES ('3', '《设计模式》');
  48. INSERT INTO `textbooks` VALUES ('4', '《大学英语I》');
  49. -- ----------------------------
  50. -- Table structure for courses
  51. -- ----------------------------
  52. DROP TABLE IF EXISTS `courses`;
  53. CREATE TABLE `courses` (
  54. `id` int(11) NOT NULL AUTO_INCREMENT COMMENT '课程ID',
  55. `name` varchar(255) NOT NULL COMMENT '课程名',
  56. `textbook_id` int(11) NOT NULL COMMENT '教科书ID',
  57. `grade_id` int(11) NOT NULL,
  58. PRIMARY KEY (`id`),
  59. KEY `textbook_id` (`textbook_id`),
  60. KEY `grade_id` (`grade_id`),
  61. CONSTRAINT `courses_ibfk_3` FOREIGN KEY (`textbook_id`) REFERENCES `textbooks` (`id`),
  62. CONSTRAINT `courses_ibfk_4` FOREIGN KEY (`grade_id`) REFERENCES `grades` (`id`)
  63. );
  64. -- ----------------------------
  65. -- Records of courses
  66. -- ----------------------------
  67. INSERT INTO `courses` VALUES ('1', '高等数学', '1', '1');
  68. INSERT INTO `courses` VALUES ('2', '大学英语I', '4', '1');
  69. INSERT INTO `courses` VALUES ('3', 'JAVA入门', '2', '2');
  70. INSERT INTO `courses` VALUES ('4', '设计模式', '3', '3');
  71. -- ----------------------------
  72. -- Table structure for student_courses
  73. -- ----------------------------
  74. DROP TABLE IF EXISTS `student_courses`;
  75. CREATE TABLE `student_courses` (
  76. `course_id` int(11) NOT NULL COMMENT '课程ID',
  77. `student_id` int(11) NOT NULL COMMENT '学生ID',
  78. PRIMARY KEY (`course_id`,`student_id`),
  79. KEY `student_id` (`student_id`),
  80. CONSTRAINT `student_courses_ibfk_1` FOREIGN KEY (`student_id`) REFERENCES `students` (`id`),
  81. CONSTRAINT `student_courses_ibfk_2` FOREIGN KEY (`course_id`) REFERENCES `courses` (`id`)
  82. );
  83. -- ----------------------------
  84. -- Records of student_courses
  85. -- ----------------------------
  86. INSERT INTO `student_courses` VALUES ('1', '1');
  87. INSERT INTO `student_courses` VALUES ('2', '1');
  88. INSERT INTO `student_courses` VALUES ('3', '1');
  89. INSERT INTO `student_courses` VALUES ('1', '2');
  90. INSERT INTO `student_courses` VALUES ('2', '2');
  91. INSERT INTO `student_courses` VALUES ('3', '2');
  92. INSERT INTO `student_courses` VALUES ('1', '3');
  93. INSERT INTO `student_courses` VALUES ('2', '3');
  94. INSERT INTO `student_courses` VALUES ('3', '3');

测试类例子,DruidDataSourceConfig 是我项目中 druid 数据库连接池的配置类:

  1. import static org.junit.Assert.*;
  2. import org.junit.Before;
  3. import org.junit.Test;
  4. import org.junit.runner.RunWith;
  5. import org.springframework.beans.factory.annotation.Autowired;
  6. import org.springframework.boot.test.context.SpringBootTest;
  7. import org.springframework.test.context.junit4.SpringRunner;
  8. import org.springframework.transaction.annotation.Transactional;
  9. import com.codelib.springboot.sample.mybatis.config.DruidDataSourceConfig;
  10. import com.codelib.springboot.sample.mybatis.config.MyBatisConfig;
  11. import com.codelib.springboot.sample.mybatis.pojo.Textbook;
  12. @RunWith(SpringRunner.class)
  13. @SpringBootTest(classes={MyBatisConfig.class, DruidDataSourceConfig.class})
  14. // 需要加事务,防止各用例间相互影响
  15. @Transactional
  16. public class TextbookMapperTest {
  17. @Autowired
  18. private TextbookMapper textbookMapper;
  19. @Before
  20. public void setUp() throws Exception {
  21. }
  22. @Test
  23. public void testSelectByPrimaryKey() {
  24. Textbook textbook = textbookMapper.selectByPrimaryKey(1);
  25. String expected = "《高等数学》";
  26. String actual = textbook.getName();
  27. assertEquals(expected, actual);
  28. }
  29. }

对于关系型数据库,除了单表操作外,表间关系一般可以归结为三种情况:一对一、一对多和多对多。

一对一

课程 Course 和教科书 Textbook 是一对一的关系

插入:

  1. /**
  2. * 一对一插入
  3. * 当依赖的Textbook不存在时,需要先将数据插入Textbook,然后再插入Course
  4. * @param course
  5. * @return
  6. */
  7. @Override
  8. public int intsertCourseTextbook(Course course) {
  9. int result = 0;
  10. try {
  11. Textbook textbook = course.getTextbook();
  12. textbookMapper.insert(textbook);
  13. // 关键在于 textbook 插入后获取 id
  14. course.setTextbookId(textbook.getId());
  15. courseMapper.insert(course);
  16. result = 1;
  17. } catch (Exception e) {
  18. logger.error("插入失败:{}", e.toString());
  19. }
  20. return result;
  21. }

xml 配置中关键是 <selectKey> 的配置,插入后返回 id :

  1. <insert id="insert" parameterType="com.codelib.springboot.sample.mybatis.pojo.Textbook">
  2. <!--
  3. WARNING - @mbg.generated
  4. This element is automatically generated by MyBatis Generator, do not modify.
  5. -->
  6. <selectKey keyProperty="id" resultType="int" order="AFTER">
  7. SELECT LAST_INSERT_ID() AS ID
  8. </selectKey>
  9. insert into textbooks (id, name)
  10. values (#{id,jdbcType=INTEGER}, #{name,jdbcType=VARCHAR})
  11. </insert>

查询:

关键是 <association> 标签的配置

  1. <resultMap id="CourseTextbookResultMap" type="course">
  2. <id column="id" javaType="java.lang.Integer" jdbcType="INTEGER" property="id" />
  3. <result column="name" javaType="java.lang.String" jdbcType="VARCHAR" property="name" />
  4. <result column="grade_id" javaType="java.lang.Integer" jdbcType="INTEGER" property="gradeId" />
  5. <result column="textbook_id" javaType="java.lang.Integer" jdbcType="INTEGER" property="textbookId" />
  6. <association column="textbook_id" javaType="textbook" property="textbook" resultMap="TextbookResult" />
  7. </resultMap>
  8. <resultMap id="TextbookResult" type="textbook">
  9. <id column="textbook_id" javaType="java.lang.Integer" jdbcType="INTEGER" property="id" />
  10. <result column="textbook_name" javaType="java.lang.String" jdbcType="VARCHAR" property="name" />
  11. </resultMap>
  12. <select id="selectCourseTextbookResultMapByPrimaryKey" parameterType="java.lang.Integer" resultMap="CourseTextbookResultMap">
  13. select a.id, a.name, a.grade_id, a.textbook_id, b.id textbook_id, b.name textbook_name
  14. from courses a
  15. left join textbooks b on b.id=a.textbook_id
  16. where a.id=#{id,jdbcType=INTEGER}
  17. </select>
  1. @Test
  2. public void testSelectCourseTextbookResultMapByPrimaryKey() {
  3. Course course = coursemapper.selectCourseTextbookResultMapByPrimaryKey(1);
  4. String expected = "《高等数学》";
  5. String actual = course.getTextbook().getName();
  6. assertEquals(expected, actual);
  7. }

对于关联查询,如果存在同名的字段,需要给字段取别名,以区分开来

一对多

关键在于 <collection> 标签的配置,多的一则是用 List 。

Course.java:

  1. ...
  2. // 一对一
  3. private Textbook textbook;
  4. // 一对多
  5. private List<Student> students = new ArrayList<>();
  6. ...
  1. <resultMap id="CourseStudentsResultMap" type="course">
  2. <id column="id" javaType="java.lang.Integer" jdbcType="INTEGER" property="id" />
  3. <result column="name" javaType="java.lang.String" jdbcType="VARCHAR" property="name" />
  4. <result column="grade_id" javaType="java.lang.Integer" jdbcType="INTEGER" property="gradeId" />
  5. <result column="textbook_id" javaType="java.lang.Integer" jdbcType="INTEGER" property="textbookId" />
  6. <collection ofType="student" property="students" resultMap="StudentResult" />
  7. </resultMap>
  8. <resultMap id="StudentResult" type="student">
  9. <id column="student_id" javaType="java.lang.Integer" jdbcType="INTEGER" property="id" />
  10. <result column="student_name" javaType="java.lang.String" jdbcType="VARCHAR" property="name" />
  11. </resultMap>
  12. <select id="selectCourseStudentsResultMapByPrimaryKey" parameterType="int" resultMap="CourseStudentsResultMap">
  13. select
  14. a.id, a.name, a.grade_id, a.textbook_id, c.id student_id, c.name student_name
  15. from courses a
  16. left join student_courses b on a.id=b.course_id
  17. left join students c on b.student_id=c.id
  18. where a.id = #{id,jdbcType=INTEGER}
  19. </select>
  1. @Test
  2. public void selectCourseStudentsResultMapByPrimaryKey() {
  3. Course course = coursemapper.selectCourseStudentsResultMapByPrimaryKey(1);
  4. int actual = course.getStudents().size();
  5. int expected = 3;
  6. assertEquals(expected, actual);
  7. }

多对多

这一点跟 Hibernate 不太一样,需要为关联表建实体类。其它的就跟一对多差不多了,只需要将一对多的思想转换一下即可。

  1. /**
  2. * 多对多
  3. * 对于 Student 和 Coureses 都已经存在,只是建立关联关系的情况
  4. * 只需要往 student_courses 表插入数据即可
  5. */
  6. @Override
  7. public int insertStudentCourses(Student student) {
  8. int result = 0;
  9. try {
  10. int studentId = student.getId();
  11. List<Course> courses = student.getCourses();
  12. for (Course course : courses) {
  13. StudentCourseKey studentCourseKey = new StudentCourseKey(course.getId(), studentId);
  14. studentCourseMapper.insert(studentCourseKey);
  15. result ++;
  16. }
  17. } catch (Exception e) {
  18. logger.error("插入失败:{}", e.toString());
  19. }
  20. return result;
  21. }

总结

对于 MyBatis 的使用关键是 sql 的编写。先从单表开始,了解 Example 类的用法,对理解 xml 映射及配置很有帮助。对于一对一、一对多、多对多的用法,关键是思维的转换,先理解清楚一对一关系的用法,另外两个就迎刃而解了。

源码是最好的文档

欢迎指出不足

参考

MyBatis 从入门到熟悉.md的更多相关文章

  1. Java-MyBatis:MyBatis 3 入门

    ylbtech-Java-MyBatis:MyBatis 3 入门 1.返回顶部 1. 入门 安装 要使用 MyBatis, 只需将 mybatis-x.x.x.jar 文件置于 classpath ...

  2. MyBatis学习总结(一)——MyBatis快速入门

    一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...

  3. MyBatis快速入门

    一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...

  4. MyBatis学习总结(一)——MyBatis快速入门(转载)

    本文转载自http://www.cnblogs.com/jpf-java/p/6013537.html MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了 ...

  5. MyBatis入门学习教程-MyBatis快速入门

    一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...

  6. MyBatis学习总结(一)——MyBatis快速入门

    一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC代码和参数的手工设置以及对结果集的检索封装.MyBatis可以 ...

  7. 【转】MyBatis学习总结(一)——MyBatis快速入门

    [转]MyBatis学习总结(一)——MyBatis快速入门 一.Mybatis介绍 MyBatis是一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架.MyBatis消除了几乎所有的JDBC ...

  8. mybatis快速入门(六)

    前面mybatis的入门程序基本上都写完了,就看大家的灵活运用了,今天来吧前面的整合一下封装一个公共的BaseDao 只需要把前面的改造下然后创建一个BaseDao的接口,其它的继承BaseDao接口 ...

  9. MyBatis学习总结-MyBatis快速入门的系列教程

    MyBatis学习总结-MyBatis快速入门的系列教程 [MyBatis]MyBatis 使用教程 [MyBatis]MyBatis XML配置 [MyBatis]MyBatis XML映射文件 [ ...

随机推荐

  1. express 创建node服务器

    var express = require('express'); var app = new express(); app.listen(3000); app.get('/',function(re ...

  2. STL 容器(vector 和 list )

    1.这个容器的知识点比较杂 迭代器的理解: 1.erase()函数的返回值,它的迭代器在循环遍历中的奇特之处: #define _CRT_SECURE_NO_WARNINGS #include < ...

  3. poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分, dinic, isap

    poj 2391 Ombrophobic Bovines, 最大流, 拆点, 二分 dinic /* * Author: yew1eb * Created Time: 2014年10月31日 星期五 ...

  4. sublime for mac 注册码

    https://www.jianshu.com/p/04e1b65dd2c0https://fatesinger.com/100121

  5. mysql-shell的安装和使用

    mysql-shell是一个高级的mysql命令行工具.它直接两种模式(交互式&批处理式)三种语言(javascript\python\sql) 1.下载地址 https://dev.mysq ...

  6. 使用NoSQL Manager for MongoDBclient连接mongodb

    1.安装NoSQL Manager for MongoDB 下载地址:http://www.mongodbmanager.com/download 2.打开client,选server-new mon ...

  7. atitit.信息系统方案规划 p71.doc

    [信息系统方案规划 ] 版本 v2 2015-7-1 变更记录 日期 修改人 版本 变更事由 说明 2015.07 艾龙 1.0 初创 2015.07 艾龙 2.0 添加接口 1. 业务功能与流程设计 ...

  8. [iOS]delegate和protocol

    转自:http://haoxiang.org/2011/08/ios-delegate-and-protocol/ 今天上班和同事讨论工程怎么组织的时候涉及到这个话题.iOS开发上对delegate使 ...

  9. Springboot client 常用配置详解

    Property name Description Default value spring.boot.admin.client.enabled Enables the Spring Boot Adm ...

  10. C# ZPL II 命令打印标签

    public class BarPrinter { public static byte[] ZPLPrinter(string p_title = "", string p_sp ...