预研报告——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的地方.在面向对象的系统中,持久层主要关注对象(或者更精确地说应该是存储在那些对象中的数据)的存取.在企业应用程序中持久层通常用关系数据库系统来存储数据,虽然某些情况下其 ...
随机推荐
- sql树形查询
sql: 使用Common As:递归公用表 https://docs.microsoft.com/en-us/sql/t-sql/queries/with-common-table-expressi ...
- RPC的应用(The lowest layer of RPC)
server端代码: #include <stdio.h>#include <rpc/rpc.h>#include <rpcsvc/rusers.h> void n ...
- Python中使用list和tuple
list: Python内置的一种数据类型是列表:list.list是一种有序的集合,可以随时添加和删除其中的元素. 比如,列出班里所有同学的名字,就可以用一个list表示: 变量classmates ...
- JWT如何在Spring Cloud微服务系统中在服务相互调时传递
转载请标明出处: http://blog.csdn.net/forezp/article/details/78676036 本文出自方志朋的博客 在微服务系统中,为了保证微服务系统的安全,常常使用jw ...
- vue+nodejs+express+mysql 建立一个在线网盘程序
vue+nodejs+express+mysql 建立一个在线网盘程序 目录 vue+nodejs+express+mysql 建立一个在线网盘程序 第一章 开发环境准备 1.1 开发所用工具简介 1 ...
- Java : java基础(1)
java编译器有常亮优化机制,如果是常量的计算,会直接判断常量计算结果的取值范围,如果是变量,则没办法判断计算取值范围,编译会异常(如两个byte类型的变量相加). java中的常量指的是用 stat ...
- SVN 命令整理
1.将文件checkout到本地目录 svn checkout path(path是服务器上的目录) 例如:svn checkout svn://192.168.1.35/pro/domain 如果开 ...
- 点按钮ajax get方法修改0或1状态封装成函数
最终效果 列表页面表格里点击按钮修改状态 按钮样式要引入bootstrap才可以用 本文件用的是laravel框架环境 larave路由里 Route::get('category/changesta ...
- hadoop生态搭建(3节点)-04.hadoop配置
如果之前没有安装jdk和zookeeper,安装了的请直接跳过 # https://www.oracle.com/technetwork/java/javase/downloads/java-arch ...
- 国内maven库链接地址,链接阿里的库,下载很快!!!
<mirror> <id>alimaven</id> <name>aliyun maven</name> <url>http:/ ...