一、预研任务介绍和预研目标

任务介绍:

与 Hibernate 相比, MyBatis 是一个半自动化的持久层框架,以轻量级、效率高、原生代而好评如潮。虽然有在分享会上大致讲解,但是还是重新梳理成文字,方便后来人查阅。

预研目标:

编写并讲解 MyBatis 与持久层结合的 demo ,实际应用起这门新技术。

二、操作步骤

1. jar 包准备

备注:mybatis.jar是mybatis的核心,mybatis-spring是mybatis团队出品的mybatis整合spring工具包。

2.  准备工作

1 ) 在数据库(MySQL )上的 test 数据库新建如下表格并添加测试数据:

CREATE TABLE sys_employees (

  emp_id INT(11) NOT NULL AUTO_INCREMENT,

  emp_name VARCHAR(255) NULL DEFAULT NULL COMMENT '员工名称',

  emp_password VARCHAR(255) NULL DEFAULT NULL COMMENT '员工密码',

  emp_email VARCHAR(255) NULL DEFAULT NULL COMMENT '员工邮件',

  emp_desc VARCHAR(255) NULL DEFAULT NULL COMMENT '员工描述',

  emp_account VARCHAR(255) NULL DEFAULT NULL COMMENT '员工账户',

  is_sys BOOL NULL DEFAULT '0' COMMENT '是否管理员 0:否 1:是',

  is_using BOOL NULL DEFAULT '1' COMMENT '是否在职 0:否 1:是',

  PRIMARY KEY(emp_id)

)

ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;Insert into sys_employees values(null, 'jayzee', '123456', null, null, 'jayzee', 0, 1);Insert into sys_employees values(null, 'nikey', '123456', null, null, 'jayzee', 0, 1); 

2 )  新建一个简单的java项目 Pro 4 - MyBatisDemo,在其 build path 下新建一个source folder 名为 resources 专门放配置文件,在resources文件夹 下编写如下文件( generator.xml )并使用 mybatis generator 插件  [1]生成 model 类、 mapper 接口及 xml :

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration
PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN"
"http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd"> <generatorConfiguration>
<!-- classPathEntry:数据库的JDBC驱动 -->
<classPathEntry
location="/home/jayzeee/Documents/Java/Jars/mysql/mysql-connector-java-5.1.17-bin.jar" /> <context id="MySQLTables" targetRuntime="MyBatis3">
<!-- 去除自动生成的注释 -->
<commentGenerator>
<property name="suppressAllComments" value="true" />
</commentGenerator> <jdbcConnection driverClass="com.mysql.jdbc.Driver"
connectionURL="jdbc:mysql://localhost:3306/test" userId="root"
password="123456">
</jdbcConnection> <javaTypeResolver>
<property name="forceBigDecimals" value="false" />
</javaTypeResolver> <!-- targetProject:自动生成代码的位置 -->
<javaModelGenerator targetPackage="com.nikey.oa.model.Demo"
targetProject="Pro 4 - MyBatisDemo">
<property name="enableSubPackages" value="true" />
<property name="trimStrings" value="true" />
</javaModelGenerator> <sqlMapGenerator targetPackage="com.nikey.oa.mapper.Demo"
targetProject="Pro 4 - MyBatisDemo">
<property name="enableSubPackages" value="true" />
</sqlMapGenerator> <javaClientGenerator type="XMLMAPPER"
targetPackage="com.nikey.oa.mapper.Demo" targetProject="Pro 4 - MyBatisDemo">
<property name="enableSubPackages" value="true" />
</javaClientGenerator> <!-- tableName:用于自动生成代码的数据库表;domainObjectName:对应于数据库表的javaBean类名 -->
<table tableName="sys_employees" domainObjectName="Employee" /> </context> </generatorConfiguration>

