MyBatis入门
MyBatis是一个第一类持久性框架,支持自定义SQL,存储过程和高级映射。MyBatis几乎消除了所有JDBC代码和手动设置参数以及检索结果。MyBatis可以使用简单的XML或Annotations来配置和映射基元,Map接口和Java POJO(Plain Old Java Objects)到数据库记录。
优势
简化了JDBC的开发
-
能够更好的完成ORM(对象关系映射)
1.Mybatis原理图
#### 2.准备环境
(1)创建mybatisdb数据库,创建user表
Create database mybatisdb;
Use mybatisdb;
Create table user(
id int primary key auto_increment,
name varchar(100),
addr varchar(100),
age int);
Insert into user values(null,'guangtouqiang','北京',28);
Insert into user values(null,'xiongda','上海',30);
Insert into user values(null,'xiaonger','上海',19);
(2)编译器引入dtd文件
作为xml的约束文件,没连网的情况下也可以在编写xml时可以出现提示信息。
3.MyBatis入门案例( 从XML构建SqlSessionFactory)
(1)需求
利用MyBatis框架查询user表中的所有数据
(2)创建mybatisDemo的Java工程,并导入jar包
(3)创建sqlMapConfig.xml
(4)创建log4j.properties
用来打印日志文件(SQL语句),可以很清楚的看到执行的sql和执行sql使用的参数。
# Global logging configuration
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
(5)创建pojo对象
POJO对象的属性名字要和数据库表字段的名字保持一致否则无法封装结果集
package com.znonline.pojo;
/**
* User表
*/
public class User {
// id
private int id;
// 用户名
private String name;
// 地址
private String addr;
// 年龄
private int age;
public User() {
}
public User(int id, String name, String addr, int age) {
this.id = id;
this.name = name;
this.addr = addr;
this.age = age;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "User [id=" + id + ", name=" + name + ", addr=" + addr + ", age=" + age + "]";
}
}
(6) 创建映射文件UserMapper.xml
在User类的同级包下,创建UserMapper.xml,代表这个文件是User对象的映射文件
(7) sqlMapConfig.xml中引入UserMapper.xml
上面已引入
(8)创建UserTest类
package com.znonline.test;
import java.io.IOException;
import java.io.InputStream;
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.znonline.pojo.User;
/**
* 测试User
* @author zn
*/
public class UserTest {
@Test
public void FindUserAll() throws IOException {
//1.创建会话工厂
InputStream in = Resources.getResourceAsStream("sqlMapConfig.xml");
SqlSessionFactory ssf = new SqlSessionFactoryBuilder().build(in);
//2.创建Sqlsession,执行SQL
SqlSession session = ssf.openSession();
//定位SQL位置 (namespace值.id值)
List list = session.selectList("userns.all");
//3.处理结果集
for(User u:list) {
System.out.println(u);
}
//4.释放资源
session.close();
}
}
4.综合案例 - Maven工程
实现User表的CRUD
(1)准备pom.xml
4.0.0
com.znonline
mybatisDemoV2.0
0.0.1-SNAPSHOT
UTF-8
mysql
mysql-connector-java
5.1.40
junit
junit
4.11
org.mybatis
mybatis
3.2.8
log4j
log4j
1.2.17
org.apache.maven.plugins
maven-compiler-plugin
3.5.1
1.7
UTF-8
(2).创建sqlMapConfig.xml
4.0.0
com.znonline
mybatisDemoV2.0
0.0.1-SNAPSHOT
UTF-8
mysql
mysql-connector-java
5.1.40
junit
junit
4.11
org.mybatis
mybatis
3.2.8
log4j
log4j
1.2.17
org.apache.maven.plugins
maven-compiler-plugin
3.5.1
1.7
UTF-8
(3).创建log4j.properties
# Global logging configuration
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
(4).创建pojo对象
(5).主体业务
- Select
Map:
Test:
/**
* User 的CRUD操作
* @author zn
*/
public class UserTest {
// 声明会话工厂,线程安全
SqlSessionFactory ssf = null;
/**
* 测试前初始化步骤
*/
@Before
public void init() {
InputStream in;
try {
//
in = Resources.getResourceAsStream("sqlMapConfig.xml");
ssf = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 查询User表中所有数据
*/
@Test
public void findAll() {
SqlSession session = ssf.openSession();
List list = session.selectList("userns.findAll");
// 3.处理结果集
for (User u : list) {
System.out.println(u);
}
session.close();
}
/**
* 查询User表总记录数
*/
@Test
public void count() {
SqlSession session = ssf.openSession();
int count = session.selectOne("userns.count");
System.out.println("User_Table count:"+count);
session.close();
}
/**
* 根据id查询User
*/
@Test
public void findById() {
SqlSession session = ssf.openSession();
int userId = 3;
User user = session.selectOne("userns.findById", userId);
System.out.println(user);
session.close();
}
}
show:
- Insert
Map:
insert into user values(null,#{name},#{addr},#{age})
Test:
/**
* 在User中新增一条记录
*/
@Test
public void save() {
SqlSession session = ssf.openSession();
User user = new User();
user.setName("lisi");
user.setAddr("上海");
user.setAge(21);
session.insert("userns.save", user);
// MyBatis需要手动提交事务
session.commit();
session.close();
}
Log/show:
- Update
Map:
update user set age=#{age}
where name=#{name}
Test:
/**
* 修改指定User名字的年龄
*/
@Test
public void updateAgeByName() {
SqlSession session = ssf.openSession();
User user = new User();
user.setAge(25);
user.setName("zhangsan");
session.update("userns.updateAgeByName", user);
session.commit();
session.close();
}
Log/Show:
- Delete
Map:
delete from user where id=#{id}
Test:
/**
* 按id删除指定User表中数据
*/
@Test
public void deleteById() {
SqlSession session = ssf.openSession();
int id = 3;
session.delete("userns.deleteById", id);
session.commit();
session.close();
}
Log/Show:
5.mybatis入门总结
MyBatis的真正力量在于Mapped Statements。这就是魔术发生的地方。尽管功能强大,但Mapper XML文件相对简单。当然,如果您将它们与等效的JDBC代码进行比较,您会立即看到节省了95%的代码。MyBatis专注于SQL,并尽力避开您的方式。
Mapper XML文件只有几个第一类元素(按照它们应该被定义的顺序):
cache- 为给定命名空间配置缓存。
cache-ref- 从另一个命名空间引用缓存配置。
resultMap- 描述如何从数据库结果集加载对象的最复杂和最强大的元素。
parameterMap~~~~- 已弃用!老派的方式来映射参数。内联参数是首选,将来可能会删除此元素。这里没有记录。sql- 可重用的SQL块,可以被其他语句引用。
insert- 映射的INSERT语句。
update- 映射的UPDATE语句。
delete- 映射的DELETE语句。
select- 映射的SELECT语句。
接下来的部分将详细描述每个元素,从语句本身开始。
1.查询(select)
Map标签 | 相关描述 |
---|---|
id | 作为该SQL的唯一标志 |
paramentType | 代表要执行这个select语句需要传入一个类型为long的参数,即User对象的id |
resultType | 完成ORM的映射关系所在 返回的预期类型的完全限定类名或别名 对于集合,这应该是集合包含的类型,而不是集合本身的类型 |
Test查询可以使用的方法 | 相关描述 |
---|---|
selectList | 代表这次调用的select语句查询的结果集会有一条以上的数据 |
selectOne | 返回一条数据,也可以用selectList方法,返回一个指定的数据 |
2.新增(Insert)
Map标签 | 相关描述 |
---|---|
id | 作为这条SQL的唯一标志 |
ParameterType | 指定参数类型,通常制定一个对象类型 |
flushCache | 将此设置为true将导致在调用此语句时刷新第2级和本地缓存。 默认值:对于insert,update和delete语句为true。 |
timeout | 这将设置驱动程序在抛出异常之前等待数据库从请求返回的最大秒数。 默认为未设置(取决于驱动程序) |
statementType | STATEMENT,PREPARED或CALLABLE中的任何一个 默认值:PREPARED。 |
Test查询可以使用的方法 | 相关描述 |
---|---|
Insert(String statement) | 没有参数的话,直接执行查询的sql即可 |
Insert(Stringstatement,Objectparam) | 需要参数的话,可以传入 |
3.修改(update)
4.删除(delete)
6.扩展
1.别名
在sqlMapConfig.xml中,可以使用typeAliases元素来简化开发的操作
2.SQL中有特殊字符
当SQL中有特殊字符<,mybatis不能正常解析时,用括起来就解决了
``
3. #和$取值的区别
两种方式都可以获取参数的值。
推荐能用#不用$:
-
{}(推荐!)
1.相当于JDBC中的PreparedStatement,是经过预编译的,是安全的。
2.会为参数自动拼接引号。
3.执行SQL效果:select * from user whereuserId=”1”andpwd=”2”
-
${}:
1.相当于JDBC中的Statement ,未经过预编译,仅仅是取变量的值,是非安全的,存在SQL注入。
2.执行SQL效果:select * from user whereuserId=1andpwd=2