http://blog.csdn.net/yerenyuan_pku/article/details/71699515

MyBatis框架的架构

MyBatis框架的架构如下图: 

下面作简要概述:

  1. SqlMapConfig.xml,此文件作为mybatis的全局配置文件,配置了mybatis的运行环境等信息。mapper.xml文件即sql映射文件,文件中配置了操作数据库的sql语句,此文件需要在SqlMapConfig.xml中加载。
  2. 通过mybatis环境等配置信息构造SqlSessionFactory(即会话工厂)。
  3. 由会话工厂创建sqlSession即会话,操作数据库需要通过sqlSession进行。
  4. mybatis底层自定义了Executor执行器接口操作数据库,Executor接口有两个实现,一个是基本执行器、一个是缓存执行器。
  5. MappedStatement也是mybatis一个底层封装对象,它包装了mybatis配置信息及sql映射信息等。mapper.xml文件中一个sql对应一个MappedStatement对象,sql的id即是MappedStatement的id
  6. MappedStatement对sql执行输入参数进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql前将输入的java对象映射至sql中,输入参数映射就是JDBC编程中对preparedStatement设置参数。
  7. MappedStatement对sql执行输出结果进行定义,包括HashMap、基本类型、pojo,Executor通过MappedStatement在执行sql后将输出结果映射至java对象中,输出结果映射过程相当于JDBC编程中对结果的解析处理过程。

MyBatis入门

mybatis下载

mybaits的代码由github.com管理,地址:https://github.com/mybatis/mybatis-3/releases。大家可从该地址下载mybatis最新框架。 
本人下载的是mybatis-3.2.7,其目录结构为: 

开发需求

现在我们明确需求,即实现以下功能:

  1. 根据用户id查询一个用户信息
  2. 根据用户名称模糊查询用户信息列表
  3. 添加用户
  4. 更新用户
  5. 删除用户

MyBatis入门程序配置

【第一步】,使用Eclipse创建一个普通的Java工程,例如mybatis-day01。 
【第二步】,加入Jar包。工程所需加入的Jar包有mybatis核心包、依赖包和MySQL数据驱动包。如下: 
 
【第三步】,在classpath下创建日志记录文件——log4j.properties。我们可在mybatis-day01工程下新建一个config源码包,并在该源码包下创建一个日志记录文件——log4j.properties 
 
log4j.properties文件的内容如下:

  1. # Global logging configuration
  2. log4j.rootLogger=DEBUG, stdout
  3. # Console output...
  4. log4j.appender.stdout=org.apache.log4j.ConsoleAppender
  5. log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
  6. log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

mybatis默认使用log4j作为输出日志信息。 
【第四步】,在classpath下创建SqlMapConfig.xml文件。我们同样可在config源码包下创建该文件 
 
其内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE configuration
  3. PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-config.dtd">
  5. <configuration>
  6. <!-- 和spring整合后environments配置将废除 -->
  7. <environments default="development">
  8. <environment id="development">
  9. <!-- 使用jdbc事务管理 -->
  10. <transactionManager type="JDBC" />
  11. <!-- 数据库连接池 -->
  12. <dataSource type="POOLED">
  13. <property name="driver" value="com.mysql.jdbc.Driver" />
  14. <property name="url" value="jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8" />
  15. <property name="username" value="root" />
  16. <property name="password" value="yezi" />
  17. </dataSource>
  18. </environment>
  19. </environments>
  20. </configuration>

SqlMapConfig.xml是mybatis的核心配置文件,以上文件的配置内容为数据源、事务管理。 
注意:等后面mybatis和Spring两个框架整合之后,environments的配置将被废除。 
【第五步】,创建一个po类——User.java。我们可在src目录下新建一个名为cn.itheima.mybatis.po的包,并在该包下创建一个po类——User.java 
 
po类作为mybatis进行sql映射使用,po类通常与数据库表对应,User.java文件的内容如下:

  1. public class User {
  2. private int id;
  3. private String username;// 用户姓名
  4. private String sex;// 性别
  5. private Date birthday;// 生日
  6. private String address;// 地址
  7. public int getId() {
  8. return id;
  9. }
  10. public void setId(int id) {
  11. this.id = id;
  12. }
  13. public String getUsername() {
  14. return username;
  15. }
  16. public void setUsername(String username) {
  17. this.username = username;
  18. }
  19. public String getSex() {
  20. return sex;
  21. }
  22. public void setSex(String sex) {
  23. this.sex = sex;
  24. }
  25. public Date getBirthday() {
  26. return birthday;
  27. }
  28. public void setBirthday(Date birthday) {
  29. this.birthday = birthday;
  30. }
  31. public String getAddress() {
  32. return address;
  33. }
  34. public void setAddress(String address) {
  35. this.address = address;
  36. }
  37. @Override
  38. public String toString() {
  39. return "User [id=" + id + ", username=" + username + ", sex=" + sex + ", birthday=" + birthday + ", address="
  40. + address + "]";
  41. }
  42. }