3 ) 删除自动生成的 Employee-example.java 和 EmployeeMapper.java 里面的所有方法; EmployeeMapper.xml 中 <resultMap> 之后的文本全部不要(自动生成的这些东西太冗杂了,我们完全无用,自己的才是最合适的)。还有 一个建议,最好在resources下面新建一个与 src存放mapper 相同的包名把把 EmployeeMapper.xml迁移过去(后面会解释为什么这么做)。目前包结构如下:

4) 在 resources 下添加 log4j.properties ,开启 mybatis 后台信息打印,内容如下:

# Rules reminder:

# DEBUG < INFO < WARN < ERROR < FATAL

# Global logging configuration

log4j.rootLogger=DEBUG, stdout

# My logging configuration...

log4j.logger.org.apache.ibatis.logging.commons.JakartaCommonsLoggingImpl=stdout

## Console output...

log4j.appender.stdout=org.apache.log4j.ConsoleAppender

log4j.appender.stdout.layout=org.apache.log4j.PatternLayout

log4j.appender.stdout.layout.ConversionPattern=%5p %d %C: %m%n

3. 整合 Spring

1) resources 下新建 spring 文件夹,并新建 applicationContext.xml ,内容如下:

<?xml version="1.0" encoding="UTF-8"?>
<!--
Copyright 2013 Nikey
Author Jayzee
Created 2013-08-04
--> <beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd"> <!-- 启用autowire -->
<context:annotation-config /> <!-- 启用spring注解扫描并指定包所在的位置 -->
<context:component-scan base-package="*" /> <!--配置apache dbcp数据源 -->
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="com.mysql.jdbc.Driver" />
<property name="url"
value="jdbc:mysql://localhost:3306/test?useUnicode=true&amp;characterEncoding=utf8" />
<property name="username" value="root" />
<property name="password" value="123456" />
<!-- 连接池启动时的初始值 -->
<property name="initialSize" value="7" />
<!-- 连接池的最大值 -->
<property name="maxActive" value="20" />
<!-- 最大空闲值.当经过一个高峰时间后,连接池可以慢慢将已经用不到的连接慢慢释放一部分,一直减少到maxIdle为止 -->
<property name="maxIdle" value="7" />
<!-- 最小空闲值.当空闲的连接数少于阀值时,连接池就会预申请去一些连接,以免洪峰来时来不及申请 -->
<property name="minIdle" value="2" />
</bean> <!-- 使用事务管理器管理数据源 -->
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource" />
</bean> <!-- 启用事务注解,使用@Transactional注解 -->
<tx:annotation-driven transaction-manager="transactionManager"/> <!-- 定义mybatis的sqlSessionFactory -->
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<!-- 以每个类的类名作为该类的别名,如Employee等同于com.nikey.oa.model.Demo.Employee -->
<property name="typeAliasesPackage" value="com.nikey.oa.model" />
<!--configLocation属性指定mybatis的核心配置文件-->
<property name="configLocation" value="classpath:mybatis/configuration.xml"/>
</bean> <!-- sqlsessiontemplate模板,主要用于测试 -->
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean> <!-- 扫描mybatis的mappers并让他们自动注入,
  为什么上面建议放配置文件的包名与放接口的包名一致,是因为这个扫描器会把xml和interface一起扫描,并将xml的内容作为interface的实现类 -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.nikey.oa.mapper" />
</bean>
</beans>

2) mybatis核心配置文件配置

<?xml version="1.0" encoding="utf8"?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd"> <configuration> <!-- 配置全局设置,参照API -->
<settings>
<!-- 开启batch -->
<setting name="defaultExecutorType" value="BATCH" />
</settings> <!-- 配置别名,已在spring配置,无需重复配置 -->
<!-- <typeAliases>
<typeAlias alias="Employee" type="com.nikey.oa.model.Employee"/>
</typeAliases> --> <!-- 由于已在spring配置文件里扫描mappper,无需重复配置 -->
<!-- <mappers>
<mapper resource="classpath:com/nikey/oa/mapper/Demo/EmployeeMapper.xml"/>
</mappers> --> <!-- 添加对一些特殊类型的处理,详情参照API -->
<typeHandlers>
<typeHandler handler="org.apache.ibatis.type.BooleanTypeHandler" javaType="Boolean" jdbcType="BIT"/>
<typeHandler handler="org.apache.ibatis.type.BlobTypeHandler" javaType="byte[]" jdbcType="BLOB"/>
</typeHandlers> </configuration>

