一、准备数据库
+--------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------+--------------+------+-----+---------+----------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| name | varchar(255) | YES | | NULL | |
| gender | char(1) | YES | | NULL | |
| mobile | varchar(20) | YES | | NULL | |
+--------+--------------+------+-----+---------+----------------+
二、搭建工程
2.1新建maven工程,引入jar包
<dependency>
<groupId>org.mybatis</groupId>
<artifactId>mybatis</artifactId>
<version>3.4.6</version>
</dependency>
<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>6.0.6</version>
</dependency>
2.2新建配置文件
注意配置文件要在resource下否则读不到
mybatis全局配置文件mybatis-config.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和url不能同时用-->
<properties resource="db.properties">
<property name="driver" value="com.mysql.jdbc.Driver"></property>
</properties>
<!--mybatis支持配置多环境 可以用default设置默认环境-->
<environments default="development">
<!--这个例子中的 driver 将会由 properties 元素中设置的相应值来替换。
username password 和 url 属性将会由 db.properties 文件中对应的值来替换。这样就为配置提供了诸多灵活选择。-->
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="${driver}"/>
<property name="url" value="${db.url}"/>
<property name="username" value="${db.username}"/>
<property name="password" value="${db.password}"/>
</dataSource>
</environment>
<environment id="prod">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis?useUnicode=true&serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="mapper/test01/UserMapper.xml"/>
</mappers>
</configuration>
属性也可以被传递到 SqlSessionFactoryBuilder.build()方法中。例如:
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, props);
// ... or ...
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(reader, environment, props);
属性优先级
如果属性在不只一个地方进行了配置,那么 MyBatis 将按照下面的顺序来加载:
在 properties 元素体内指定的属性首先被读取。
然后根据 properties 元素中的 resource 属性读取类路径下属性文件或根据 url 属性指定的路径读取属性文件,并覆盖已读取的同名属性。
最后读取作为方法参数传递的属性,并覆盖已读取的同名属性。
因此,通过方法参数传递的属性具有最高优先级,resource/url 属性中指定的配置文件次之,最低优先级的是 properties 属性中指定的属性。
mpper配置文件
<?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的命名空间习惯上对应mapper的java文件以保证唯一性-->
<mapper namespace="com.yjj.test01.mapper.UserMapper">
<!--id要全局唯一-->
<select id="getUser" parameterType="int" resultType="com.yjj.test01.entity.User">
select t.id,t.name from t_user t where id = #{id}
</select>
<select id="queryUser" parameterType="int" resultType="hashmap">
select t.* from t_user t where id = #{id}
</select>
<!--map只适用于返回单行记录,下面会返回全表适配时会报错-->
<select id="findAll" resultType="hashmap">
select t.* from t_user t
</select>
</mapper>
命名空间的一点注释
命名解析:为了减少输入量,MyBatis 对所有的命名配置元素(包括语句,结果映射,缓存等)使用了如下的命名解析规则。
- 完全限定名(比如“com.mypackage.MyMapper.selectAllThings”)将被直接查找并且找到即用。
- 短名称(比如“selectAllThings”)如果全局唯一也可以作为一个单独的引用。如果不唯一,有两个或两个以上的相同名称(比如“com.foo.selectAllThings ”和“com.bar.selectAllThings”),那么使用时就会收到错误报告说短名称是不唯一的,这种情况下就必须使用完全限定名。
实体类
public class User {
private Integer id;
private String name;
private String gender;
private String mobile;
//省略getter、setter
}
UserMapper.java
public interface UserMapper {
User getUser(Integer id);
Map queryUser(Integer id);
Map findAll();
}
测试类
package com.yjj.test01;
import com.yjj.test01.entity.User;
import com.yjj.test01.mapper.UserMapper;
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.Reader;
/**
* @Description:
* @Author: yinjunjie
* @CreateDate: 2018/9/10 19:52
* @Version: 1.0
*/
public class MybatisHelloWorld {
public static void main(String[] args) {
newStyle();
}
public static void oldStyle(){
String resource = "mybatis.xml";
Reader reader;
try {
//读取配置
reader = Resources.getResourceAsReader(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
//打开获取session
SqlSession session = sqlMapper.openSession();
try {
//执行sql
User user = (User) session.selectOne("com.yjj.test01.mapper.UserMapper.getUser", 1);
System.out.println(user.getId() + "," + user.getName());
} finally {
//关闭session
session.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 推荐使用
*/
public static void newStyle(){
String resource = "mybatis.xml";
Reader reader;
try {
//读取配置
reader = Resources.getResourceAsReader(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
//打开获取session
SqlSession session = sqlMapper.openSession();
try {
//执行sql
UserMapper userMapper=session.getMapper(UserMapper.class);
User user = (User) userMapper.getUser(1);
System.out.println(user.getId() + "," + user.getName());
} finally {
//关闭session
session.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
如果不出意外运行结果会输出1,殷俊杰
三、简单增删改
<?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的命名空间习惯上对应mapper的java文件以保证唯一性-->
<mapper namespace="com.yjj.test01.mapper.UserMapper">
<!--id要全局唯一-->
<!--这个语句被称作 getUser,接受一个 int(或 Integer)类型的参数,并返回一个 com.yjj.test01.entity.User 类型的对象
当没有配置别名时,必须写完全限定名-->
<select id="getUser" parameterType="int" resultType="com.yjj.test01.entity.User">
SELECT
t.*
FROM t_user t
WHERE id = #{id}
</select>
<!--这个语句被称作 queryUser,接受一个 int(或 Integer)类型的参数,并返回一个 HashMap 类型的对象,其中的键是列名,值便是结果行中的对应值。-->
<select id="queryUser" parameterType="int" resultType="hashmap">
SELECT t.*
FROM t_user t
WHERE id = #{id}
</select>
<!--map只适用于返回单行记录,下面会返回全表适配时会报错-->
<select id="findAll" resultType="hashmap">
SELECT t.*
FROM t_user t
</select>
<select id="queryAll" resultType="com.yjj.test01.entity.User">
SELECT * from t_user
</select>
<!--insert语句执行后会执行selectkey 并把返回结果注入到user对象的id属性中-->
<insert id="insert" parameterType="com.yjj.test01.entity.User">
INSERT INTO t_user (name,gender,mobile) VALUES (#{name},#{gender},#{mobile})
<selectKey resultType="java.lang.Integer" keyProperty="id">
SELECT LAST_INSERT_ID()
</selectKey>
</insert>
<delete id="delete" parameterType="int">
DELETE FROM t_user WHERE id=#{id}
</delete>
<update id="update" parameterType="com.yjj.test01.entity.User">
UPDATE t_user t set t.id=#{id}
<if test="name !=null">
, t.name=#{name}
</if>
<if test="mobile !=null">
,t.mobile=#{mobile}
</if>
<if test="gender != null">
,t.gender=#{gender}
</if>
WHERE t.id=#{id}
</update>
</mapper>
/**
* @Description:
* @Author: YinJunjie
* @CreateDate: 2018/9/14 15:11
* @Version: 1.0
*/
public class TestUser {
private static final String resource = "mybatis.xml";
private SqlSession session;
private UserMapper userMapper;
@BeforeEach
public void before() throws IOException {
//读取配置
Reader reader = Resources.getResourceAsReader(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
//打开获取session
session = sqlMapper.openSession();
userMapper=session.getMapper(UserMapper.class);
}
@AfterEach
public void after() {
session.commit();
//关闭session
session.close();
}
@Test
public void testInsert() {
List<User> userList=userMapper.queryAll();
userList.forEach(user -> System.out.println(user));
User user=new User();
user.setName("三狗子");
user.setGender("1");
user.setMobile("110");
System.out.println(userMapper.insert(user));
System.out.println("userId:"+user.getId());
}
@Test
public void testDelete(){
int i=userMapper.delete(8);
List<User> userList=userMapper.queryAll();
userList.forEach(user -> System.out.println(user));
}
@Test
public void update(){
User user=userMapper.getUser(7);
user.setMobile("333333");
int i=userMapper.update(user);
System.out.println(i);
User user1=userMapper.getUser(user.getId());
System.out.println(user1);
}
}
package com.yjj.test01;
import com.yjj.test01.entity.User;
import com.yjj.test01.mapper.UserMapper;
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.*;
import java.io.IOException;
import java.io.Reader;
import java.util.List;
/**
* @Description:
* @Author: YinJunjie
* @CreateDate: 2018/9/14 15:11
* @Version: 1.0
*/
public class TestUser {
private static final String resource = "mybatis.xml";
private SqlSession session;
private UserMapper userMapper;
@BeforeEach
public void before() throws IOException {
//读取配置
Reader reader = Resources.getResourceAsReader(resource);
//创建SqlSessionFactory
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
//打开获取session
session = sqlMapper.openSession();
userMapper=session.getMapper(UserMapper.class);
}
@AfterEach
public void after() {
session.commit();
//关闭session
session.close();
}
@Test
public void testInsert() {
List<User> userList=userMapper.queryAll();
userList.forEach(user -> System.out.println(user));
User user=new User();
user.setName("三狗子");
user.setGender("1");
user.setMobile("110");
System.out.println(userMapper.insert(user));
//如果不写selectKey插入后的id不会注入到对象中
System.out.println("userId:"+user.getId());
}
@Test
public void testDelete(){
int i=userMapper.delete(8);
List<User> userList=userMapper.queryAll();
userList.forEach(user -> System.out.println(user));
}
@Test
public void update(){
User user=userMapper.getUser(7);
user.setMobile("333333");
int i=userMapper.update(user);
System.out.println(i);
User user1=userMapper.getUser(user.getId());
System.out.println(user1);
}
}
关于selectKey描述如下
<selectKey
keyProperty="id"
resultType="int"
order="BEFORE"
statementType="PREPARED">
属性描述
- keyProperty
selectKey 语句结果应该被设置的目标属性。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 - keyColumn
匹配属性的返回结果集中的列名称。如果希望得到多个生成的列,也可以是逗号分隔的属性名称列表。 - resultType
结果的类型。MyBatis 通常可以推算出来,但是为了更加确定写上也不会有什么问题。MyBatis 允许任何简单类型用作主键的类型,包括字符串。如果希望作用于多个生成的列,则可以使用一个包含期望属性的 Object 或一个 Map。 - order
这可以被设置为 BEFORE 或 AFTER。如果设置为 BEFORE,那么它会首先选择主键,设置 keyProperty 然后执行插入语句。如果设置为 AFTER,那么先执行插入语句,然后是 selectKey 元素 - 这和像 Oracle 的数据库相似,在插入语句内部可能有嵌入索引调用。 - statementType
MyBatis 支持 STATEMENT,PREPARED 和 CALLABLE 语句的映射类型,分别代表 PreparedStatement 和 CallableStatement 类型。