mybatis入门级02——基础知识
一、Mybatis框架原理
- Mybatis是一个持久层框架,是apache下的顶级项目。
- Mybatis托管到googlecode下,再后来托管到github下。
- Myabtis让程序主要将精力放在sql上,通过mybatis提供的映射方式,自由灵活生成(半自动化,大部分需要程序猿编写sql)满足需要sql语句。
- Mybatis可以将向prepareStatement中输入参数自动进行输入映射,将查询结果集灵活映射成java对象(输出映射)。
图解:
二、入门级程序浅析
1.3 Mybatis入门程序
- 环境
Jdk1.8、eclispe Version: 2018-09 (4.9.0)、mysql 5.7
Mysql驱动包
Mybatis驱动包
Mybatis依赖包 - log4j.properties
# Global logging configuration
# 在开发环境中日志级别设置成DEBUG,生产环境为info或error
log4j.rootLogger=DEBUG, stdout
# Console output...
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%5p [%t] - %m%n
- 工程目录结构
- 创建po类
com.kjgym.po.User
public class User {
private int id;
private String username;
private String sex;
private Date birthday;
private String address;
- 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命名空间,作用是对sql进行分类华管理,理解sql隔离
注意:使用mapper代理方法开发,namespace有特殊重要的作用
-->
< mapper namespace="test">
<!-- 通过用户id查询用户 -->
<!-- 通过select执行数据库查询
id:标识映射文件中的sql,
将sql语句封装到mappedstatement对象中,称为statement的id
#{}:表示一个占位符
#{id}:其中的id表示接收输入的参数,参数名称就是id,如果输入参数时简单类型,#{}中的参数名可以任意,可以是value或其他名称
parameterType:指定输入参数的类型
resultType:指定sql输出结果所映射的java对象。sqlect指定resultType表示将单挑记录映射成的java对象
-->
<select id="findUserById" parameterType="int" resultType="com.kjgym.po.User">
SELECT * FROM t_user WHERE id=#{id}
</select>
<!-- 通过用户用户名模糊查询用户 -->
<!-- resultType可能返回多条数据 ,但是将单挑记录映射成的java对象
${}:表示拼接sql,会引发sql注入。
select * from t_user where username like '%' or 1=1 or '%'
${value}:接收输入参数的内容。如果传入类型是简单类型,${}中只能使用value
-->
<select id="findUserByName" parameterType="java.lang.String" resultType="com.kjgym.po.User">
SELECT * FROM t_user WHERE username LIKE #{username}
<!--SELECT * FROM t_user WHERE username LIKE '%${username}%' -->
<!--这种传入时不需要加%了
-->
</select>
<!-- 添加用户信息 -->
<insert id="insertUser" parameterType="com.kjgym.po.User">
insert into t_user(id, username,birthday,sex,address) value(#{id}, #{username}, #{birthday}, #{sex}, #{address})
<!-- 将插入数据的主键返回,返回到user对象当中
SELECT LAST_INSERT_ID():得到刚insert进去记录的主键值,只适用于自增主键。
keyProperty:将查询到主键值设置到parameterType指定的对象的哪个属性
order:SELECT LAST_INSERT_ID()执行顺序,相对于insert语句来说它的执行顺序
resultType:指定SELECT LAST_INSERT_ID()的结果类型
-->
<selectKey keyProperty="id" order="AFTER" resultType="java.lang.Integer">
select LAST_INSERT_ID()
</selectKey>
<!-- 使用mysql的uuid()生成主键
执行过程:
首先通过uuid()得到主键,将主键设置到user对象的id属性中
其次在insert执行时,从user对象中取出id属性值
-->
<!--
<selectKey keyProperty="id" order="BEFORE" resultType="java.lang.String">
select uuid()
</selectKey>
-->
</insert>
<!-- 根据id删除用户信息 -->
<delete id="deletetUserById" parameterType="int">
delete from t_user where id = #{id}
</delete>
<!-- 更新用户信息 -->
<insert id="updateUser" parameterType="com.kjgym.po.User">
update t_user set username=#{username}, birthday=#{birthday}, sex=#{sex}, address=#{address} where id=#{id}
</insert>
</ mapper>
- 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>
<!-- 和spring整合后 environments将被废除 -->
<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/db_mybatis02?characterEncoding=utf-8"/>
<property name="username" value="root"/>
<property name="password" value="246626"/>
</dataSource>
</environment>
</environments>
<!-- 加载映射文件 -->
<mappers>
<mapper resource="sqlmap/User.xml"/>
</mappers>
</configuration>
- 添加junit包测试
A、根据id查询用户信息
B、根据名字模糊查询用户信息
C、添加用户
D、删除用户
E、更新用户
测试代码如下:
package com.kjgym.test;
import java.io.InputStream;
import java.util.Date;
import java.util.List;
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.Test;
import com.kjgym.po.User;
import org.junit.After;
import org.junit.Before;
public class Test01 {
private SqlSession sqlSession;
@Before
public void setUp() throws Exception {
// 1.得到配置文件流
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
// 2.创建会话工厂,传入mybatis的配置文件信息流
SqlSessionFactory sessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 3.通过工厂得到sqlSession
sqlSession = sessionFactory.openSession();
// 4.通过sqlSession操作数据库
// 5.最后关闭SQLSession
}
@After
public void tearDown() throws Exception {
sqlSession.close();
}
/**
* 根据ID查询用户信息
*
* @author: kangjia
* @date: 2018年11月6日下午5:25:54
* @return:
*/
@Test
public void findUserByIdTest() {
// sqlSession.selectOne(statement, parameter)
// 参数一:映射文件中statement的id,等同于namespace+“.”+statementid
// 参数二:指定和映射文件中所匹配的paramenterType类型的参数
// selectOne结果是与映射文件中所匹配的resultType类型的对象
User user = sqlSession.selectOne("test.findUserById", 3);
System.out.println(user);
}
/**
* 根据用户名模糊查询用户信息
* 可能会返回多条数据
*
* @author: kangjia
* @date: 2018年11月6日下午5:26:36
* @return:
*/
@Test
public void findUserByNameTest() {
// sqlSession.selectList(statement, parameter)
// 参数一:映射文件中statement的id,等同于namespace+“.”+statementid
// 参数二:指定和映射文件中所匹配的paramenterType类型的参数
// selectOne结果是与映射文件中所匹配的resultType类型的对象
List<User> userList = sqlSession.selectList("test.findUserByName", "%k%");
System.out.println(userList);
}
/**
* 插入用户信息
*
* @author: kangjia
* @date: 2018年11月6日下午6:03:08
* @return:
*/
@Test
public void insertUserTest() {
User user = new User();
user.setUsername("cj");
// 注意的是 在这里插入时数据库对应字段时失败了 插入了问号,解决方法:在mybatis-config.xml配置文件中,对应行改为:
// <property name="url" value="jdbc:mysql://localhost:3306/db_mybatis02?characterEncoding=utf-8"/>
user.setAddress("河北");
user.setBirthday(new Date());
user.setSex("1");
sqlSession.insert("test.insertUser", user);
// 提交事务
sqlSession.commit();
System.out.println(user);
}
/**
* 根据id删除用户信息
*
* @author: kangjia
* @date: 2018年11月6日下午6:14:27
* @return:
*/
@Test
public void deletetUserByIdTest() {
sqlSession.delete("test.deletetUserById", 6);
// 提交事务
sqlSession.commit();
}
/**
* 更新用户信息
*
* @author: kangjia
* @date: 2018年11月6日下午9:48:57
* @return:
*/
@Test
public void updateUserTest() {
User user = new User();
user.setId(8);
user.setUsername("cj");
// 注意的是 在这里插入时数据库对应字段时失败了 插入了问号,解决方法:在mybatis-config.xml配置文件中,对应行改为:
// <property name="url" value="jdbc:mysql://localhost:3306/db_mybatis02?characterEncoding=utf-8"/>
user.setAddress("河北");
user.setBirthday(new Date());
user.setSex("1");
sqlSession.update("test.updateUser", user);
// 提交事务
sqlSession.commit();
}
}
- 总结
1) #{}表示一个占位符,接收输入参数,类型可以是简单类型,pojo,hashmap。如果接受简单类型,#{}中可以写成value或其他名称。如果接收pojo对象,通过OGNL读取对象中的属性值,通过属性.属性.属性…的方式获取对象属性值。
2) ${}表示一个拼接符号,会引起sql注入。不推荐使用。接收输入参数,类型可以是简单类型,pojo,hashmap。如果接受简单类型,#{}中只能写成value。如果接收pojo对象,通过OGNL读取对象中的属性值,通过属性.属性.属性…的方式获取对象属性值。
3) 可以使用selectOne的地方也可以使用selectList,反之不能。
会报异常:org.apache.ibatis.exceptions.TooManyResultsException: Expected one result (or null) to be returned by selectOne(), but found: ……
4) 自增主键mysql主键返回,执行insert提交之前自动生成一个自增主键。通过mysql函数获取到刚插入记录的自增主键LAST_INSERT_ID(),是insert执行之后执行该方法。
5) 使用mysql的uuid()生成主键
执行过程:首先通过uuid()得到主键,将主键设置到user对象的id属性中;其次在insert执行时,从user对象中取出id属性值
6) parameterType
7) resultType