这里先吐槽下,写的半天的东西,IE 浏览器弹出调试窗口导致写的东西全部没保存,搞得我还要重新用谷歌写,思路全没了,fuck.
前面学习了下 spring 的 DAO 层,说起 DAO 层,那 ORM 肯定是少不了的,ORM 的框架也比较多,做 C# 的时候用 EF,现在 Java 的话流行 SSM,所以就想着学习下 Mybatis, 参考这 EF 的几篇博客,打算 MyBatis 这块也系统的学习下,主要涉及单表增删改查,属性与列名映射,表之间关系映射,事务与锁,存储过程,缓存,Spring 与 MyBatis 结合这几块,可能随着深入的学习还会有慢慢补充.今天主要学习单表的增删改查.
一,准备
1. 引入库
这里新建了一个 maven 的 project,既然是 MyBatis, 肯定少不了 pom.xml 中引入它,同时与数据库交换,这里用的是 mysql,所以也少不了 mysql 连接库.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>Cuiyw</groupId>
<artifactId>MyBatisDemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>MyBatisDemo</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- https://mvnrepository.com/artifact/org.mybatis/mybatis -->
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.2.1</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.6</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
View Code
2. 创建 Model
既然是 ORM,那肯定也得有对象,所以创建 model. 这里创建了一个简单的 User 类.
package Cuiyw.MyBatis.Model;
public class User {@Override public String toString() {
// TODO Auto-generated method stub
return "User [id=" + Id + ", name=" + Name + ", age=" + Age + "]";
}
public int getId() {
return Id;
}
public void setId(int id) {
Id = id;
}
public String getName() {
return Name;
}
public void setName(String name) {
Name = name;
}
public int getAge() {
return Age;
}
public void setAge(int age) {
Age = age;
}
private int Id;
private String Name;
private int Age;
}
View Code
3. 创建数据库表
ORM 要做持久化,那少不了数据库,这里创建了 MyBatis 数据库,并增加了 user 表.
CREATE DATABASE `mybatis` /*!40100 DEFAULT CHARACTER SET utf8 */;
CREATE TABLE `user` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`NAME` varchar(20) DEFAULT NULL,
`age` int(11) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=3 DEFAULT CHARSET=utf8;
View Code
二,MyBatis 使用
前面算是把准备工作做完了,那下面就是开始 MyBatis 的使用了,这里主要是单表的增删改查.处理增删改查的时候首先要解决的是怎么把 User 类与数据库中的 user 表对应起来,对象关系映射那肯定得有个映射才对.于是乎 UserMapper 出现了,用它来映射数据库处理得一些操作.
<?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,namespace的值习惯上设置成包名+sql映射文件名,这样就能够保证namespace的值是唯一的
例如namespace="Cuiyw.MyBatis.DBMapping.UserMapper"就是Cuiyw.MyBatis.DBMapping(包名)+UserMapper(UserMapper.xml文件去除后缀)
-->
<mapper namespace="Cuiyw.MyBatis.DBMapping.UserMapper">
<!-- 在select标签中编写查询的SQL语句, 设置select标签的id属性为getUser,id属性值必须是唯一的,不能够重复
使用parameterType属性指明查询时使用的参数类型,resultType属性指明查询返回的结果集类型
resultType="Cuiyw.MyBatis.Model.User"就表示将查询结果封装成一个User类的对象返回
User类就是user表所对应的实体类
-->
<!--
根据id查询得到一个user对象
-->
<select id="getUser" parameterType="int"
resultType="Cuiyw.MyBatis.Model.User">
select * from user where id=#{id}
</select>
<select id="getUserList" resultType="Cuiyw.MyBatis.Model.User">
select * from user
</select>
<insert id="addUser" parameterType="Cuiyw.MyBatis.Model.User">
<selectKey resultType="java.lang.Integer" order="AFTER" keyProperty="id">
SELECT LAST_INSERT_ID()
</selectKey>
insert into user(name,age) values (#{name},#{age})
</insert>
<delete id="deleteUserById" parameterType="int">
delete from user where id=#{id}
</delete>
<update id="updateUser" parameterType="Cuiyw.MyBatis.Model.User">
update user set name=#{name},age=#{age} where id=#{id}
</update>
</mapper>
View Code
上面 UserMapper.xml 中配置了对 user 表的增删改查,有了 UserMapper.xml,算是项目中与表 user 扯上关系了,通过传入传出参数也与 User 类扯上了关系,不过还差一步,就是目前并不知道是映射到哪个数据库,地址多少,所以还需要一个数据库配置文件.这里要提下 insert,其他几个都是直接一条 sql,而 insert 与其他不一样,主要是为了演示新增返回主键值.
<?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>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC" />
<!-- 配置数据库连接信息 -->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver" />
<property name="url" value="jdbc:mysql://localhost:3306/mybatis" />
<property name="username" value="root" />
<property name="password" value="123456" />
</dataSource>
</environment>
</environments>
<mappers>
<!-- 注册UserMapper.xml文件, UserMapper.xml位于Cuiyw.MyBatis.DBMapping这个包下,所以resource写成meCuiyw/MyBatis/DBMapping/UserMapper.xml-->
<mapper resource="Cuiyw/MyBatis/DBMapping/UserMapper.xml" />
</mappers>
</configuration>
View Code
1. 新增
先了解下 insert 的属性.
parameterType: 入参的全限定类名或类型别名
keyColumn: 设置数据表自动生成的主键名.对特定数据库(如 PostgreSQL),若自动生成的主键不是第一个字段则必须设置
keyProperty: 默认值 unset,用于设置 getGeneratedKeys 方法或 selectKey 子元素返回值将赋值到领域模型的哪个属性中
useGeneratedKeys: 取值范围 true|false(默认值),设置是否使用 JDBC 的 getGenereatedKeys 方法获取主键并赋值到 keyProperty 设置的领域模型属性中.MySQL 和 SQLServer 执 auto-generated key field,因此当数据库设置好自增长主键后,可通过 JDBC 的 getGeneratedKeys 方法获取.但像 Oralce 等不支持 auto-generated key field 的数据库就不能用这种方法获取主键了
statementType: 取值范围 STATEMENT,PREPARED(默认值),CALLABLE
flushCache: 取值范围 true(默认值)|false,设置执行该操作后是否会清空二级缓存和本地缓存
timeout: 默认为 unset(依赖 jdbc 驱动器的设置),设置执行该操作的最大时限,超时将抛异常
databaseId: 取值范围 oracle|mysql 等,表示数据库厂家,元素内部可通过 `` 来为特定数据库指定不同的 sql 语句
这里有两个知识点,第一个是 commit() 提交的问题.我刚开始是按照下面写的.
//mybatis的配置文件
String resource = "DBConfig.xml";
//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession();
String statement = "Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
User user = new User();
user.setName("Cuiyw");
user.setAge(27);
int result = session.insert(statement, user);
session.close();
System.out.println(user.getId());
View Code
在 main 中运行上面的代码,也能打印出返回的主键值,但当我打开数据库表查询时并没有找到数据,当时觉得时没刷新,刷新了好几变还是没有,又去百度了下,参考其他博客发现时自己少了 session.commit(), 增加上之后发现数据库也有值了.
//mybatis的配置文件
String resource = "DBConfig.xml";
//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession();
String statement = "Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
User user = new User();
user.setName("Cuiyw");
user.setAge(27);
int result = session.insert(statement, user);
session.commit();
session.close();
System.out.println(user.getId());
View Code
但有搜了几篇文章,发现有的 insert 时也没调用 commit(), 刚开始怀疑是不是代码遗漏了,还看了下面的评论,怎么也没人说,这不科学啊,于是有继续百度查找原因,终于还是找到了,原来 SqlSessionFactory 的 openSession 中有个是带布尔值参数的方法 autoCommit,默认是 false, 代表不是自定提交,所以当我创建 session 时传入 true 后,也不用再写 commit() 方法了.
//mybatis的配置文件
String resource = "DBConfig.xml";
//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession(true);
String statement = "Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
User user = new User();
user.setName("Cuiyw");
user.setAge(27);
int result = session.insert(statement, user);
//session.commit();
session.close();
System.out.println(user.getId());
View Code
第二个是获取主键的问题.这个也是之前做 C# 的时候遇到过,所以想着看下 MyBatis 是怎么实现,除了除了上面使用 selectKey 的方式还可以在 insert 中直接配置 keyProperty 和 useGeneratedKeys.
selectKey 常用属性如下:
作用:在 insert 元素和 update 元素中插入查询语句.
keyProperty: 默认值 unset,用于设置 getGeneratedKeys 方法或 selectKey 子元素返回值将赋值到领域模型的哪个属性中
resultType:keyPropety 所指向的属性类全限定类名或类型别名
order 属性: 取值范围 BEFORE|AFTER,指定是在 insert 语句前还是后执行 selectKey 操作
statementType: 取值范围 STATEMENT,PREPARED(默认值),CALLABLE2. 删改查其实这几个是比较类似的,都是 SqlSession 中调用对应的方法.下面是先增加一个 user,然后修改,遍历和删除
public static void main(String[] args) throws IOException {
//mybatis的配置文件
String resource = "DBConfig.xml";
//使用MyBatis提供的Resources类加载mybatis的配置文件(它也加载关联的映射文件)
Reader reader = Resources.getResourceAsReader(resource);
//构建sqlSession的工厂
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(reader);
//创建能执行映射文件中sql的sqlSession
SqlSession session = sessionFactory.openSession(true);
System.out.println("新增");
String statement = "Cuiyw.MyBatis.DBMapping.UserMapper.addUser";
User user = new User();
user.setName("Cuiyw");
user.setAge(27);
int result = session.insert(statement, user);
//session.commit();
//session.close();
System.out.println(user.getId());
System.out.println("查询单个");
statement = "Cuiyw.MyBatis.DBMapping.UserMapper.getUser";
user = session.selectOne(statement, user.getId());
//session.close();
System.out.println(user.toString());
System.out.println("修改");
statement = "Cuiyw.MyBatis.DBMapping.UserMapper.updateUser";
user.setName("Cuiye Update");
result = session.update(statement, user);
System.out.println("遍历所有");
statement = "Cuiyw.MyBatis.DBMapping.UserMapper.getUserList";
List < User > users = session.selectList(statement);
// session.close();
for (int i = 0; i < users.size(); i++) {
System.out.println(users.get(i));
}
session.commit();
System.out.println("删除");
statement = "Cuiyw.MyBatis.DBMapping.UserMapper.deleteUserById";
session.delete(statement, user.getId());
System.out.println("删除之后遍历所有");
statement = "Cuiyw.MyBatis.DBMapping.UserMapper.getUserList";
users = session.selectList(statement);
session.close();
for (int i = 0; i < users.size(); i++) {
System.out.println(users.get(i));
}
}
View Code
来源: https://www.cnblogs.com/5ishare/p/8320691.html