Java框架_Mybatis框架_入门增删改查

一句话介绍Mybatis:

    Mybatis是一个优秀的持久层框架,它对jdbc操作数据库的过程进行封装,使开发不需要花费精力去处理使用原生JDBC时要进行的操作(注册驱动、创建connection、statement等)。

一句话概括Mybatis工作机制:

    Mybatis通过xml或注解配置statement(拼装sql),并通过与java对象进行映射生成最终执行的sql语句,交由框架执行后结果映射成java对象并返回。

※一个入门的Mybatis增删改查案例:

数据库表结构:

测试数据:

创建的工程结构如下(eclipse):

lib中需要导入Mybatis所需要的依赖包,并build path,而config目录下放的是相关的配置文件:

1.JDBC的配置文件——jdbc.properties:

2.框架的配置文件——mybatis.xml

框架的配置文件名称可以随便,在xml文件头只要引入mybatis框架的约束文件路径即可:

<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">

PS: 上面的mybatis-3-config.dtd即为xml格式文件的约束文件,引入它就规定了xml文件所使用的标签以及标签之间的关系。

下面是mybatis框架配置所要用到的基本配置标签:

1.configuration——根标签,即所有其他的配置标签都在包含在configuration中

2.properties——规定了所要加载读取的指定路径的properties文件,比如:

<properties resource="jdbc.properties"></properties>

即代表框架需要从jdbc.propterties中读取到数据库连接信息

3.environments——环境标签,可以看出这里的environments是复数的,即mybatis中可以配置多个环境标签,不同环境标签使用id属性区别。之所以支持配置多个环境标签,是因为有助于将SQL映射成应用于多种数据库中,enviroments标签下,需要配置的子标签如下:

<environments default="development">
<environment id="development">
	<transactionManager type="JDBC"/>
	<dataSource type="POOLED">
		<property name="driver" value="${jdbc.DriverClassName}"/>
		<property name="url" value="${jdbc.url}"/>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</dataSource>
</environment>
</environments>

    1.environment标签——配置单个环境,不同的环境以id区别

    2.transactionManager——事务管理器标签,type属性可以选择两种类型的事务管理器:JDBC/MANAGED

        JDBC事务管理机制:直接使用java.sql.Connection对象完成对事务的提交、回滚等操作

        MANAGED事务管理机制:使用WEB容器来管理事务

    3.dataSource——数据源,type属性中可以选择3种数据源类型:UNPOOLED/POOLED/JNDI

        UNPOOLED:表示Mybatis会为每一次的数据操作都去创建一个新的连接,并关闭它,适用于小规模简单程序上。

        POOLED:Mybatis会去创建一个数据库连接池,池中的每个连接会被用于数据库操作,且操作完成时该连接会被返还给连接池。适用于测试开发环境。

        JNDI:Mybatis从应用服务器向配置好的数据源获取数据库连接。适用于生产环境。

    在dataSource标签中,通过property子标签来配置数据库的连接信息(name属性需要与jdbc.properties中所配置的属性对应,通过EL表达式取值)

此处我们的框架的配置信息就写好了,完整配置如下:

<configuration>
<!-- properties标签代表加载指定路径的properties文件 -->
<properties resource="jdbc.properties"></properties>

<environments default="development">
<environment id="development">
	<transactionManager type="JDBC"/>
	<dataSource type="POOLED">
		<property name="driver" value="${jdbc.DriverClassName}"/>
		<property name="url" value="${jdbc.url}"/>
		<property name="username" value="${jdbc.username}"/>
		<property name="password" value="${jdbc.password}"/>
	</dataSource>
</environment>
</environments>

<mappers>

</mappers>

</configuration>

PS:除此之外,最后我们还要有一个mapper标签,在里面引入对象和数据库表的映射文件,由于映射文件还没写,这在后面再说,先来配置该映射文件。

在配置映射文件之前,由于mybatis是将数据库字段映射成对象的框架,所以我们还需要有对象实体:

该实体类包含的属性(一对set/get)名要和数据库表中的字段名一一对应,但数据库表中有的字段,实体类中不一定要有,看实际需求,这里就取3个字段(id,uname,age),而数据库表中有4个字段(id,uname,area,age):

此处省略set/get方法

接着再开始配置映射文件:

1.在config目录下创建user.xml(这里先暂时在config目录下创建,在后面会介绍另一种便于批量引入的映射文件的创建方式),引入mybatis映射文件的约束头:

<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

接着是mybatis框架mapper文件配置所要用到的基本配置标签:

1.mapper标签——其属性namespace,用于对sql进行分类化管理:

<mapper namespace="model.User">

</mapper>

PS:若使用Dao开发方式,映射文件的namespace任意命名;若使用Mapper接口代理的方式开发,namespace必须为接口的全名(一般规范为XxxDao.xml,然后namespace命名为包路径.XxxDao)。这两种开发方式在后面会介绍到,这里暂时任意填写。

然后我们在mapper标签中拼装要用到的sql语句:

1.通过id来进行查询:

<select id="findUserById" parameterType="java.lang.Integer" resultType="model.User">
	select * from user where id=#{id}
</select>

解释:

首先是select——表示这是一个映射查询语句,其中有几个属性:

    1.id——作为标识符,可以被用来引用这条语句,是唯一的。

    2.parameterType——表明传入这条语句的参数类的完全限定名或别名,比如根据id查询,需要传入的id值是一个int类型,那么其包装类的全限定名即为java.lang.Integer。还有需要写别名的情况在后面会介绍到。

    3.resultType——表示这条语句期望返回的类型,比如我通过id查询,返回的结果需要用一个User实体是接收它,那么期望类型就是model.User(全限定名称)。

