学习目标
- 理解数据持久化概念和ORM原理
- 理解MyBatis的概念一级有点特性
- 搭建MyBatis环境
- 了解MyBatis与JDBC的区别与联系
- 理解核心类的作用域和声明周期
- 掌握全局配置文件结构内容
框架技术
- 是一个应用程序的半成品
- 提供可重用的公共结构
- 按一定规则组织的一组组件
分析优势
- 不用考虑公共问题
- 专心在业务层实现
- 结构统一,易用学习、维护
Spring
- 依赖注入容器/AOP实现
- 声明式事务
- 简化JavaEE应用
- 粘合剂,将大家组装到一起
Spring MVC
- 结构最清晰的MVC Model2实现
- 高度可配置,支持多种视图技术
- 定制化开发
MyBatis
- 半自动化的ORM实现
- DAO层
- 动态SQL
- 小巧灵活、简单易学
1 持久化与ORM
- 持久化就是数据在瞬时状态和持久化状态间转换的过程。
- ORM(Object Relational Mapping)
- 编写程序的时候,以面向对象的方式处理数据
- 保存数据的时候,却以关系型数据库的方式存储
- ORM解决方案包含下面四个部分
- 在持久化对象上执行基本的增、删、改、查操作
- 对持久化对象提供一种查询语言或者API
- 对象映射工具
- 提供与事务对象交互、执行检查、延迟加载以及其他优化功能
2 MyBatis简介
- MyBatis前身是IBatis,本身是Apache的一个开源项目
- 中文官网学习网站
- ORM框架
- 实体类和SQL语句之间建立映射关系
- 特点:
- 基于SQL语法,简单易学
- 能了解底层封装过程
- SQL语句封装在配置文件中,便于统一管理与维护,降低程序的耦合度
- 方便程序代码调试
3 使用MyBatis的开发步骤
1.首先创建maven工程,直接在pom文件中导入maven仓库的相关依赖即可,如果是web项目,下载mybatis-3.5.2.jar包导入工程lib文件夹下即可,(此处我们以maven工程为例):
mybatis 3.5.2 maven 仓库
<!--mybatis-->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.5.2</version>
</dependency>
2.1准备数据库连接配置文件,以Oracle为例(database.properties)
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:localhost:1521:orcl
username=ebuy
password=123456
2.2准备控制台日志配置文件(可在控制台输出打印错误)(log4j.properties)
log4j.rootLogger=DEBUG,CONSOLE
#log4j.rootLogger=ERROR,ROLLING_FILE
log4j.logger.com.ebuy.dao=debug
log4j.logger.com.ibatis=debug
log4j.logger.com.ibatis.common.jdbc.SimpleDataSource=debug
log4j.logger.com.ibatis.common.jdbc.ScriptRunner=debug
log4j.logger.com.ibatis.sqlmap.engine.impl.SqlMapClientDelegate=debug
log4j.logger.java.sql.Connection=debug
log4j.logger.java.sql.Statement=debug
log4j.logger.java.sql.PreparedStatement=debug
log4j.logger.java.sql.ResultSet=debug
######################################################################################
# Console Appender \u65e5\u5fd7\u5728\u63a7\u5236\u8f93\u51fa\u914d\u7f6e
######################################################################################
log4j.appender.CONSOLE=org.apache.log4j.ConsoleAppender
log4j.appender.Threshold=error
log4j.appender.CONSOLE.Target=System.out
log4j.appender.CONSOLE.layout=org.apache.log4j.PatternLayout
log4j.appender.CONSOLE.layout.ConversionPattern=[%p] %d %c - %m%n
3.编写MyBatis核心配置文件(mybatis-conf.xml)
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<!--导入数据库连接参数-->
<properties resource="database.properties"/>
<!--此处的优先级高于environments中的配置文件(一般不建议配置在此处)-->
<!--<properties resource="database.properties">
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</properties>-->
<!--设置MyBatis控制台输出为log4j日志文件-->
<settings>
<setting name="logImpl" value="log4j"/>
</settings>
<!--为实体类设置别名-->
<typeAliases>
<!--也可以指定某个实体类为其设置别名,type为指定类路径,alias为设置的别名-->
<!--这样配置时,user可以用在任何使用com.ebuy.pojo.SystemUser的地方。-->
<!--<typeAlias type="com.ebuy.pojo.SystemUser" alias="user"/>-->
<!--也可以指定一个包名,MyBatis会在包名下面搜索所有需要的JavaBean,默认别名为其类名-->
<package name="com.ebuy.pojo"/>
</typeAliases>
<!--默认加载是Oracle数据库-->
<environments default="oracle">
<environment id="oracle">
<!--事务管理器,使用jdbc操作数据库-->
<transactionManager type="jdbc"/>
<!--允许使用数据库连接池(提高效率)-->
<dataSource type="POOLED">
<!--切记properties中oracle加载驱动字符串中的driver,d是小写-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--要将SystemUserMapper接口配置文件加入到此处运行环境中-->
<mappers>
<!--<mapper resource="com/ebuy/dao/SystemUserMapper.xml"/>
<mapper resource="com/ebuy/dao/SystemRoleMapper.xml"/>-->
<!--考虑到未来会有很多实体类映射配置文件,所以可以一步到位,直接将所在包引入即可-->
<package name="com.ebuy.dao"/>
</mappers>
</configuration>
4.创建实体类-pojo(注意要实现序列化)
- SystemUser
package com.ebuy.pojo; import java.io.Serializable; /** * 用户实体 */ public class SystemUser implements Serializable { /** * 用户ID */ private String userinfo_uid; /** * 登录名 */ private String userinfo_loginid; /** * 姓名 */ private String userinfo_name; /** * 密码 */ private String userinfo_password; /** * 性别 */ private String userinfo_sex; /** * 电子邮箱 */ private String userinfo_email; /** * 手机 */ private String userinfo_mobile; /** * 用户状态(1 正常 2 锁定 3注销) */ private int userinfo_status; @Override public String toString() { return "SystemUser{" + "userinfo_uid='" + userinfo_uid + '\'' + ", userinfo_loginid='" + userinfo_loginid + '\'' + ", userinfo_name='" + userinfo_name + '\'' + ", userinfo_password='" + userinfo_password + '\'' + ", userinfo_sex='" + userinfo_sex + '\'' + ", userinfo_email='" + userinfo_email + '\'' + ", userinfo_mobile='" + userinfo_mobile + '\'' + ", userinfo_status=" + userinfo_status + '}'; } public SystemUser() { } public SystemUser(String userinfo_uid, String userinfo_loginid, String userinfo_name, String userinfo_password, String userinfo_sex, String userinfo_email, String userinfo_mobile, int userinfo_status) { this.userinfo_uid = userinfo_uid; this.userinfo_loginid = userinfo_loginid; this.userinfo_name = userinfo_name; this.userinfo_password = userinfo_password; this.userinfo_sex = userinfo_sex; this.userinfo_email = userinfo_email; this.userinfo_mobile = userinfo_mobile; this.userinfo_status = userinfo_status; } public String getUserinfo_uid() { return userinfo_uid; } public void setUserinfo_uid(String userinfo_uid) { this.userinfo_uid = userinfo_uid; } public String getUserinfo_loginid() { return userinfo_loginid; } public void setUserinfo_loginid(String userinfo_loginid) { this.userinfo_loginid = userinfo_loginid; } public String getUserinfo_name() { return userinfo_name; } public void setUserinfo_name(String userinfo_name) { this.userinfo_name = userinfo_name; } public String getUserinfo_password() { return userinfo_password; } public void setUserinfo_password(String userinfo_password) { this.userinfo_password = userinfo_password; } public String getUserinfo_sex() { return userinfo_sex; } public void setUserinfo_sex(String userinfo_sex) { this.userinfo_sex = userinfo_sex; } public String getUserinfo_email() { return userinfo_email; } public void setUserinfo_email(String userinfo_email) { this.userinfo_email = userinfo_email; } public String getUserinfo_mobile() { return userinfo_mobile; } public void setUserinfo_mobile(String userinfo_mobile) { this.userinfo_mobile = userinfo_mobile; } public int getUserinfo_status() { return userinfo_status; } public void setUserinfo_status(int userinfo_status) { this.userinfo_status = userinfo_status; } }
- SystemRole
package com.ebuy.pojo; import java.io.Serializable; /** * 角色实体 */ public class SystemRole implements Serializable { /** * 角色ID */ private String role_id; /** * 角色名称 */ private String role_name; /** * 角色编码 */ private String role_code; /** * 角色描述 */ private String role_description; @Override public String toString() { return "SystemRole{" + "role_id='" + role_id + '\'' + ", role_name='" + role_name + '\'' + ", role_code='" + role_code + '\'' + ", role_description='" + role_description + '\'' + '}'; } public SystemRole() { } public SystemRole(String role_id, String role_name, String role_code, String role_description) { this.role_id = role_id; this.role_name = role_name; this.role_code = role_code; this.role_description = role_description; } public String getRole_id() { return role_id; } public void setRole_id(String role_id) { this.role_id = role_id; } public String getRole_name() { return role_name; } public void setRole_name(String role_name) { this.role_name = role_name; } public String getRole_code() { return role_code; } public void setRole_code(String role_code) { this.role_code = role_code; } public String getRole_description() { return role_description; } public void setRole_description(String role_description) { this.role_description = role_description; } }
5.DAO层-SQL映射文件(mapper.xml)
- SystemUserMapper.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"> <!--namespace是命名空间,要与对应的接口的路径保持一致(如果没有创建该接口,MyBatis在内部编译时会自动创建)--> <mapper namespace="com.ebuy.dao.SystemUserMapper"> <!--查询数据库中system_userinfo 中数据记录数--> <select id="count" resultType="int"> select count(*) from system_userinfo </select> <!--查询system_userinfo中所有数据--> <select id="selectUserAll" resultType="com.ebuy.pojo.SystemUser"> select * from system_userinfo </select> </mapper>
- SystemRoleMapper.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"> <!--namespace是命名空间,要与对应的接口的路径保持一致(如果没有创建该接口,MyBatis在内部编译时会自动创建)--> <mapper namespace="com.ebuy.dao.SystemRoleMapper"> <!--查询数据库中system_role中数据记录数--> <select id="count" resultType="int"> select count(*) from system_role </select> <!--查询system_role中所有数据--> <select id="selectRoleAll" resultType="SystemRole"> select * from system_role </select> <!--根据role_id查询角色信息(参数是int类型的可以不用写)(一个参数的情况)--> <select id="getRoleById" parameterType="int" resultType="SystemRole"> select * from system_role where role_id = #{roleId} </select> <!--根据role_id和role_name查询角色信息(多个参数的情况,可以在接口中使用注解映射参数的方法)--> <select id="getRoleByIdAndName" resultType="SystemRole"> select * from system_role where role_id = #{roleId} and role_name = #{roleName} </select> <!--根据类对象中的某些参数查询角色信息(这时候参数是类对象,在接口中就不用使用注解映射了)--> <select id="getRoleByObject" parameterType="SystemRole" resultType="SystemRole"> select * from system_role where role_id = #{role_id} and role_name = #{role_name} </select> <!--插入角色数据--> <insert id="save" parameterType="SystemRole"> insert into system_role(role_id,role_name,role_code,role_description) values(SEQ_SYSTEM_ROLE_ID.nextval,#{role_name},#{role_code},#{role_description}) </insert> <!--根据roleId删除角色信息--> <delete id="deleteByRoleId" parameterType="String"> delete from system_role where role_id=#{role_id} </delete> <!--根据roleId更新角色信息--> <update id="updateByRoleId" parameterType="SystemRole"> update system_role set role_name=#{role_name},role_code=#{role_code}, role_description=#{role_description} where role_id=#{role_id} </update> </mapper>
6.创建测试类
- 步骤:
I/O流读取核心配置文件mybatis-conf.xml
创建SQLSessionFactory工厂对象,加载配置文件
创建SQLSession对象
调用mapper文件进行数据操作 - SystemUserMapperTest
package com.ebuy.test; import com.ebuy.dao.SystemUserMapper; import com.ebuy.pojo.SystemUser; import com.ebuy.util.MyBatisUtil; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; /** * @author 一宿君(CSDN : qq_52596258) * @date 2021-06-23 19:30:22 */ public class SystemUserMapperTest { @Test public void count() throws IOException { String resource = "mybatis-conf.xml"; SqlSession sqlSession = null; //读取配置文件 InputStream is = Resources.getResourceAsStream(resource); //创建sqlSessionFactory工厂 SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(is); //打开sqlSession sqlSession = ssf.openSession(); /** * 此处的count一定要和MyBatis-con.xmlf配置文件中的id保持一致 */ int count = sqlSession.selectOne("com.ebuy.dao.SystemUserMapper.count"); System.out.println(count); sqlSession.close(); } @Test public void selectUserAll(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); List<SystemUser> systemUserList = sqlSession.selectList("com.ebuy.dao.SystemUserMapper.selectUserAll"); for(SystemUser s:systemUserList){ System.out.println(s); } sqlSession.close(); }
- 上述我们看到并没有创建对应的实体类mapper映射接口,在方法中使用的是sqlSession内部的方法,并加载了mapper配置文件中的id及其路径,其实MyBatis内部机制中,mapper-conf.xml文件中的namespace命名空间所对应的就是我们本应该创建的体类mapper映射接口,我们自己虽然没有创建,但是在MyBatis内部编译源代码时,会自动为我们创建匹配的相关实体咧mapper临时接口,以此实现我们自定义的SQL功能,但是我们一般不建议这样做,效率比较低,而且不够规范。
7.创建对应的实体类mapper映射接口
- 注意:
要保证接口中的方法名和mapper配置文件中的id保持一致
- SystemUser
package com.ebuy.dao; import com.ebuy.pojo.SystemUser; import java.util.List; /** * 用户映射接口(接口中的方法名要和mapper配置文件中的id方法明保持一致) * @author 一宿君(CSDN : qq_52596258) * @date 2021-06-24 16:00:18 */ public interface SystemUserMapper { /** * 查询用户表中总记录数 * @return */ int count(); /** * 查询用户表中所有的数据 * @return */ List<SystemUser> selectUserAll(); }
- SystemRole
package com.ebuy.dao; import com.ebuy.pojo.SystemRole; import org.apache.ibatis.annotations.Param; import java.util.List; /** * @author 一宿君(CSDN : qq_52596258) * @date 2021-06-24 16:00:06 */ public interface SystemRoleMapper { /** * 查询角色表中总记录数 * @return */ int count(); /** * 查询角色表中所有记录 * @return */ List<SystemRole> selectRoleAll(); /** * 根据roleId查询角色信息一个参数的情况) * @param roleId * @return */ SystemRole getRoleById(int roleId); /** * 根据roleId和roleName查询角色信息 * @param roleId * @param roleName * @return */ SystemRole getRoleByIdAndName(@Param("roleId") int roleId, @Param("roleName") String roleName); /** * 根据类对象中某些参数信息(roleId和roleName) * @param systemRole * @return */ SystemRole getRoleByObject(SystemRole systemRole); /** * 插入角色数据 * @param SystemRole * @return */ int save(SystemRole SystemRole); /** * 根据roleId删除信息 * @param systemRole * @return */ int deleteByRoleId(SystemRole systemRole); /** * 根据roleId更新信息 * @param systemRole * @return */ int updateByRoleId(SystemRole systemRole); }
8.上述在测试类的每个方法中,我们都要重新读取配置文件和创建SQLSessionFactory工厂对象,再创建sqlSession,这样每次都要重新调用过于繁琐,我们可以创建一个获取SQLSession的工具类。
-
package com.ebuy.util; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import java.io.InputStream; /** * @author 一宿君(CSDN : qq_52596258) * @date 2021-06-23 19:42:42 */ public class MyBatisUtil { private static SqlSessionFactory sqlSessionFactory = null; static { String resource = "mybatis-conf.xml"; InputStream is = null; try { is = Resources.getResourceAsStream(resource); sqlSessionFactory = new SqlSessionFactoryBuilder().build(is); }catch (Exception ex){ ex.printStackTrace(); } } /** * 打开SqlSession * @return */ public static SqlSession createSqlSession(){ /** * true :代表手动提交事务(默认),一般设置为手动提交 * false : 代表自动提交事务 */ return sqlSessionFactory.openSession(true); } /** * 关闭SqlSesison */ public static void closeSqlSession(SqlSession sqlSession){ if(sqlSession != null){ sqlSession.close(); } } }
9.使用工具类更新测试类
- SystemUserMapperTest
package com.ebuy.test; import com.ebuy.dao.SystemUserMapper; import com.ebuy.pojo.SystemUser; import com.ebuy.util.MyBatisUtil; import org.apache.ibatis.io.Resources; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import org.apache.ibatis.session.SqlSessionFactoryBuilder; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.List; /** * @author 一宿君(CSDN : qq_52596258) * @date 2021-06-23 19:30:22 */ public class SystemUserMapperTest { /** * 利用接口引用,调用mapper映射文件中的方法 * @throws IOException */ @Test public void count2() throws IOException { SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemUserMapper systemUserMapper = sqlSession.getMapper(SystemUserMapper.class); System.out.println(systemUserMapper.count()); sqlSession.close(); } /** * 利用接口引用,调用mapper映射文件中的方法 * @throws IOException */ @Test public void selectUserAll2(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemUserMapper systemUserMapper = sqlSession.getMapper(SystemUserMapper.class); List<SystemUser> systemUserList = systemUserMapper.selectUserAll(); for(SystemUser s:systemUserList){ System.out.println(s); } } }
- SystemRoleMapperTest
package com.ebuy.test; import com.ebuy.dao.SystemRoleMapper; import com.ebuy.pojo.SystemRole; import com.ebuy.util.MyBatisUtil; import org.apache.ibatis.session.SqlSession; import org.junit.Test; import java.io.IOException; import java.util.List; /** * @author 一宿君(CSDN : qq_52596258) * @date 2021-06-23 19:30:22 */ public class SystemRoleMapperTest { /** * 利用接口引用,调用mapper映射文件中的方法 * @throws IOException */ @Test public void count() throws IOException { SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class); System.out.println(systemRoleMapper.count()); sqlSession.close(); } /** * 利用接口引用,调用mapper映射文件中的方法 * @throws IOException */ @Test public void selectRoleAll(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class); List<SystemRole> systemRoleList = systemRoleMapper.selectRoleAll(); for(SystemRole s:systemRoleList){ System.out.println(s); } } @Test public void getRoleById(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class); SystemRole systemRole = systemRoleMapper.getRoleById(1); System.out.println(systemRole); } @Test public void getRoleByIdAndName(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class); SystemRole systemRole = systemRoleMapper.getRoleByIdAndName(1,"超级管理员"); System.out.println(systemRole); } @Test public void getRoleByObject(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class); SystemRole systemRole = new SystemRole(); systemRole.setRole_id("1"); systemRole.setRole_name("超级管理员"); SystemRole systemRole2 = systemRoleMapper.getRoleByObject(systemRole); System.out.println(systemRole2); } @Test public void save(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class); SystemRole systemRole = new SystemRole(); systemRole.setRole_name("财务管理员"); systemRole.setRole_code("cwadmin"); systemRole.setRole_description("管理所有财务业务"); int r = systemRoleMapper.save(systemRole); /** * 非常关键的一步是,更新或插入数据,执行SQL后要手动进行提交 */ sqlSession.commit(); System.out.println("成功插入:" + r + "条角色数据"); } @Test public void deleteByRoleId(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class); SystemRole systemRole = new SystemRole(); systemRole.setRole_id("7"); int r = systemRoleMapper.deleteByRoleId(systemRole); /** * 非常关键的一步是,更新或插入数据,执行SQL后要手动进行提交 */ sqlSession.commit(); System.out.println("成功删除:" + r + "条角色数据"); } @Test public void updateByRoleId(){ SqlSession sqlSession = MyBatisUtil.createSqlSession(); SystemRoleMapper systemRoleMapper = sqlSession.getMapper(SystemRoleMapper.class); SystemRole systemRole = new SystemRole(); systemRole.setRole_id("7"); systemRole.setRole_name("财务管理员222222"); systemRole.setRole_code("cwadmin22222"); systemRole.setRole_description("管理所有财务业务22222"); int r = systemRoleMapper.updateByRoleId(systemRole); /** * 非常关键的一步是,更新或插入数据,执行SQL后要手动进行提交 */ sqlSession.commit(); System.out.println("成功更新:" + r + "条角色数据"); } }
先就这么多吧!!!