【第六步】,在classpath下的sqlmap目录下创建sql映射文件user.xml 
 
user.xml文件的内容如下:

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE mapper
  3. PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  4. "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
  5. <mapper namespace="test">
  6. </mapper>

namespace:即命名空间,其用于隔离sql语句(即不同sql映射文件中的两个相同id的sql语句如何来区分),这是当前的作用,后面会讲另一层非常重要的作用。 
【第七步】,加载映射文件。mybatis框架需要加载映射文件,将user.xml添加在SqlMapConfig.xml中,如下: 

故须在SqlMapConfig.xml配置文件中添加如下配置信息:

  1. <mappers>
  2. <!-- resource是基于classpath来查找的 -->
  3. <mapper resource="sqlmap/user.xml"/>
  4. </mappers>

MyBatis入门程序测试——根据id查询用户信息

在user.xml映射文件中添加如下配置:

  1. <!-- 根据id获取用户信息 -->
  2. <select id="getUserById" parameterType="int" resultType="cn.itheima.mybatis.po.User">
  3. select * from user where id=#{id};
  4. </select>
  • parameterType:查询参数的数据类型,即定义输入到sql中的映射类型。
  • resultType:查询结果的数据类型,如果是pojo则应该给出全路径。
  • #{id}表示使用PreparedStatement设置占位符号并将输入变量id传到sql中。说白点,#{}作用就是占位符,相当于JDBC中的?

接着在src目录下新建一个名为cn.itheima.mybatis.first的包,并在该包下创建一个MybatisTest单元测试类,紧接着在该类中编写如下一个但单元测试方法:

  1. public class MybatisTest {
  2. @Test
  3. public void getUserById() throws IOException {
  4. // 第一步,创建SqlSessionFactoryBuilder对象
  5. SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
  6. // 第二步,加载配置文件
  7. InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
  8. // 第三步,创建SqlSessionFactory对象
  9. SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
  10. // 第四步,创建SqlSession对象
  11. SqlSession sqlSession = sqlSessionFactory.openSession();
  12. // 第五步,使用SqlSession对象执行查询,得到User对象
  13. // 第一个参数:执行查询的StatementId
  14. User user = sqlSession.selectOne("getUserById", 10);
  15. // 第六步,打印结果
  16. System.out.println(user);
  17. // 第七步,释放资源,每一个sqlSession就是一个连接
  18. sqlSession.close();
  19. }
  20. }

以上完成的需求就是根据id查询用户信息。一般来讲工厂对象一般在实际开发是单例的,并不需要频繁地创建,故getUserById()方法可优化为:

  1. public class MybatisTest {
  2. private SqlSessionFactory sqlSessionFactory = null; // 工厂对象一般在我们的系统中是单例的
  3. @Before
  4. public void init() throws IOException {
  5. // 第一步,创建SqlSessionFactoryBuilder对象
  6. SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
  7. // 第二步,加载配置文件
  8. InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
  9. // 第三步,创建SqlSessionFactory对象
  10. sqlSessionFactory = sqlSessionFactoryBuilder.build(inputStream);
  11. }
  12. @Test
  13. public void getUserById() throws IOException {
  14. // 第四步,创建SqlSession对象
  15. SqlSession sqlSession = sqlSessionFactory.openSession();
  16. // 第五步,使用SqlSession对象执行查询,得到User对象
  17. // 第一个参数:执行查询的StatementId
  18. User user = sqlSession.selectOne("getUserById", 10);
  19. // 第六步,打印结果
  20. System.out.println(user);
  21. // 第七步,释放资源,每一个sqlSession就是一个连接
  22. sqlSession.close();
  23. }
  24. }
  • 1

根据用户名称模糊查询用户信息列表

现在我就来完成第二个需求——根据用户名称模糊查询用户信息列表。 
一开始我在user.xml映射文件中添加如下配置:

  1. <select id="getUserByName" parameterType="string" resultType="cn.itheima.mybatis.po.User">
  2. SELECT * FROM `user` WHERE username LIKE #{username}
  3. </select>
  • 1
  • 2
  • 3
  • 1
  • 2
  • 3