除了select外,其余的元素为:

insert-映射插入语句

update-映射更新语句

delete-映射删除语句

select-映射查询语句

而对于#{}符号,其实是一个占位符,表示mybatis框架会接收输入的参数并赋值到sql语句当中。

这样,一个完整的映射就完成了,将mapper文件引入到上面配置文件的mapper中去:

<mappers>
<!-- 单独引入mapper文件 -->
	<mapper resource="User.xml"/>
</mappers>

 进行测试,步骤如下:

	@Test
	public void testGetFromId() throws Exception {
		//1.获取核心配置文件的数据
		InputStream in = Resources.getResourceAsStream("mybatis.xml");
		//2.获取会话工厂(会话就是连接)
		SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in);
		//3.获取会话对象(相当于jdbc当中的connection)
		SqlSession session = factory.openSession();
		//4.操作数据库
		int id = 2;
		User user = (User)session.selectOne("model.User.findUserById",id);
		System.out.println(user );
		session.close();
	}

上述的测试代码中,Resources是由Mybatis提供的专门用于读取配置文件(即mybatis.xml),并返回一个输入流对象,由于配置文件在源目录下,所以参数直接写mybatis.xml,不能写成config/mybatis.xml.因为config本身也是一个源目录,所有源目录中的文件进行编译后时放在同一个的目录中的。整个连接的过程其实和JDBC的思路是一样的。

将会话对象的获取过程封装成一个MybatisUtil:

public class MybatisUtil {
	private static SqlSessionFactory factory;
	static{
		//1.获取核心配置文件的数据
		InputStream in;
		try{
			in = Resources.getResourceAsStream("mybatis.xml");
			//2.创建会话工厂
			factory = new SqlSessionFactoryBuilder().build(in);
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	public static SqlSessionFactory getFactory(){
		return factory;
	}
}

测试代码:

	@Test
	public void testGetFromId() throws Exception {
		SqlSession session = MybatisUtil.getFactory().openSession();
		int id = 2;
		User user = (User)session.selectOne("model.User.findUserById",id);
		System.out.println(user );
		session.close();
	}

selectOne方法:查询一条记录,不能用于查询多条记录,否则报错。其中第一个参数由namespace和对应的id属性唯一决定,第二个参数表示要传入到sql语句中的参数。

该方法的返回值是一个SqlSession,需要把它强转成User类型

测试结果:

一个简单的查询案例完成。

需求2:根据用户名查询用户信息(包含模糊查询like):

<select id="findUserByName" parameterType="java.lang.String" resultType="model.User">
	select * from user where uname like '%${value}%'
</select>

注意:这里使用的不是#{}而是${},${value}表示使用参数将该值替换,用于字符串拼接,比如传进来的参数为test,那么此处拼接结果为%test%

测试:

	@Test
	public void testGetFromName() throws Exception {
		SqlSession session = MybatisUtil.getFactory().openSession();
		String name = "test";
		List<User> list = session.selectList("model.User.findUserByName",name);
		for (User user : list) {
			System.out.println(user);
		}
		session.close();
	}

由于查询结果可能有多条语句,即可能有多个对象,所以要用一个List<User>来接收

selectList可以查询一条或多条语句

测试结果:

需求3:添加用户

<insert id="addUser" parameterType="model.User">
	insert into user values(null,#{uname},null,#{age});
</insert>

插入不需要期望返回结果,插入的类型为User,对于不需要插入的值(比如主键策略为自增,就不需要插入主键)设置为null

测试:

		SqlSession session = MybatisUtil.getFactory().openSession();
		//mybatis框架默认非自动提交事务,如果进行增删改操作时,需要手动提交事务
		User user = new User();
		user.setUname("test05");
		user.setAge(22);
		session.insert("model.User.addUser",user);
		//提交事务
		session.commit();
		session.close();

注意:mybatis框架默认为非自动提交事务,所以进行增删改操作时,需要手动提交事务

测试结果:

而在实际需求中,由于主键策略为自动递增,我们有时要拿到插入对象形成记录的主键,这是可以用到主键回填标签:

<insert id="addUser" parameterType="model.User">
<!-- 插入的时候开业使用主键回填的策略,LAST_INSERT_ID() -->
<selectKey order="AFTER" keyProperty="id" resultType="int">
	select LAST_INSERT_ID()
</selectKey>
	insert into user values(null,#{uname},null,#{age});
</insert>

添加selectKey将主键返回,其中:

    order:selectKey的执行顺序,是相对于insert语句来说的,由于mysql的自增原理,执行完insert语句之后才将主键生成,所以顺序为after

    keyProperty:指定返回主键存储在pojo中的哪个属性

    resultType:返回的主键类型

    LAST_INSERT_ID():这是一个mysql函数,返回auto_increment自增列记录的id值

需求4:更新用户

<update id="updateUser" parameterType="model.User">
	update user set uname=#{uname},age=#{age} where id=#{id}
</update>

测试:

		SqlSession session = MybatisUtil.getFactory().openSession();
		User user = new User();
		user.setId(2);
		user.setUname("test02");
		user.setAge(18);
		session.update("model.User.updateUser", user);
		session.commit();
		session.close();

测试结果:

 需求5:根据id删除用户

<delete id="deleteUser" parameterType="int">
	delete from user where id=#{id}
</delete>

测试:

		SqlSession session = MybatisUtil.getFactory().openSession();
		int id = 5;
		session.update("model.User.deleteUser", id);
		session.commit();
		session.close();

猜你喜欢

转载自blog.csdn.net/m0_37808093/article/details/81005873