MyBatis学习记录(一)

项目下载

该项目包含了代码,所需jar包和sql文件

一、MyBatis简介

MyBatis和Hibernate一样,是一个orm持久层框架。原生的jdbc操作存在大量的重复性代码(如注册驱动,创建连接,创建statement,结果集检测等)。框架的作用就是把这些繁琐的代码封装,这样可以让程序员专注于sql语句本身。而且国内目前使用Mybatis的公司比hibernate要多。mybatis相关jar包可自行到官网下载,也可用我项目提供的jar包

二、MyBatis执行流程图

在这里插入图片描述

三、MyBatis用传统的DAO实现数据的增删查改

需求:
根据用户ID查询用户信息(精准查询)
根据用户名查找用户列表(模糊查询)
添加用户
修改用户信息
根据用户ID删除用户

思路:
1、创建mysql数据库和建表并创建java项目
2、导入所需的jar包(需要用到 jdbc 的jar包)
3、编写jdbc配置文件 jdbc.properties和向控制台输出内容的日志文件 log4j.properties
4、编写mybatis的配置文件 SqlMapConfig.xml 和 sql 映射文件 user.xml
5、编写 sql 工具类 SqlSessionFactoryUtils.java
6、编写 pojo、dao接口和其实现类
7、编写测试类

项目结构图:
在这里插入图片描述

编写程序

前两个步骤在项目文件中有提供,在此就不赘述了
1、创建 jdbc.properties 和 log4j.properties

创建 jdbc.properties

该文件是用来配置数据的连接信息的,如用户名,密码等,可根据自己数据库连接信息不同进行更改。通过此种方式,在后期维护更方便,不用修改代码,改配置文件即可

jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mybatis?characterEncoding=utf-8
jdbc.username=root
jdbc.password=123456

创建 log4j.properties

编写该文件是在运行程序后能够向控制台输出一些有关sql的信息

#指定根目录下的日志级别,log4j为关键字,rootLogger表示应用根目录,console为输出设备
log4j.rootLogger=DEBUG, stdout
#定义上面的输出设备
log4j.appender.stdout=org.apache.log4j.
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n

2、工具类 SqlSessionFactoryUtils.java

编写该类是抽取部分重复代码,防止代码冗余。值得一提的是,该类中没有返回 SqlSession 对象是因为每一个线程都得使用一个sqlsession,并且sqlsession是不能共享的,它是线程不安全的

public class SqlSessionFactoryUtils {
	private static SqlSessionFactory sqlSessionFactory;
	
