话说
各位读者,晚上好啊。曾经看到一篇博客大意是说初级人员除了用Java写增删改查,还会什么?CURD确实基础,就如同生活中的柴米油盐一样。不过呢,现实就是现实啊,同样的柴米油盐,也可以过出小巧精致的生活呢~
这次分享MyBatis的增删改查和部分优化。
开发环境
IDEA(2017.2.5)
Maven Web项目
目录
1、整体框架
2、CURD
3、部分优化
4、总结
1、整体框架
环境配置基于上一篇博客,这里不再赘述。
2、CURD
实现增删改查非常简单,环境配置好后,直接修改User.xml,然后编写测试方法即可。
1、User.xml
2、mybatis.xml
3、MybatisTest
1、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命名为:包名+类名 确保唯一性-->
<mapper namespace="com.hmc.mybatis.model.User">
<!--id:查询的唯一标识
resultType 查询返回的类型-->
<select id="selectUser" resultType="user">
select * from users
</select>
<!--增-->
<insert id="addUser" parameterType="User">
insert into users (name,age) values (#{name},#{age})
</insert>
<!--改-->
<update id="updateUser" parameterType="com.hmc.mybatis.model.User">
update users set name = #{name},age= #{age} where id = #{id}
</update>
<!--删-->
<delete id="delUser" parameterType="int">
delete from users where id = #{id}
</delete>
<!--这里的#{id} 只是表示一个参数,写任何都可以#{abc}也行-->
</mapper>
注意:
1)对于查,因为有返回值,所以参数类型是resultType,对于增删改,是没有返回值的,但是有参数类型,所以配置的是parameterType类型;
2)JDBC的那个年代,我们设置参数是这样的 insert into users (name,age) values(?,?); 用?来代替参数,这里改用#{}的形式;
3)框架对于增、改都是根据对象来的,所以在#{}赋值的时候,直接用对象里面的属性就可以,比如#{id}这个id就是User中的id;
2、mybatis.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="jdbc.properties"/>
<!--配置类别名;注意参数配置顺序-->
<typeAliases>
<!--配置类别名,如果是基于类的话,可以大大简化User.xml中的resultType和parameterType配置
这个时候,单独只修改一个也是可以的
But,如果有多个类,这样也很麻烦,需要配置多个别名-->
<typeAlias type="com.hmc.mybatis.model.User" alias="_User"/>
<!--基于包的别名,默认是类名(首字母小写),MyBatis对大小写不敏感,所以User user都可以-->
<package name="com.hmc.mybatis.model"/>
</typeAliases>
<environments default="development">
<!--开发环境:development
工作环境:work
测试环境:test
-->
<!--环境,默认与开发环境的默认保持一致-->
<environment id="development">
<!--基于JDBC的事务管理-->
<transactionManager type="JDBC"></transactionManager>
<dataSource type="POOLED">
<!--驱动-->
<property name="driver" value="${driver}"/>
<!--连接地址-->
<property name="url" value="${url}"/>
<!--用户名-->
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--关联实体映射文件-->
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>
1)增加-读取外部配置文件;
2)增加-使用别名
3、MybatisTest
package com.hmc.mybatis.test;
import com.hmc.mybatis.model.User;
import com.hmc.mybatis.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.jupiter.api.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
/**
* User:Meice
* 2017/11/18
*/
public class MybatisTest {
/**
* 测试-查
*/
@Test
public void test() {
//1 、加载mybatis.xml
// 法一: InputStream is = this.getClass().getClassLoader().getResourceAsStream("mybatis.xml");
SqlSession session = null;
try {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
//2、构建SqlSessionFactory
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(is);
//3、获取session
session = factory.openSession();//默认不自动提交事务
//4、执行查询
//获取对应命名空间下的select id
//List<User> users = session.selectList("com.hmc.mybatis.model.User.selectUser");
List<User> users = session.selectList(User.class.getName()+".selectUser");
//5、使用users
System.out.println(users);
} catch (IOException e) {
e.printStackTrace();
}finally{
//6、关闭资源
if(session != null) session.close();
}
}
/**
* 为避免类全名写错,通过
* User.Class.getName()的方式优化
*/
/**
* 测试-增
*/
@Test
public void testAdd() {
SqlSession sqlSession = null;
try {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
sqlSession = sqlSessionFactory.openSession(true);//默认不自动提交事务;设置为true就会自动提交
User user = new User("探春妹妹",16);
//sqlSession.insert("com.hmc.mybatis.model.User.addUser",user);
sqlSession.insert(User.class.getName()+".addUser",user);
// sqlSession.commit();
} catch (IOException e) {
e.printStackTrace();
}finally {
sqlSession.close();
}
}
/**
* 以上发现,在获取session及关闭session方面代码有重复,所以类似Hibernate一样,封装起来.
*/
/**
* 测试-改
*/
@Test
public void testUpdate() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
User user = new User("刘姥姥",66);
user.setId(6);
//sqlSession.update("com.hmc.mybatis.model.User.updateUser",user);
sqlSession.update(User.class.getName()+".updateUser",user);
MybatisUtil.CloseSqlSession(sqlSession);
}
/**
* 测试过程报错如下:
* org.apache.ibatis.exceptions.PersistenceException:
### Error updating database. Cause: java.sql.SQLSyntaxErrorException: Unknown column '刘姥姥' in 'field list'
### The error may involve com.hmc.mybatis.model.User.updateUser-Inline
### The error occurred while setting parameters
### SQL: update users set name = 刘姥姥,age= ? where id = ?
### Cause: java.sql.SQLSyntaxErrorException: Unknown column '刘姥姥' in 'field list'
你知道什么原因么?笑死我了,我修改语句是这样的:
update users set name = ${name},age= #{age} where id = #{id}
还出现了$符号,haha!
*/
/**
* 测试-删
*/
@Test
public void testDel() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
//sqlSession.delete("com.hmc.mybatis.model.User.delUser",6);
sqlSession.delete(User.class.getName()+".delUser",6);
MybatisUtil.CloseSqlSession(sqlSession);
}
/**
* 这个测试获取类全名
* 方便优化配置,避免每次写类全名,容易出错
*/
@Test
public void TestCls () {
System.out.println(User.class);
System.out.println(User.class.getName());
}
/**
* 运行结果:
* class com.hmc.mybatis.model.User
*
* class com.hmc.mybatis.model.User
com.hmc.mybatis.model.User
*/
}
以上代码在查、增方面没有优化获取SqlSession,在改和删方面都优化了。通过MybatisUtil来优化的。具体优化细节,下一个环节详细说明。
3、部分优化
1、优化1-获取SqlSession的方式
2、优化2-测试类中频繁写类全名;
3、优化3-对实体类取别名,基于包的别名
4、优化4-从配置文件读取参数;
1、优化1-获取SqlSession的方式
因为每写一个方法流程如下:加载配置文件:mybatis.xml==》构建SqlSessionFactory==》获取SqlSession,所以封装起来。
MybatisUtil
package com.hmc.mybatis.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.IOException;
import java.io.InputStream;
/**
* User:Meice
* 2017/11/19
*/
public class MybatisUtil {
/**
* 这个类的作用就是封装获取SqlSession的方法
* 便于CURD操作调用
*/
//定义获取SqlSession的方法
public static SqlSession getSqlSession() {
try {
InputStream is = Resources.getResourceAsStream("mybatis.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(is);
SqlSession sqlSession = sqlSessionFactory.openSession(true);//这里设置为自动开启事务
return sqlSession;
} catch (IOException e) {
e.printStackTrace();
return null;
}
}
//定义关闭SqlSession的方法
public static void CloseSqlSession(SqlSession sqlSession) {
sqlSession.close();
}
}
2、优化2-测试类中频繁写类全名;
我们每次调用SqlSession的CURD方法时,都需要给定一个类全名,便于直接找到。这样很容易出错,那么一长串,最开始我们是这么写的:
List<User> users = session.selectList("com.hmc.mybatis.model.User.selectUser");
优化后,我们是这么写的:
List<User> users = session.selectList(User.class.getName()+".selectUser");
这样就能避免小手一抖,然后郁闷半天。
3、优化3-对实体类取别名,基于包的别名
别名单词:alias
在配置User.xml的时,不论是resultType还是parameterType,我们都是写一长串:
<!--改-->
<update id="updateUser" parameterType="com.hmc.mybatis.model.User">
大量重复,很无聊呢。所以,怎么优化呢?别名。在mybatis.xml中配置属性typeAliases,注意配置顺序。默认有2中配置方式,一是:基于类配置(类一旦多起来,就要配置很多),二是:基于包配置。基于包配置,默认就是类名。不区分大小写。
参数配置顺序如下:
所以,简化后的配置是这样的:
<select id="selectUser" resultType="user">
select * from users
</select>
<!--增-->
<insert id="addUser" parameterType="User">
insert into users (name,age) values (#{name},#{age})
</insert>
因为不区分大小写,所以User user都可以。
4、优化4-从配置文件读取参数
优化JDBC的时候,我们开始把driver、url、username、password等配置参数写死,这样就不够灵活,后面通过读取外部配置文来优化。现在也是同样,在resources下面新增配置文件。然后在mybatis.xml中配置properties属性(注意配置顺序),通过${}来获取。
1) jdbc.properties
driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/sysmgr?serverTimezone=GMT
username=root
password=119913
2) 配置mybatis.xml
<!--配置外部读取配置文件,注意配置属性顺序-->
<properties resource="jdbc.properties"/>
3)修改获取连接方式
<property name="driver" value="${driver}"/>
......
4、总结
1、MyBatis的CURD似乎比Hibernate麻烦多了,实际上运行效率要高于Hibernate,低于JDBC;主要还是配、配、配;
2、如果读者从JDBC开始追随笔者,那么现在的优化都不是事;
3、还是那句话,配置主要参考官方文档。耐下性子看文档,对英语绝对是一个很大的提高。学以致用嘛,这样以后不用交学费,只用花时间,就可以学到很新的东西,因为你有了进入另外一个世界的钥匙。这才是学习英语的最为崇高的意义。
好了,该吃下午饭了。感觉自己成了八戒,只知道吃、吃、吃。下期再会!