3) mybatis的核心,mapper(即dao)的讲解以及使用

首先,打开EmployeeMapper.java,修改内容如下:

package com.nikey.oa.mapper.Demo;

import com.nikey.oa.model.Demo.Employee;

/**
* @author jayzeee
*
*/
public interface EmployeeMapper {/**
* @param employee
* @return 根据查询返回一个雇员
*/
Employee getAnEmployee(Employee employee); }

其次,修改EmployeeMapper.xml,修改内容如下:

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd" >
<mapper namespace="com.nikey.oa.mapper.Demo.EmployeeMapper" > <!-- id表示主键,result表示普通字段,column与数据库字段名对应,property与javabean的属性对应,type是javabean名字,其实我们这里我们已经使用了别名,
它的全名是com.nikey.oa.model.Demo.Employee -->
<resultMap id="BaseResultMap" type="Employee" >
<id column="emp_id" property="empId" jdbcType="INTEGER" />
<result column="emp_name" property="empName" jdbcType="VARCHAR" />
<result column="emp_password" property="empPassword" jdbcType="VARCHAR" />
<result column="emp_email" property="empEmail" jdbcType="VARCHAR" />
<result column="emp_desc" property="empDesc" jdbcType="VARCHAR" />
<result column="emp_account" property="empAccount" jdbcType="VARCHAR" />
<result column="is_sys" property="isSys" jdbcType="BIT" />
<result column="is_using" property="isUsing" jdbcType="BIT" />
</resultMap> <!-- sql块,方便重用 -->
<sql id="employee">
E.emp_id, E.emp_name, E.emp_password, E.emp_email, E.emp_desc, E.emp_account, E.is_sys, E.is_using
</sql> <!-- id与方法同名,parameterType表示传进来的参数(可以不写让mybatis自动判断),resultmap表示返回的结果集,
我们可以自己灵活组织结果集,学mybatis实际就是在写sql和组织resultmap -->
<select id="getAnEmployee" parameterType="Employee" resultMap="BaseResultMap">
select
<!-- 引用sql块 -->
<include refid="employee"/>
from sys_employees E
<!-- 动态判断,不为空则加入where后面,where有自动去除and的功能,所以不用担心语句出错 -->
<where>
<if test="empId !=null ">
E.emp_id = #{empId}
</if>
<if test="empName !=null and empName != '' ">
and E.emp_name = #{empName}
</if>
<if test="empPassword !=null and empPassword != '' ">
and E.emp_password = #{empPassword}
</if>
</where>
</select> </mapper>

4)测试

首先,在build path下新建source文件夹test,并在test下新建包名:com.nikey.oa.mapper.Demo

其次,我们在该包下建一个SqlSessionTemplateTest.java,内容如下:

package com.nikey.oa.mapper.Demo;

import org.mybatis.spring.SqlSessionTemplate;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext; import com.nikey.oa.model.Demo.Employee; /**
* @author jayzeee
*
*/
public class SqlSessionTemplateTest {public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("spring/applicationContext.xml");
SqlSessionTemplate sqlSessionTemplate = (SqlSessionTemplate) context.getBean("sqlSessionTemplate"); //使用sqlSessionTemplate调用mapper里的方法,语法:无需指定mapper,直接在参数里填方法名,因为这个方法名是全局的
Employee e = new Employee();
e.setEmpName("jayzee");
Employee employee = sqlSessionTemplate.selectOne("getAnEmployee", e);
System.out.println(employee);
} }

打印结果:com.nikey.oa.model.Demo.Employee@1d5e5d7