如果查询结果返回的是List集合,那么resultType只需要设置为List集合中的一个元素的数据类型即可。 
接着在MybatisTest单元测试类编写如下单元测试方法:

  1. @Test
  2. public void getUserByName() {
  3. // 创建一个SqlSession对象
  4. SqlSession sqlSession = sqlSessionFactory.openSession();
  5. // 执行查询
  6. List<User> list = sqlSession.selectList("getUserByName", "%张%");
  7. for (User user : list) {
  8. System.out.println(user);
  9. }
  10. // 释放资源
  11. sqlSession.close();
  12. }
  • 1

运行以上方法,Eclipse控制台打印如下: 

实际开发中建议使用#{}占位符这种方式,因为这样可以防止SQL注入。除了以上这种方式外,在此我还介绍第二种方式,即在user.xml映射文件中添加如下配置:

  1. <select id="getUserByName" parameterType="string" resultType="cn.itheima.mybatis.po.User">
  2. SELECT * FROM `user` WHERE username LIKE '%${value}%'
  3. </select>

${value}表示使用参数将${value}替换,做字符串的拼接,${}为字符串拼接指令。注意:如果是取简单数据类型的参数,括号中的值必须为value。 
如此一来,MybatisTest单元测试类中的getUserByName()方法应修改为:

  1. @Test
  2. public void getUserByName() {
  3. // 创建一个SqlSession对象
  4. SqlSession sqlSession = sqlSessionFactory.openSession();
  5. // 执行查询
  6. List<User> list = sqlSession.selectList("getUserByName", "张");
  7. for (User user : list) {
  8. System.out.println(user);
  9. }
  10. // 释放资源
  11. sqlSession.close();
  12. }
  • 1

运行以上方法,Eclipse控制台打印如下: 

很明显这种方式在实际开发中是不建议使用的,因为无法防止SQL注入。

总结

#{}和${}

#{}:表示一个占位符号,可以很好地去避免sql注入。其原理是将占位符位置的整个参数和sql语句两部分提交给数据库,数据库去执行sql语句,去表中匹配所有的记录是否和整个参数是否一致。 
#{}要获取输入参数的值:

  • 如果输入参数是简单数据类型,则#{}中可以写value或其它名称。
  • 如果输入参数是pojo对象类型,则#{}可通过OGNL方式去获取,表达式就是属性.属性.属性....方式。

${}表示一个sql拼接符号,其原理是在向数据库发出sql之前去拼接好sql再提交给数据库执行。 
${}要获取输入参数的值:

  • 如果输入参数是简单数据类型,则${}中只能写value。
  • 如果输入参数是pojo对象类型,则${}可通过OGNL方式去获取,表达式就是属性.属性.属性....方式。

一般情况下建议使用#{},特殊情况下必须要用${},比如:

  1. 动态拼接sql中动态组成排序字段,要通过${}将排序字段传入sql中。
  2. 动态拼接sql中动态组成表名,要通过${}将表名传入sql中。

parameterType和resultType

parameterType:指定输入参数类型,mybatis通过ognl从输入对象中获取参数值拼接在sql中。 
resultType:指定输出结果类型,mybatis将sql查询结果的一行记录数据映射为resultType指定类型的对象。

selectOne()和selectList()方法

selectOne查询一条记录,如果使用selectOne查询多条记录则抛出异常: 

selectList可以查询一条或多条记录。

添加用户

现在我就来完成第三个需求——添加用户。首先在user.xml映射文件中添加如下配置:

  1. <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
  2. INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
  3. </insert>

如果输入参数是pojo,那么#{}中的名称就是pojo类中的属性(用到了对象图导航的思想),而不能随便写了。 
然后试着在MybatisTest单元测试类编写如下单元测试方法:

  1. @Test
  2. public void addUser() {
  3. // 创建一个SqlSession对象
  4. SqlSession sqlSession = sqlSessionFactory.openSession();
  5. // 创建User对象
  6. User user = new User();
  7. user.setUsername("小乔");
  8. user.setBirthday(new Date());
  9. user.setSex("2");
  10. user.setAddress("上海");
  11. // 插入用户
  12. sqlSession.insert("insertUser", user);
  13. // 释放资源
  14. sqlSession.close();
  15. }

运行以上方法,发现Eclipse控制台中打印: 

