Mybatis入门

掌握了这些,你才算真正的Mybatis入门😊

概述

Mybatis是SSM框架中的M,百度百科,是一个优秀的持久层框架,对jdbc过程进行封装,更加专注于SQL。本文将详细的带你快速掌握Mybatis入门操作和配置。

教程

1.jdbc存在的问题及Mybatis和hibernate的区别

jdbc存在的问题
  • 频繁对数据库进行连接的创建释放,浪费系统资源
  • sql代码不易维护
  • 如果查询多个条件,需要where 1==1等前提条件,较为麻烦
  • pojo(bean)对象和数据库有关联但是不能利用此关联简化代码
Mybatis如何解决
  • 在sqlMapConfig.xml中配置数据连接池,使用连接池管理数据库链接。
  • 将Sql语句配置在XXXXmapper.xml文件中与java代码分离
  • Mybatis自动将java对象映射至sql语句,通过statement中的parameterType定义输入参数的类型。
  • Mybatis自动将sql执行结果映射至java对象,通过statement中的resultType定义输出结果的类型。
Mybatis和hibernate的区别

Mybatis需要自己写Sql语句,而hibernate可以做到真正的只操作对象实现dao层操作,在更换数据库软件时,Mybatis需要重新编写特定的sql语句,而hibernate只需要改配置即可,由此得出mybatis无法做到数据库无关性。但是,正因为可以自己写sql语句,Mybatis可以利用其灵活的特性编写复杂的服务。

2.环境搭建

2.1下载Mybatis

下载地址

mybatis-3.2.7.jar mybatis的核心包

lib文件夹 mybatis的依赖包所在

mybatis-3.2.7.pdf mybatis使用手册

2.2.创建配置文件
db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=root
sqlMapConfig.xml

在src下创建sqlMapConfig.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>
    <!-- 是用resource属性加载外部配置文件 -->
    <properties resource="db.properties"></properties>
    
	<!-- 和spring整合后 environments配置将废除 -->
	<environments default="development">
		<environment id="development">
			<!-- 使用jdbc事务管理 -->
			<transactionManager type="JDBC" />
			<!-- 数据库连接池 -->
			<dataSource type="POOLED">
				<property name="driver" value="${jdbc.driver}" />
				<property name="url"
					value="${jdbc.url}" />
				<property name="username" value="${jdbc.username}" />
				<property name="password" value="${jdbc.password}" />
			</dataSource>
		</environment>
	</environments>
	</environments>
</configuration>

sqlMapConfig.xml是mybatis核心配置文件,配置文件内容为数据源、事务管理。

log4j.properties

src下创建log4j.properties(日志配置),代码如下

# Global logging configuration
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

mybatis默认使用log4j作为输出日志信息。

2.3创建JavaBean文件

此处需要由你自定义的表结构来写(后续介绍逆向工程可以简化此步骤)

2.4创建sql映射文件

新建包mapper,在其下创建User.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:命名空间,用于隔离sql,还有一个很重要的作用,Mapper动态代理开发的时候使用,需要指定Mapper的类路径 -->
<mapper namespace="com.heima.mapper.UserMapper">
</mapper>

加载映射文件,将users.xml添加在SqlMapConfig.xml,如下:

<mappers>
    <!-- <mapper resource="sqlmap/User.xml"/> -->
    <!-- 一般项目都用package 此方法要求mapper接口名称和mapper映射文件名称相同并且在同一目录下 -->
    <package name="com.heima.mapper"/>
</mappers>

3.写测试代码

3.1编写sql
<!-- 通过id查询一个用户 -->
<select id="findUserById" parameterType="Integer" resultType="User">
    select * from user where id = #{v}
</select>
<!-- 根据用户名模糊查询用户列表
 #{任意}		select * from user where username=? 	#{}表示占位符=='五' 错误案例:like "%'五'%"找的是中间是'五'
 ${value} 	select * from user username like '%五%'	字符串拼接	但是这种会造成sql注入
  -->
<select id="findUserByUsername"  parameterType="String" resultType="com.heima.domain.User">
    select * from user where username like "%"#{v}"%"
