手把手教mybatis第一节

Mybatis 教程1

mybatis的简介

前身叫Ibatis,是一个&半自动的ORM框架(Object R model)对象关系模型&,完整ORM框架(hibernate),hibernate的入门难度高,mybatis的入门级别低,如果你会用jdbc,你应该会用mybatis,仅仅是对jdbc的封装

MyBatis本是apache的一个开源项目iBatis,2010年这个项目由apache software foundation迁移到了[google code](https://baike.baidu.com/item/google code/2346604?fromModule=lemma_inlink),并且改名为MyBatis。2013年11月迁移到Github

iBATIS一词来源于“internet”和“abatis”的组合,是一个基于Java持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAOs)。

当前,最新版本是MyBatis 3.5.13,其发布时间是2023年03月11日。

迅速在中国互联网行业应用(hibernate>mybatis),原因:简单,中国软件从业人员的能力

MyBatis 是一款优秀的持久层框架,它支持定制化 SQL存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生信息,将接口和 Java 的 POJOs(Plain Ordinary Java Object,普通的 Java对象)映射成数据库中的记录。 [1]

传统JDBC存在的问题

  • 数据库连接信息硬编码(配置文件)【全局配置文件】
Class.forName("com.mysql.cj.jdbc.Driver") // crac
DriverManager.getConnection(url,username,pwd);// 开发环境username root修改
// 保存源码  编译字节码--生产环境和开发环境完全一致
// 开发环境  装有eclipse的环境   jdk   a
// 生产环境  服务器上的环境   crm
// 测试环境  用于测试人员进行测试的环境 crm
// 环境:操作系统的位数  JDK的版本号
// 1.8 jdk 包含有xml操作的依赖
// 11 jdk 将xml的依赖移除了
  • 频繁获取连接(数据库连接池)【mybatis自主开发的数据库连接池】
  • 查询结果封装(使用反射进行封装)【通过xml配置来解决】
  • Sql语句应编码问题(可以通过配置文件来解决)【映射文件】

mybatis帮我们解决了以上所有问题

mybatis的运行原理

在这里插入图片描述

  • mybatis的核心是配置文件,分别为全局配置文件(1个)和映射文件(n个)。全局配置文件中定义了数据库连接信息、事务信息、数据库连接池信息、别名、插件、加载映射文件等信息。映射文件中包含sql语句以及结果映射、动态sql等。
  • SqlSessionFactoryBuild加载配置文件生成SqlSessionFactory(构建者模式)
  • SqlSessionFactory.openSession的方法来获取SqlSession对象(工厂模式)
  • SqlSession是一个接口,他是mybatis提供给开发人员的开发标准(用于操作数据库的所有的方法),包含有insert update delete等操作数据库的方法
  • SqlSession调用exector执行器(SimpleExector,CacheExector,BatchExector),让执行器来操作数据库
  • 执行器调用mapperstatement对象,包含sql语句,输入参数,输出结果
  • 真实的调用数据库

xml

xml是一种重量级数据传输格式,一般使用在EJB

  • 声明,声明xml的编码格式以及版本信息
<?xml version="1.0" encoding="UTF-8"?>
  • 约束(用来规定xml中节点的名称以及节点中的属性的名称的书写规范的)

    • dtd约束
    • schema约束
  • 自定义节点信息

    如果xml中包含有约束,自定义节点必须按照约束的书写规范进行编写,如果没有约束,随便写

搭建入门案例

  • 创建se的工程
  • 添加依赖
    • mysql-connector-java
    • mybatis依赖