	//静态代码块在类被加载的时候就运行了,而且只运行一次,并且优先于各种代码块以及构造函数。
	//如果一个类中有多个静态代码块,会按照书写顺序依次执行
	static {
		try {
			SqlSessionFactoryBuilder sessionFactoryBuilder = new SqlSessionFactoryBuilder();
			InputStream inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
			// 加载配置文件,创建SqlSessionFactory对象
			sqlSessionFactory = sessionFactoryBuilder.build(inputStream);
		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
	}

	public static SqlSessionFactory getSqlSessionFactory() {
		return sqlSessionFactory;
	}

3、创建 SqlMapConfig.xml 和 user.xml

创建 SqlMapConfig.xml 全局配置文件

主要是2个标签:

environments:用于获取数据库连接池连接,与spring整合后 environments 配置将废除。

mappers:用于引用映射文件。

ps: typeAliases标签是定义别名用的(就是在映射文件属性值需要用到比如com.itheima.mybatis.pojo时,可以用别名代替,使代码简介),package标签是别名包扫描器(推荐使用此方式),整个包下的类都被定义别名,别名就是类名,不区分大小写

<?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">

<!-- dtd模式必须严格按照它的模式顺序写代码 ,如mappers必须在environments之后-->
<configuration>
	
	<!-- 加载jdbc文件-->
	<properties resource="jdbc.properties"/>
	
	<typeAliases>
	<package name="com.itheima.mybatis.pojo"/>
	</typeAliases>
	
	<environments default="development"> 
		<!-- 可配置多个environment,若配置多个environment,将 environments的default改动就行,如default="test"-->  
		<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>
	<!-- 加载映射文件 -->
	<mappers>
		<!-- 传统dao写法只有这种配置方式-->
		<mapper resource ="mybatis/user.xml"/>			
	</mappers>
</configuration>

创建 sql 映射文件 user.xml

ps: namespace是命名空间,类似项目的包,在传统dao中,namespace可随意命名,但在动态代理中,需要写接口的全路径名

{}是占位符,相当于jdbc的?,${}字符串拼接指令,如果时普通的基本类型(如string,double等),只能写value。

对数据进行增删查改对应的标签分别是 insert,delete,select,update。里面的id属性是唯一的标识,方便调用。parameterType属性是入参的类型,传入java类型,转化为sql类型。
resultType是出参的类型,执行sql语句后将sql类型转化为java数据类型并返回。

useGeneratedKeys=“true” keyProperty=“id” 的功能是主键返回,两者要配合使用,keyProperty的值是表中主键的属性名

<?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="user">
	<select id="getUserById" parameterType="int" resultType="com.itheima.mybatis.pojo.User">
				SELECT * FROM USER WHERE id = #{id}
	</select>
	
	<select id="getUserByName" parameterType="string" resultType="com.itheima.mybatis.pojo.User" >
				SELECT * FROM USER WHERE username like '%${value}%'
	</select>
	
	<insert id="insertUser" parameterType="com.itheima.mybatis.pojo.User" useGeneratedKeys="true" keyProperty="id">				
		<!-- 
		useGeneratedKeys="true" keyProperty="id" 功能是主键返回
		-->
		INSERT INTO USER
		            (`username`,
		             `birthday`,
		             `sex`,
		             `address`)
		VALUES (#{username},
		        #{birthday},
		        #{sex},
		        #{address});		
	</insert>
	
	<update id="updateUser" parameterType="com.itheima.mybatis.pojo.User">
		UPDATE USER SET username = #{username} WHERE id = #{id}
	</update>
	
	<delete id="deleteUser" parameterType="int">
		DELETE FROM `user` WHERE `id` = #{id}
	</delete>
</mapper>

4、编写 pojo、dao接口和其实现类

pojo类

package com.itheima.mybatis.pojo;

import java.util.Date;

public class User {

	private Integer id;//用户id
	private String userName;// 用户名
	private String sex;// 性别
	private Date birthday;// 生日
	private String address;// 地址
	//省略掉 set 和 get 方法

dao接口

package com.itheima.mybatis.dao;

import java.util.List;

import com.itheima.mybatis.pojo.User;

/**、
 * 用户信息持久化接口
 * @author zhang
 *
 */
public interface UserDao {
	/**
	 * 根据用户ID查询用户信息
	 * @param id
	 * @return
	 */
	User gUserById(Integer id); 	
	/**
	 * 根据用户名查询用户信息
	 * @param userName
	 * @return
	 */
	List<User> getUserByUserName(String userName);
	/**
	 * 向数据库插入用户
	 * @param user
	 */
	void insertUser(User user);
	/**
	 * 修改用户信息
	 * @param user
	 */
	void updatetUser(User user);
	
	/**
	 * 根据ID删除用户
	 * @param id
	 */
	void deletetUser(Integer id);
}

实现类

// 只展示部分代码
public class UserDaoImpl implements UserDao {

	@Override
	public User gUserById(Integer id) {
		
		SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
		SqlSession sqlSession = sqlSessionFactory.openSession();
		User user = sqlSession.selectOne("user.getUserById", id);
		sqlSession.close(); //关闭sqlSession

		return user;
	}

	@Override
	public List<User> getUserByUserName(String userName) {
		
		SqlSessionFactory sqlSessionFactory = SqlSessionFactoryUtils.getSqlSessionFactory();
		SqlSession sqlSession = sqlSessionFactory.openSession();
		List<User> list = sqlSession.selectList("user.getUserByName", userName);
		sqlSession.close();
		return list;
	}
}

4、编写测试类

// 只展示部分代码
public class UserDaoTest {

	@Test
	public void testGUserById() {
		UserDaoImpl userDaoImpl = new UserDaoImpl();
		User user = userDaoImpl.gUserById(31);
		System.out.println(user);
	}

	@Test
	public void testGetUserByUserName() {
		UserDaoImpl userDaoImpl = new UserDaoImpl();
		List<User> list = userDaoImpl.getUserByUserName("张");
		for(User user:list) {
			System.out.println(user);
		}
	}
}

四、 MyBatis用动态代理实现数据的增删查改(官方推荐)

传统的dao对数据的操作的缺点是,如果接口增加一个方法,所有实现类需要实现这个方法外,增加了代码维护的复杂度。

mybatis 使用动态代理需要符合以下四个要求:

  1. namespace必须是接口的全路径名
  2. 接口的方法名必须与映射文件的sql id一致
  3. 接口的输入参数必须与映射文件的parameterType类型一致
  4. 接口的返回类型必须与映射文件的resultType类型一致
    总结一句话就是接口的全路径名,方法名,参数类型,返回值类型必须和namespace,sql属性id,parameterType,resultType相等

下面用动态代理实现上面例子

1、重新创建包com.itheima.mybatis.mapper,里面存放接口类UserMapper.java和映射文件userMapper.xml(放在同一目录的原因待会引用映射文件要用另一种方式)。接口类只需将刚才的UserDao.java复制过去即可映射文件只需将
mapper namespace="user"这句改为
mapper namespace="com.itheima.mybatis.mapper.UserMapper"即可

部分代码

<mapper namespace="com.itheima.mybatis.mapper.UserMapper">
	<select id="getUserById" parameterType="int" resultType="user">
				SELECT * FROM USER WHERE id = #{id1}
	</select>
	
	<select id="getUserByUserName" parameterType="string" resultType="user" >
				SELECT * FROM USER WHERE username like '%${value}%'
	</select>

2、修改SqlMapConfig.xml文件,在mappers下新增 package name=“com.itheima.mybatis.mapper” 即可,name的值为接口的包路经

<!-- 加载映射文件 -->
	<mappers>
		<!-- 第一种方式,加载 resource  传统dao写法只有这种配置方式-->
 		<mapper resource ="mybatis/user.xml"/>	
 		<!-- 第二种方式,包扫描器要求(推荐使用此方式):
			 1、映射文件与接口同一目录下
			 2、映射文件名必需与接口文件名称一致(不区分大小写)
		-->
		<package name="com.itheima.mybatis.mapper"/>	
	</mappers>

3、编写测试类

//部分代码
public class UserMapperTest {

	@Test
	void testGetUserById() {
		// 加载配置得到SqlSession
		SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
		// 获取代理对象,相当于实现类,反射实现
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 查询数据
		User user = userMapper.getUserById(31);
		System.out.println(user);
		// 关闭资源
		sqlSession.close();
	}

	@Test
	void testGetUserByUserName() {
		SqlSession sqlSession = SqlSessionFactoryUtils.getSqlSessionFactory().openSession();
		// 获取代理对象
		UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
		// 查询数据
		List<User> list = userMapper.getUserByUserName("张");
		for (User user : list) {
			System.out.println(user);
		}
		// 关闭资源
		sqlSession.close();
	}
	
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值