虽然发出了sql语句,但是事务并没将其提交,而是回滚了。故User对象是无法插入到数据库user表中的。所以addUser()单元测试方法应修改为:

  1. @Test
  2. public void addUser() {
  3. // 创建一个SqlSession对象
  4. SqlSession sqlSession = sqlSessionFactory.openSession();
  5. // 创建User对象
  6. User user = new User();
  7. user.setUsername("小乔");
  8. user.setBirthday(new Date());
  9. user.setSex("2");
  10. user.setAddress("上海");
  11. // 插入用户
  12. sqlSession.insert("insertUser", user);
  13. // 提交事务
  14. sqlSession.commit();
  15. // 释放资源
  16. sqlSession.close();
  17. }
  • 1

运行以上方法,Eclipse控制台会打印: 

事务已提交,可发现数据库user表中插入一条记录。

MySQL自增主键返回

现在有这样一个需求:想要得到MySQL数据库给我们生成的主键id,即获取主键。那如何实现这个需求呢?这里要用到MySQL数据库中的一个函数:

  • LAST_INSERT_ID():返回auto_increment自增列新记录id值。该函数是在当前事务下取到你最后生成的id值,而我们应知道查询操作是没有开启事务的,增删改操作是需要开启事务的。

如此一来,需要将user.xml映射文件中的如下配置:

  1. <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
  2. INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
  3. </insert>