https://mvnrepository.com/

  • 创建全局配置文件xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration
  PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
 <!-- 环境(多环境定义)
 default:复数环境中定义的单个环境的id,
  -->
  <environments default="dev">
  <!-- 单个环境定义
  id: 当前环境的唯一编号
   -->
    <environment id="dev">
    <!-- 定义事务
    type : jdbc使用jdbc的事务
          MANAGED 使用非事务的形式
     -->
      <transactionManager type="JDBC"/>
      <!-- 
     数据源  数据库连接池的定义
     type: POOLED 连接池(mybatis自己开发的连接池,性能差)
           不允许使用第三方连接池
           UNPOOLED 使用非连接池的方式
           JNDI (java naming directory interface)
           java命名目录接口
           底层架构使用JNDI
       -->
      <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///db1"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
      </dataSource>
    </environment>
     <environment id="prod">
      <transactionManager type="JDBC"/>
       <dataSource type="POOLED">
        <property name="driver" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql:///java2301q"/>
        <property name="username" value="root"/>
        <property name="password" value="123456"/>
      </dataSource>
    </environment>
  </environments>
  <!-- 加载映射文件 -->
 <mappers>
 <!-- resource代表classpath下xml的路径 -->
    <mapper resource="user.xml"/>
  </mappers>
</configuration>
  • 创建映射文件xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="user">
<!-- 如果封装结果是集合,resultType中只需要定义集合中泛型 -->
  <select id="selectUsers" resultType="com.xx.pojo.User">
    select * from sys_user
  </select>
</mapper>
  • 使用构建者模式创建sqlSessionFactory
package com.xx.test;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

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 com.xx.pojo.User;

public class Test1 {
	
	public static void main(String[] args) throws IOException {
		SqlSessionFactoryBuilder build = new SqlSessionFactoryBuilder();
		// 需要将配置文件转为inputStream
		// 将classpath下的文件转为inputstream的方法
		InputStream inputStream = Resources.getResourceAsStream("configer.xml");
		SqlSessionFactory factory = build.build(inputStream);
		SqlSession session = factory.openSession();
		// 放mapperstatement的id,一部分内容  namespace.sqlId
		List<User> users = session.selectList("user.selectUsers");
		users.stream().forEach(a->{
			System.out.println(a.getName());
		});
		session.close();
	}

}

Dao模式

分析作用域

SqlSessionFactoryBuilder

确定sqlSessionFactoryBuilder是单例

这个类可以被实例化、使用和丢弃,一旦创建了 SqlSessionFactory,就不再需要它了。 因此 SqlSessionFactoryBuilder 实例的最佳作用域是方法作用域(也就是局部方法变量)。 你可以重用 SqlSessionFactoryBuilder 来创建多个 SqlSessionFactory 实例,但最好还是不要一直保留着它,以保证所有的 XML 解析资源可以被释放给更重要的事情。

SqlSessionFactory(单例)

SqlSessionFactory 一旦被创建就应该在应用的运行期间一直存在,没有任何理由丢弃它或重新创建另一个实例。 使用 SqlSessionFactory 的最佳实践是在应用运行期间不要重复创建多次,多次重建 SqlSessionFactory 被视为一种代码“坏习惯”。因此 SqlSessionFactory 的最佳作用域是应用作用域。 有很多方法可以做到,最简单的就是使用单例模式或者静态单例模式。注意:如果factory是多例,缓存没有效果

SqlSession

每个线程都应该有它自己的 SqlSession 实例。SqlSession 的实例不是线程安全的,因此是不能被共享的,所以它的最佳的作用域是请求或方法作用域。 绝对不能将 SqlSession 实例的引用放在一个类的静态域,甚至一个类的实例变量也不行。 也绝不能将 SqlSession 实例的引用放在任何类型的托管作用域中,比如 Servlet 框架中的 HttpSession。 如果你现在正在使用一种 Web 框架,考虑将 SqlSession 放在一个和 HTTP 请求相似的作用域中。 换句话说,每次收到 HTTP 请求,就可以打开一个 SqlSession,返回一个响应后,就关闭它。 这个关闭操作很重要,为了确保每次都能执行关闭操作,你应该把这个关闭操作放到 finally 块中

sqlSession是线程不安全的,不允许作为成员变量,应该在每个方法中创建独立的对象

是IBATIS的实现方式,结合DAO模式进行数据库操作

Dao模式中包含的内容:

  • 实体类
  • DAO接口