</select>
<!-- 添加用户 -->
<insert id="addUser"  parameterType="com.heima.domain.User">
    <!-- 添加用户返回id -->
    <selectKey keyProperty="id" resultType="Integer" order="AFTER">
        select LAST_INSERT_ID()
    </selectKey>
    insert into user (username,birthday,address,sex) 
    values (#{username},#{birthday},#{address},#{sex})
</insert>

这里我们注意到入参或者结果是我们定义的类时需要写相对路径,我们可以在sqlMapConfig加入如下代码:

<!-- 别名	包及其子包下所有类	头字母大小写都行 -->
<typeAliases>
    <package name="com.heima.domain"/>
</typeAliases>
3.2创建junit包测试

方法通用部分

//加载核心配置文件
String resource = "sqlMapConfig.xml";
InputStream in = Resources.getResourceAsStream(resource);
//创建SqlSessionFactory
SqlSessionFactory build = new SqlSessionFactoryBuilder().build(in);
//创建sqlSession
SqlSession openSession = build.openSession();

编写原始dao开发方式会发现selectOne/selectList很繁琐,我们更推荐用Mapper动态代理方式

3.3Mapper动态代理方式

在Mapper包下新建UserMapper.java接口,并把User.xml重命名UserMapper.xml(原则4用到)

Mapper接口遵循四个原则:

  1. 接口方法名 ==Mapper.xml中id名
  2. 返回值类型与Mapper.xml文件中返回值类型要一致
  3. 方法的入参类型与Mapper.xml中入参类型要一致
  4. 命名空间绑定此接口
3.4MapperTest
//SqlSession帮我生成一个实现类(给接口)
UserMapper mapper = openSession.getMapper(UserMapper.class);
User user = mapper.findUserById(10);
System.out.println(user);

4.动态sql

如果sql查询字段名和pojo的属性名不一致,需要用到resultMap

if标签,where标签,foreach标签

<sql id="select">//公共部分
    select * from user
</sql>
<!-- 根据性别和名字查询用户 where标签可以去掉第一个前and 这样可以不用写1==1-->
<select id="selectUserBySexAndUsername" parameterType="User" resultType="User">
    <include refid="select"></include>
    <where>
        <if test="sex != null and sex != ''">
            sex = #{sex}
        </if>
        <if test="username != null and username != ''">
            and username = #{username}
        </if>
    </where>
</select>
	
<!-- 根据多个id查询用户信息 id in(1,2,3)-->
<select id="selectUserByIds" parameterType="QueryVo" resultType="User">
    <include refid="select"></include>
    <where>
        <foreach collection="idList" item="id" separator="," open="id in (" close=")">
            #{id}
        </foreach>
    </where>
</select>

5.关联查询

5.1一对一查询

需要在Orders.java添加User user属性

<!-- 一对一关联查询 以订单为中心关联用户 -->
<resultMap type="Orders" id="order">
    <result column="user_id" property="userId"/>
    <!-- 只有单表查询才会主动映射,这里所有值都需要手动映射 -->
    <result column="id" property="id"/>
    <result column="createtime" property="createtime"/>
    <result column="number" property="number"/>
    <!-- 一对一 -->
    <association property="user" javaType="User">
        <result column="username" property="username"/>
    </association>
</resultMap>
<select id="selectOrdersOneToOne" resultMap="order">
    select o.id,o.user_id,o.number,o.createtime,u.username from orders o 
    left join user u on o.user_id=u.id
</select>
5.2一对多查询

需要在User.java添加List ordersList;

<!-- 一对多关联查询 -->
	<resultMap type="User" id="user">
		<id column="user_id" property="id"/>
		<result column="username" property="username"/>
		<!-- 一对多 -->
		<collection property="ordersList" ofType="Orders"><!-- ofType指定泛型 -->
			<id column="id" property="id"/>
			<result column="number" property="number"/>
			<result column="createtime" property="createtime"/>
		</collection>
	</resultMap>
	<select id="selectUserList" resultMap="user">
		select o.id,o.user_id,o.number,o.createtime,u.username from user u  
		left join orders o on o.user_id=u.id
	</select>

6. Mybatis整合spring

6.1配置头
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
	xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
	xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
	http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd
	http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-4.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
	http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util-4.0.xsd">

   <!-- 加载配置文件 -->
   <context:property-placeholder location="classpath:db.properties" />

	<!-- 数据库连接池 -->
	<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
		destroy-method="close">
		<property name="driverClassName" value="${jdbc.driver}" />
		<property name="url" value="${jdbc.url}" />
		<property name="username" value="${jdbc.username}" />
		<property name="password" value="${jdbc.password}" />
		<property name="maxActive" value="10" />
		<property name="maxIdle" value="5" />
	</bean>

	<!-- 配置SqlSessionFactory -->
	<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
		<!-- 配置mybatis核心配置文件 -->
		<property name="configLocation" value="classpath:SqlMapConfig.xml" />
		<!-- 配置数据源 -->
		<property name="dataSource" ref="dataSource" />
	</bean>
</beans>
6.2传统Dao开发
<!-- Mybatis的工厂 -->
<bean id="sqlSessionFactoryBean" class="org.mybatis.spring.SqlSessionFactoryBean">
    <!-- 注入连接池 -->
    <property name="dataSource" ref="dataSource"></property>
    <!-- 核心配置文件的位置 -->
    <property name="configLocation" value="classpath:sqlMapConfig.xml"></property>
</bean>

<!-- Dao -->
<bean id="userDao" class="com.heima.dao.UserDaoImpl">
    <!-- 注入工厂 -->
    <property name="sqlSessionFactory" ref="sqlSessionFactoryBean"></property>
</bean>
6.3Mapper动态代理开发
<!-- Mapper动态代理开发 
 <bean id="userMapper" class="org.mybatis.spring.mapper.MapperFactoryBean">
  <property name="sqlSessionFactory" ref="sqlSessionFactoryBean"></property>
  <property name="mapperInterface" value="com.heima.mapper.UserMapper"></property>
  相当于:
  //创建sqlSession
  SqlSession openSession = build.openSession();

  //SqlSession帮我生成一个实现类(给接口)
  UserMapper mapper = openSession.getMapper(UserMapper.class);

 </bean>-->

<!-- Mapper动态代理开发 扫描 自动注入工厂-->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
    <!-- 基本包 -->
    <property name="basePackage" value="com.heima.mapper"></property>
</bean>
6.4SpringTest
ApplicationContext ac = new ClassPathXmlApplicationContext("applicationContext.xml");
//UserMapper mapper = (UserMapper) ac.getBean("userMapper");Mapper动态代理开发 
UserMapper mapper = ac.getBean(UserMapper.class);//Mapper动态代理开发 扫描 自动注入工厂
User user = mapper.findUserById(10);
System.out.println(user);

7.Mybatis逆向工程

使用官方网站的Mapper自动生成工具mybatis-generator-core-1.3.2来生成po类和Mapper映射文件

导入逆向工程Project,修改配置运行即可得到

注意:

  1. 逆向工程生成的代码只能做单表查询
  2. 不能在生成的代码上进行扩展,因为如果数据库变更,需要重新使用逆向工程生成代码,原来编写的代码就被覆盖了。
  3. 一张表会生成4个文件

结语

上述基本就是Mybatis入门所有的内容啦,如果这篇文章对你有帮助的话,动动小手点个赞吧🤭

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值