修改为(即添加selectKey实现将主键返回):

  1. <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
  2. <selectKey keyProperty="id" resultType="int" order="AFTER">
  3. SELECT LAST_INSERT_ID()
  4. </selectKey>
  5. INSERT INTO `user` (username,birthday,sex,address) VALUES (#{username},#{birthday},#{sex},#{address})
  6. </insert>
  • 1
  • keyProperty:返回的主键存储在pojo中的哪个属性(即其对应pojo的主键属性)。获取主键,实际上是将主键取出来之后封装到了pojo的主键属性当中。
  • resultType:返回的主键是什么类型(即其对应pojo的主键的数据类型)。
  • order:selectKey的执行顺序,是相对于insert语句来说的,由于mysql的自增原理,执行完insert语句之后才将主键生成,所以这里selectKey的执行顺序为AFTER。

最后将addUser()单元测试方法应修改为:

  1. @Test
  2. public void addUser() {
  3. // 创建一个SqlSession对象
  4. SqlSession sqlSession = sqlSessionFactory.openSession();
  5. // 创建User对象
  6. User user = new User();
  7. user.setUsername("大乔");
  8. user.setBirthday(new Date());
  9. user.setSex("2");
  10. user.setAddress("上海");
  11. // 插入用户
  12. sqlSession.insert("insertUser", user);
  13. System.out.println(user.getId());
  14. // 提交事务
  15. sqlSession.commit();
  16. // 释放资源
  17. sqlSession.close();
  18. }

运行以上方法,Eclipse控制台会打印: 

MySql使用uuid实现主键

使用uuid实现主键,需要增加通过select uuid()语句得到uuid值作为主键。所以需要将user.xml映射文件中id为insertUser的Statement改置为:

  1. <insert id="insertUser" parameterType="cn.itheima.mybatis.po.User">
  2. <selectKey resultType="java.lang.String" order="BEFORE"
  3. keyProperty="id">
  4. select uuid()
  5. </selectKey>
  6. insert into user(id,username,birthday,sex,address)
  7. values(#{id},#{username},#{birthday},#{sex},#{address})
  8. </insert>

因为是使用uuid做主键,所以应该先生成主键然后再插入数据,此时order属性的值应是BEFORE。

删除用户

现在我就来完成第四个需求——删除用户。首先在user.xml映射文件中添加如下配置:

  1. <!-- 删除用户 -->
  2. <delete id="deleteUser" parameterType="int">
  3. DELETE FROM `user` WHERE id=#{id1}
  4. </delete>
  • 1

然后在MybatisTest单元测试类编写如下单元测试方法:

  1. @Test
  2. public void deleteUser() {
  3. // 创建一个SqlSession对象
  4. SqlSession sqlSession = sqlSessionFactory.openSession();
  5. // 删除用户
  6. sqlSession.delete("deleteUser", 29);
  7. // 提交事务
  8. sqlSession.commit();
  9. // 释放资源
  10. sqlSession.close();
  11. }
  • 1
  • 2

更新用户

现在我就来完成第五个需求——修改用户信息。首先在user.xml映射文件中添加如下配置:

  1. <!-- 修改用户信息 -->
  2. <update id="updateUser" parameterType="cn.itheima.mybatis.po.User">
  3. UPDATE `user` set username=#{username} WHERE id=#{id}
  4. </update>

然后在MybatisTest单元测试类编写如下单元测试方法:

  1. @Test
  2. public void updateUser() {
  3. // 创建一个SqlSession对象
  4. SqlSession sqlSession = sqlSessionFactory.openSession();
  5. // 创建一个User对象
  6. User user = new User();
  7. user.setUsername("张角");
  8. user.setId(10);
  9. // 更新用户
  10. sqlSession.update("updateUser", user);
  11. // 提交事务
  12. sqlSession.commit();
  13. sqlSession.close();
  14. }

MyBatis解决了JDBC编程的问题

还记得MyBatis框架的学习(一)——MyBatis介绍一文中使用JDBC编程所带来的问题吗?现在使用MyBatis这个框架就可以解决JDBC编程所带来的这些问题。

  1. 数据库连接创建、释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库连接池可解决此问题。 
    解决:在SqlMapConfig.xml中配置数据连接池,使用连接池管理数据库连接。
  2. Sql语句写在代码中造成代码不易维护,实际应用sql变化的可能较大,sql变动需要改变java代码。 
    解决:将Sql语句配置在XXXXmapper.xml文件中与java代码分离。
  3. 向sql语句传参数麻烦,因为sql语句的where条件不一定,可能多也可能少,占位符需要和参数一一对应。 
    解决: MyBatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
  4. 对结果集解析麻烦,sql变化导致解析代码变化,且解析前需要遍历,如果能将数据库记录封装成pojo对象解析比较方便。 
    解决: MyBatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。

MyBatis与Hibernate的不同之处

MyBatis和Hibernate不同,它不完全是一个ORM框架,因为MyBatis需要程序员自己编写Sql语句,不过MyBatis可以通过XML或注解方式灵活配置要运行的sql语句,并将java对象和sql语句映射生成最终执行的sql,最后将sql执行的结果再映射生成java对象。 
MyBatis学习门槛低,简单易学,程序员直接编写原生态sql,可严格控制sql执行性能,灵活度高,非常适合对关系数据模型要求不高的软件开发,例如互联网软件、企业运营类软件等,因为这类软件需求变化频繁,一但需求变化要求成果输出迅速。但是灵活的前提是MyBatis无法做到数据库无关性,如果需要实现支持多种数据库的软件则需要自定义多套sql映射文件,工作量大。 
Hibernate对象/关系映射能力强,数据库无关性好,对于关系模型要求高的软件(例如需求固定的定制化软件)如果用Hibernate开发可以节省很多代码,提高效率。但是Hibernate的学习门槛高,要精通门槛更高,而且怎么设计O/R映射,在性能和对象模型之间如何权衡,以及怎样用好Hibernate需要具有很强的经验和能力才行。 
总之,按照用户的需求在有限的资源环境下只要能做出维护性、扩展性良好的软件架构都是好架构,所以框架只有适合才是最好。

我个人总结的MyBatis与Hibernate这两个框架的不同之处:

  • MyBatis学习成本低,入门门槛低。MyBatis需要程序员自己写sql,对sql修改和优化就比较灵活。MyBatis是不完全的ORM框架,MyBatis需要程序员编写sql,但是MyBatis也存在映射(输入映射、输出映射)适用场景:需求变化较快的项目开发,比如互联网项目、电商。
  • Hibernate学习成本高,入门门槛高,Hibernate是ORM框架,不需要程序员编写sql,自动根据对象映射生成sql。适用场景:需求固定的中小型项目,如OA系统、ERP系统。

企业在技术选型上应考虑各个技术框架的特点去进行选型,企业要根据人力、物力等资源去衡量,以节省成本利润最大化为目标进行选型。 
至此,我们就算入门MyBatis了。读者如需查看源码,可参考MyBatis框架的学习(二)——MyBatis架构与入门

(转)MyBatis框架的学习(二)——MyBatis架构与入门的更多相关文章

  1. (转)MyBatis框架的学习(七)——MyBatis逆向工程自动生成代码

    http://blog.csdn.net/yerenyuan_pku/article/details/71909325 什么是逆向工程 MyBatis的一个主要的特点就是需要程序员自己编写sql,那么 ...

  2. (转)MyBatis框架的学习(六)——MyBatis整合Spring

    http://blog.csdn.net/yerenyuan_pku/article/details/71904315 本文将手把手教你如何使用MyBatis整合Spring,这儿,我本人使用的MyB ...

  3. (转)MyBatis框架的学习(一)——MyBatis介绍

    http://blog.csdn.net/yerenyuan_pku/article/details/71699343 MyBatis介绍 MyBatis本是apache的一个开源项目iBatis,2 ...

  4. mybatis源码学习(二)--mybatis+spring源码学习

    这篇笔记主要来就,mybatis是如何利用spring的扩展点来实现和spring的整合 1.mybatis和spring整合之后,我们就不需要使用sqlSession.selectOne()这种方式 ...

  5. (转)MyBatis框架的学习(三)——Dao层开发方法

    http://blog.csdn.net/yerenyuan_pku/article/details/71700957 使用MyBatis开发Dao层,通常有两个方法,即原始Dao开发方法和Mappe ...

  6. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(1 构建目录环境和依赖)

    引言:在用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建一   的基础上 继续进行项目搭建 该部分的主要目的是测通MyBatis 及Spring-dao ...

  7. (转)MyBatis框架的学习(五)——一对一关联映射和一对多关联映射

    http://blog.csdn.net/yerenyuan_pku/article/details/71894172 在实际开发中我们不可能只是对单表进行操作,必然要操作多表,本文就来讲解多表操作中 ...

  8. 用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(2 配置spring-dao和测试)

    用IntelliJ IDEA 开发Spring+SpringMVC+Mybatis框架 分步搭建二:配置MyBatis 并测试(1 搭建目录环境和依赖) 四:在\resources\spring 下面 ...

  9. (转)MyBatis框架的学习(四)——Mapper.xml文件中的输入和输出映射以及动态sql

    http://blog.csdn.net/yerenyuan_pku/article/details/71893689 前面对MyBatis框架的学习中,我们对Mapper.xml映射文件多少有些了解 ...

随机推荐

  1. codevs-2235

    2235 机票打折 题目描述 Description .输入机票原价(3到4位的正整数,单位:元),再输入机票打折率(小数点后最多一位数字).编程计算打折后机票的实际价格(单位:元.计算结果要将个位数 ...

  2. outlook2013 解决附件大小限制

    1.先关闭outlook,然后点击"运行"-->输入"regedit" #打开注册表 2.依次打开  “HKEY_CURRENT_USER\Softwar ...

  3. mysql server安装(windows)

    1 在 https://dev.mysql.com/downloads/mysql/ 上下载mysql压缩包 2 解压,并把bin目录加入环境变量 3 初始化,完成后会在mysql根目录下生成data ...

  4. Flutter实战视频-移动电商-15.首页_商品推荐模块编写

    15.首页_商品推荐模块编写 商品推荐,我们做成可以横向滚动的 分析: 上面是标题,下面是ListView,里面是一个Column, column分三层,第一是图片,第二是价格,第三是市场价格 小细节 ...

  5. Eclipse+Maven+TestNg+ReportNg 生成测试报告

    http://blog.csdn.net/a542551042/article/details/46729585

  6. Installing cmake 2.8.8 or higher on Ubuntu 12.04 (Precise Pangolin) (转载)

    转自:http://cameo54321.blogspot.com/2014/02/installing-cmake-288-or-higher-on.html Check the version o ...

  7. Maven面试必备

    Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Depen ...

  8. bzoj 2406: 矩阵【二分+有源汇上下界可行流】

    最大值最小,所以考虑二分 |Σaij-Σbij|<=mid,所以Σbij的上下界就是(Σaij-mid,Σaij+mid) 考虑建有上下界网络,连接(s,i,Σaik-mid,Σaik+mid) ...

  9. 洛谷P3265 [JLOI2015]装备购买(线性基+高斯消元)

    传送门 不知道线性基是什么东西的可以看看蒟蒻的总结 不难看出题目讲的就是线性基 这种最小化权值的问题一般都是贪心的,就是按价值从低到高考虑每一个是否能选 据说贪心的证明得用拟阵我不会 据说这题是实数意 ...

  10. 剑指OFFER之最大子向量和(连续子数组的最大和)(九度OJ1372)

    题目描述: HZ偶尔会拿些专业问题来忽悠那些非计算机专业的同学.今天JOBDU测试组开完会后,他又发话了:在古老的一维模式识别中,常常需要计算连续子向量的最大和,当向量全为正数的时候,问题很好解决.但 ...