预研报告——MyBatis持久层的demo
一、预研任务介绍和预研目标
任务介绍:
与 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&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的更多相关文章
- MyBatis持久层框架使用总结 转载
MyBatis持久层框架使用总结 MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google co ...
- MyBatis持久层框架使用总结
MyBatis 本是apache的一个开源项目iBatis, 2010年这个项目由apache software foundation 迁移到了google code,并且改名为MyBatis . 2 ...
- Spring集成MyBatis持久层框架
一.MyBatis介绍 MyBatis 是一款优秀的持久层框架,它支持定制化SQL.存储过程以及高级映射.MyBatis 避免了几乎所有的JDBC代码和手动设置参数以及获取结果集,可以使用简单的XML ...
- MyBatis持久层框架学习之01 MyBatis的起源和发展
一.MyBatis的简介 MyBatis 是支持定制化 SQL.存储过程以及高级映射的优秀的持久层框架. MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集. MyB ...
- spring-boot+mybatis开发实战:如何在spring-boot中使用myabtis持久层框架
前言: 本项目基于maven构建,使用mybatis-spring-boot作为spring-boot项目的持久层框架 spring-boot中使用mybatis持久层框架与原spring项目使用方式 ...
- java持久层框架mybatis如何防止sql注入
看到一篇很好的文章:http://www.jfox.info/ava-persistence-framework-mybatis-how-to-prevent-sql-injection sql注入大 ...
- 持久层框架:MyBatis 3.2(2)
每个MyBatis应用程序主要都是使用SqlSessionFactory实例的,一个SqlSessionFactory实例可以通过SqlSessionFactoryBuilder获得.SqlSessi ...
- Mybatis(一):手写一套持久层框架
作者 : 潘潘 未来半年,有幸与导师们一起学习交流,趁这个机会,把所学所感记录下来. 「封面图」 自毕业以后,自己先创业后上班,浮沉了近8年,内心着实焦躁,虽一直是走科班路线,但在技术道路上却始终没静 ...
- MyBatis知多少(7)持久层
持久层是适合使用MyBatis的地方.在面向对象的系统中,持久层主要关注对象(或者更精确地说应该是存储在那些对象中的数据)的存取.在企业应用程序中持久层通常用关系数据库系统来存储数据,虽然某些情况下其 ...
随机推荐
- ## `nrm`的安装使用
作用:提供了一些最常用的NPM包镜像地址,能够让我们快速的切换安装包时候的服务器地址:什么是镜像:原来包刚一开始是只存在于国外的NPM服务器,但是由于网络原因,经常访问不到,这时候,我们可以在国内,创 ...
- CentOS 7 安装oracle 11G
一.安装Oracle前准备 首先要设置主机名,并在/etc/hosts下解析. 镜像没挂全,导致缺少包pdksh-5.2.14.compat-libstdc++-33-3.2.3 1.创建运行orac ...
- Set linux mq_queue size for user
设置调整mq_queue的size*num如果大于默认(POSIX message queues),则需要调整系统限制和用户限制,不然在mq_open是会报"Too many open fi ...
- redis主从同步收到以下参数影响
repl-ping-slave-period主从心跳ping的时间间隔.默认10 repl-timeout 从节点超时时间.默认60 repl-backlog-size 主节点保存操作日志的大 ...
- 查找mysql中未提交的事务
1.查找未提交事务 在mysql中运行: select t.trx_mysql_thread_id from information_schema.innodb_trx t 2.删除线程 kill ...
- 图的遍历(Python实现)
图的遍历(Python实现) 记录两种图的遍历算法——广度优先(BFS)与深度优先(DFS). 图(graph)在物理存储上采用邻接表,而邻接表是用python中的字典来实现的. 两种遍历方式的代码如 ...
- PADS快捷键
问:在pads layout中怎样显示或隐藏铺铜的效果 答: 无模命令:po 或者spo 前者是平面层 后者是混合层. 同时你可以在ctrl+alt+c 色彩项中关闭 copper . 使用 无模命令 ...
- python学习——装饰器函数
一.装饰器函数的作用是什么 答:装饰器函数是在不修改原函数及其调用方式的情况下对原函数功能进行扩展 对于搞python开发的人来说,函数占据了至关重要的地位.都说学好函数你就可以去找工作了,好了,假如 ...
- 怎么实现hibernate悲观锁和乐观锁?
隔离级别的安全控制是整体一个大的方面,而锁机制更加的灵活,它执行的粒度可以很小,可以在一个事务中存在. Hibernate悲观锁是依靠底层数据库的锁机制实现,在查询query.setLockMode( ...
- ActivityStream是什么?什么是Feed流?
我先说说feed流吧,它就是社交网站中用户活动信息流,例如用户写了博客.发了照片.评论了什么等等.Facebook叫newsFeed.推特叫TimeLineFeed.ActivityStream是这些 ...