package com.xx.dao;

import java.util.List;

import com.xxx.pojo.User;

public interface UserDao {

	/**
	 * insert用户信息
	 * @param user 用户信息
	 * @return 影响行数
	 */
	int insertUser(User user);
	
	int updateUser(User user);
	
	int deleteById(Integer id);
	
	User selectById(Integer id);
	
	List<User> selectUsers();
}

  • 接口的实现类
  • 工具类
package com.xx![在这里插入图片描述](https://i-blog.csdnimg.cn/direct/da91de2d050341bdb0bcfb1eadc17b3b.png#pic_center)
.util;

import java.io.IOException;
import java.io.InputStream;

import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;

public class SqlSessionUtil {
	
	private static SqlSessionFactoryBuilder builder;
	private static SqlSessionFactory factory;
	static {
		try {
			builder = new SqlSessionFactoryBuilder();
			InputStream inputStream = Resources.getResourceAsStream("configer.xml");
			factory = builder.build(inputStream);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}
	
	
	public static SqlSession getSession() {
		SqlSession session = factory.openSession();
		return session;
	}

}

SqlSession API

openSession()默认采用了手动提交的事务,openSession(true)可以修改为自动提交的事务,也可以使用session.commit()手动提交事务

方法名返回结果描述
int insert(String statement);int只能执行insert语句,返回结果为影响行数。执行的是静态sql
int insert(String statement, Object parameter);int只能执行insert语句,返回结果为影响行数。执行的是预编译sql,参数2为占位符需要的数据
commit()手动提交事务
int update(String statement)int只能执行update语句,返回结果为影响行数。执行的是静态sql
int update(String statement,Object parameter)int只能执行update语句,返回结果为影响行数。执行的是预编译sql,参数2为占位符需要的数据
int delete(String statmenet)int只能执行delete语句,返回结果为影响行数。执行的是静态sql
int delete(String statement,Object paramter)int只能执行delete语句,返回结果为影响行数。执行的是预编译sql,参数2为占位符需要的数据
T selectOne(String statement);任意类型执行的查询语句查询结果<=1条的,只能执行DQL语句
T selectOne(String statement,Object paramter);任意类型执行的查询语句动态sql查询结果<=1条的,只能执行DQL语句
List selectList(String statement,Object paramter);集合执行的动态sql,查询结果>=0
List selectList(String statement);集合执行静态sql
rollback事务回滚
getConfiguration();Configuration获取到全局配置。返回结果是将全局配置文件封装成的对象
T getMapper(Class type);任意类型代理模式中用来获取接口的代理对象的方法

注意

mybatis中的占位符不能使用?,采用#{}

#{}要求

  • 如果输入参数是简单数据类型#{任意值}
#{sddfsdfsdfsdfsd}
  • 如果输入参数是自定义类型#{属性的属性名}
  • 如果输入参数是map类型#{key}

${}字符拼接,要求

  • 如果输入参数是简单数据类型${value}
  • 如果输入参数是自定义类型${属性的属性名}
  • 如果输入参数是map类型${key}

resultType:

同名的结果映射,如果查询结果的列名和实体类的属性名完全不一致,返回null,如果查询结果的列名有和实体类的属性名一致的,返回结果不为空,同名的封装成功,不同名,结果封装不成功采用属性的默认值。

在这里插入图片描述

package com.xxx.dao.impl;

import java.util.List;

import org.apache.ibatis.session.SqlSession;

import com.xxx.dao.UserDao;
import com.xxx.pojo.User;
import com.xxx.util.SqlSessionUtil;

public class UserDaoImpl implements UserDao {
	

	@Override
	public int insertUser(User user) {
		SqlSession session   = SqlSessionUtil.getSession();
		int flag=0;
		try {
	    flag = session.insert("user.insertUser",user);
	    int i =1/user.getAge();
	    session.commit();
		}catch(Exception ex) {
			ex.printStackTrace();
			session.rollback();
		}
		session.close();
		return flag;
	}

	@Override
	public int updateUser(User user) {
		SqlSession session   = SqlSessionUtil.getSession();
		int flag = session.insert("user.updateUser",user);
		session.close();
		return flag;
	}

	@Override
	public int deleteById(Integer id) {
		SqlSession session   = SqlSessionUtil.getSession();
		int flag = session.insert("user.deleteById",id);
		session.close();
		return flag;
	}

	@Override
	public User selectById(Integer id) {
		SqlSession session = SqlSessionUtil.getSession();
		User user = session.selectOne("user.selectUserById",id);
		session.close();
		return user;
	}

	@Override
	public List<User> selectUsers() {
		SqlSession session = SqlSessionUtil.getSession();
		List<User> users = session.selectList("user.selectUsers");
		session.close();
		return users;
	}

}

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
  PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
  "https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="user">
<!-- 如果封装结果是集合,
resultType中只需要定义集合中泛型 
如果调用selectList,resultType代表的是集合中的泛型
-->
  <select id="selectUsers" resultType="com.xxx.pojo.User">
    select * from tb_user
  </select>
  
  <insert id="insertUser" parameterType="com.xxx.pojo.User">
  	insert into tb_user(name,sex,age) values('${name}',${sex},${age})
  </insert>
  
  <update id="updateUser">
   update tb_user set name=#{name},sex=#{sex},age=#{age}
   where id=#{id}
  </update>
  
  <delete id="deleteById">
  	delete from tb_user where id=#{id}
  </delete>
  <!-- 
  mapperstatemet
  resultType:用于结果映射,进行的是同名的结果映射
   -->
  <select id="selectUserById" resultType="com.xxx.pojo.User">
  select id id1,name name2,sex sex2,age age1 from tb_user 
  </select>
  
</mapper>
数据治理是确保数据准确性、可靠性、安全性、可用性和完整性的体系和框架。它定义了组织内部如何使用、存储、保护和共享数据的规则和流程。数据治理的重要性随着数字化转型的加速而日益凸显,它能够提高决策效率、增强业务竞争力、降低风险,并促进业务创新。有效的数据治理体系可以确保数据在采集、存储、处理、共享和保护等环节的合规性和有效性。 数据质量管理是数据治理中的关键环节,它涉及数据质量评估、数据清洗、标准化和监控。高质量的数据能够提升业务决策的准确性,优化业务流程,并挖掘潜在的商业价值。随着大数据和人工智能技术的发展,数据质量管理在确保数据准确性和可靠性方面的作用愈发重要。企业需要建立完善的数据质量管理和校验机制,并通过数据清洗和标准化提高数据质量。 数据安全与隐私保护是数据治理中的另一个重要领域。随着数据量的快速增长和互联网技术的迅速发展,数据安全与隐私保护面临前所未有的挑战。企业需要加强数据安全与隐私保护的法律法规和技术手段,采用数据加密、脱敏和备份恢复等技术手段,以及加强培训和育,提高安全意识和技能水平。 数据流程管理与监控是确保数据质量、提高数据利用率、保护数据安全的重要环节。有效的数据流程管理可以确保数据流程的合规性和高效性,而实时监控则有助于及时发现并解决潜在问题。企业需要设计合理的数据流程架构,制定详细的数据管理流程规范,并运用数据审计和可视化技术手段进行监控。 数据资产管理是将数据视为组织的重要资产,通过有效的管理和利用,为组织带来经济价值。数据资产管理涵盖数据的整个生命周期,包括数据的创建、存储、处理、共享、使用和保护。它面临的挑战包括数据量的快速增长、数据类型的多样化和数据更新的迅速性。组织需要建立完善的数据管理体系,提高数据处理和分析能力,以应对这些挑战。同时,数据资产的分类与评估、共享与使用规范也是数据资产管理的重要组成部分,需要制定合理的标准和规范,确保数据共享的安全性和隐私保护,以及建立合理的利益分配和权益保障机制。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

_AndyLau

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值