至此,我们的包结构如下:

如果你想开启mybatis的缓存机制,需要加入如下两个配置:

配置1:在EmployeeMapper.xml下添加<cache>

配置2:系列化Employee.java

入门讲解到此为止,下面讲解mybatis的高级部分

4.灵活传参以及resultmap的组织

1) 准备工作

在本地的mysql的test数据库下运行下面的语句:

CREATE TABLE sys_roles (
role_id INT(11) NOT NULL AUTO_INCREMENT,
role_name VARCHAR(255) NULL DEFAULT NULL COMMENT '角色名称',
role_desc VARCHAR(255) NULL DEFAULT NULL COMMENT '角色描述',
is_enable BOOL NULL DEFAULT '1' COMMENT '是否启用 0:否 1:是',
is_sys BOOL NULL DEFAULT '0' COMMENT '是否管理员 0:否 1:是',
PRIMARY KEY(role_id)
)
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE sys_employees_roles (
emp_id INT(11) NOT NULL COMMENT '员工',
role_id INT(11) NOT NULL COMMENT '角色',
PRIMARY KEY(emp_id, role_id),
INDEX emp_id_index(emp_id),
INDEX role_id_index(role_id),
FOREIGN KEY(emp_id)
REFERENCES sys_employees(emp_id)
ON DELETE NO ACTION
ON UPDATE CASCADE,
FOREIGN KEY(role_id)
REFERENCES sys_roles(role_id)
ON DELETE NO ACTION
ON UPDATE CASCADE
)
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE departments (
depart_id INT(11) NOT NULL AUTO_INCREMENT,
depart_name VARCHAR(255) NULL DEFAULT NULL COMMENT '部门名称',
depart_desc VARCHAR(255) NULL DEFAULT NULL COMMENT '部门描述',
PRIMARY KEY(depart_id)
)
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;CREATE TABLE departments_employees (
emp_id INT(11) NOT NULL COMMENT '员工',
depart_id INT(11) NOT NULL COMMENT '部门',
PRIMARY KEY(emp_id, depart_id),
INDEX depart_id_index(depart_id),
INDEX emp_id_index(emp_id),
FOREIGN KEY(depart_id)
REFERENCES departments(depart_id)
ON DELETE NO ACTION
ON UPDATE CASCADE,
FOREIGN KEY(emp_id)
REFERENCES sys_employees(emp_id)
ON DELETE NO ACTION
ON UPDATE CASCADE
)
ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8;insert into sys_roles values (4, '技术工程师', '小弟', 1, 0);insert into sys_roles values (5, '软件工程师', '小弟', 1, 0);insert into sys_employees_roles values (1, 4);insert into sys_employees_roles values (1, 5);insert into departments values (1, '软件部', '做软件的');insert into departments_employees values (1, 1);

修改generator.xml底部内容如下:

<!-- tableName:用于自动生成代码的数据库表;domainObjectName:对应于数据库表的javaBean类名 -->
<table tableName="sys_roles" domainObjectName="Role" />
<table tableName="departments" domainObjectName="Department" />

参照上文删除-example.java文件和清除接口以及xml的无用信息

在Employee.java下添加如下信息:

private List<Role> roles;

private Department department;

public Department getDepartment() {
return department;
} public void setDepartment(Department department) {
this.department = department;
} public List<Role> getRoles() {
return roles;
} public void setRoles(List<Role> roles) {
this.roles = roles;
}

预研报告——MyBatis持久层的demo的更多相关文章

  1. MyBatis持久层框架使用总结 转载

    MyBatis持久层框架使用总结   MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google co ...

  2. MyBatis持久层框架使用总结

    MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis . 2 ...

  3. Spring集成MyBatis持久层框架

    一.MyBatis介绍 MyBatis 是一款优秀的持久层框架,它支持定制化SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,可以使用简单的XML ...

  4. MyBatis持久层框架学习之01 MyBatis的起源和发展

    一.MyBatis的简介  MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架.    MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. MyB ...

  5. spring-boot+mybatis开发实战:如何在spring-boot中使用myabtis持久层框架

    前言: 本项目基于maven构建,使用mybatis-spring-boot作为spring-boot项目的持久层框架 spring-boot中使用mybatis持久层框架与原spring项目使用方式 ...

  6. java持久层框架mybatis如何防止sql注入

    看到一篇很好的文章:http://www.jfox.info/ava-persistence-framework-mybatis-how-to-prevent-sql-injection sql注入大 ...

  7. 持久层框架:MyBatis 3.2(2)

    每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得.SqlSessi ...

  8. Mybatis(一):手写一套持久层框架

    作者 : 潘潘 未来半年,有幸与导师们一起学习交流,趁这个机会,把所学所感记录下来. 「封面图」 自毕业以后,自己先创业后上班,浮沉了近8年,内心着实焦躁,虽一直是走科班路线,但在技术道路上却始终没静 ...

  9. MyBatis知多少(7)持久层

    持久层是适合使用MyBatis的地方.在面向对象的系统中,持久层主要关注对象(或者更精确地说应该是存储在那些对象中的数据)的存取.在企业应用程序中持久层通常用关系数据库系统来存储数据,虽然某些情况下其 ...

随机推荐

  1. Spring 事务声明无效果(转)

    为了打印清楚日志,很多方法我都加tyr catch,在catch中打印日志.但是这边情况来了,当这个方法异常时候 日志是打印了,但是加的事务却没有回滚. 例:      类似这样的方法不会回滚 (一个 ...

  2. Java 依赖、关联、聚合和组合

    必须转一个,写的太好了! https://blog.csdn.net/zhengzhb/article/details/7190158

  3. Struts2中期(这框架目前正处于淘汰状态)

    Struts2的第二天 Struts2的第二天的内容 1. Struts2框架中的Servlet的API的使用 2. Struts2中Action接收请求参数 3. Struts2中自定义拦截器 案例 ...

  4. iOS 让视图UIView单独显示某一侧的边框线

    iOS 让视图UIView 单独显示某一侧的边框线   有时候需要让view显示某一侧的边框线,这时设置layer的border是达不到效果的.在网上查阅资料发现有一个投机取巧的办法,原理是给view ...

  5. flexible.js在华某为手机上使用rem时,页面宽度超出手机屏幕宽度

    问题:手机端项目在华为的某款手机上显示时页面内容没有自适应手机宽度,出现横向滚动条 原因:手机获取手机屏幕宽度并计算出rem时出现偏差,明显宽余真实手机屏宽度 解决方案一:在页面里获取页面最外层dom ...

  6. 【CodeForces 660D】Number of Parallelograms(n个点所能组成的最多平行四边形数量)

    You are given n points on a plane. All the points are distinct and no three of them lie on the same ...

  7. OI 刷题记录——每周更新

    每周日更新 2016.05.29 UVa中国麻将(Chinese Mahjong,Uva 11210) UVa新汉诺塔问题(A Different Task,Uva 10795) NOIP2012同余 ...

  8. yum仓库客户端搭建和NTP时间同步客户端配置

    一.yum仓库客户端搭建 yum源仓库搭建分为服务器端和客户端. 服务端主要提供软件(rpm包)和yumlist.也就是提供yum源的位置.一般是通过http或者ftp提供位置. 客户端的配置:yum ...

  9. Java OOP——第四章 异常

    1. 接口:接口就是给出一些没有内容的方法,封装到一起,到某个类要使用的时候,在根据具体情况把这些方法写出来. 接口是更加抽象的抽象的类, 抽象类里的方法可以有方法体, 接口里的所有方法都没有方法体. ...

  10. Axure RP Extension for Chrome安装

    Axure RP Extension for Chrome安装 Axure RP Extension for Chrome是一款谷歌插件,主要可以用来查看原型文件.以前安装插件的时候总是找半天资源,很 ...