1.什么是Mybatis?
MyBatis是一个优秀的持久层框架,它对jdbc操作数据库的过程进行封装,使开发者只需要关注 SQL 本身,而不需要花费精力去处理例如注册驱动、创建connection、创建statement、手动设置参数、结果集检索等jdbc繁杂的过程代码。
Mybatis通过xml或注解的方式将要执行的各种statement(statement、preparedStatemnt、CallableStatement)配置起来,并通过java对象和statement中的sql进行映射生成最终执行的sql语句,最后由mybatis框架执行sql并将结果映射成java对象并返回。
2.为什么需要Mybatis?
帮助程序员将数据存入到数据库中。
方便:
传统的JDBC代码太复杂了。简化、框架、自动化。
不用Mybatis也可以。更容易上手。
优点:
简单易学灵活
sql和代码的分离,提高了可维护性。
提供映射标签,支持对象与数据库的orm字段关系映射
提供对象关系映射标签,支持对象关系组建维护
提供xml标签,支持编写动态sql。
单表的增删改查
代码
1.创建测试的数据库
use mydb;
CREATE TABLE classInfo(
cid int primary key auto_increment,
cname varchar(20),
cinfo varchar(20)
);
INSERT INTO classInfo(cname,cinfo) VALUES('移动212','普通班级');
INSERT INTO classInfo(cname,cinfo) VALUES('移动213','优秀班级');
INSERT INTO classInfo(cname,cinfo) VALUES('移动214','优秀班级');
SELECT *FROM classInfo;
2.创建一个Java项目并导入mybatis框架的jar包(在项目中创建一个lib文件夹放入mybatis框架的jar包,并导入项目中)
3.创建跟表对应的实体类(在src中创建com.yun.bean包,然后创建User实体类)
package com.yun.bean;
public class User {
private Integer cid;
private String cname;
private String cinfo;
public Integer getCid() {
return cid;
}
public void setCid(Integer cid) {
this.cid = cid;
}
public String getCname() {
return cname;
}
public void setCname(String cname) {
this.cname = cname;
}
public String getCinfo() {
return cinfo;
}
public void setCinfo(String cinfo) {
this.cinfo = cinfo;
}
@Override
public String toString() {
return "User{" +
"cid=" + cid +
", cname='" + cname + '\'' +
", cinfo='" + cinfo + '\'' +
'}';
}
}
4.创建针对表操作的接口类(在src中创建com.yun.dao包,然后创建UserDao的接口,然后在接口中定义针对数据库的增删改查等操作 )
package com.yun.dao;
import com.yun.bean.User;
import java.util.List;
public interface UserDao {
//根据id查询
User selectByuid(int cid);
//全查
List<User> selectAll();
//添加
int add(User user);
//删除
int delete(int cid);
//修改
int update(User user);
}
5.在接口的包中创建对应的mapper映射配置文件
<?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="com.yun.dao.UserDao">
<select id="selectByuid" resultType="com.yun.bean.User">
select * from classInfo where cid=#{cid};
</select>
<select id="selectAll" resultType="com.yun.bean.User">
select *from classInfo;
</select>
<insert id="add" parameterType="com.yun.bean.User">
insert into classInfo(cname,cinfo) values(#{cname},#{cinfo});
</insert>
<delete id="delete" parameterType="int">
delete from classInfo where cid=#{cid};
</delete>
<update id="update" parameterType="com.yun.bean.User">
update classInfo set cname=#{cname},cinfo=#{cinfo}where cid=#{cid};
</update>
</mapper>
6.在src目录中创建mybatis框架的核心配置文件(打印日志输出)
<?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>
<!--配置属性集,下面需要读取配置文件key对应的value-->
<properties resource="jdbc.properties" />
<settings>
<!--配置项目使用log4j的日志输出-->
<setting name="logImpl" value="log4j"/>
</settings>
<typeAliases>
<!-- <typeAlias type="com.qi.bean.User" alias="user"></typeAlias>-->
<!-- <typeAlias type="java.lang.String" alias="string"></typeAlias>-->
<!--加载com.qi.bean包中所有的类,给类默认起别名为类的名字但首字母小写-->
<package name="com.yun.bean"/>
</typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="jdbc"></transactionManager>
<dataSource type="pooled">
<property name="driver" value="${jdbc.driver}"/>
<property name="url" value="${jdbc.url}"/>
<property name="username" value="${jdbc.user}"/>
<property name="password" value="${jdbc.password}"/>
</dataSource>
</environment>
</environments>
<mappers>
<package name="com.yun.dao"/>
</mappers>
</configuration>
7.写入外部插件(在src里面创建log4j.properties)
log4j.rootLogger=TRACE,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
#log4j.appender.stdout.Target=System.err
log4j.appender.stdout.layout=org.apache.log4j.SimpleLayout
log4j.appender.logfile=org.apache.log4j.FileAppender
log4j.appender.logfile.File=wocao.log
log4j.appender.logfile.layout=org.apache.log4j.PatternLayout
log4j.appender.logfile.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %F %p %m%n
log4j.logger.mapperNS =TRACE
log4j.logger.com.mybatis=DEBUG
log4j.logger.com.mybatis.common.jdbc.SimpleDataSource=DEBUG
log4j.logger.com.mybatis.common.jdbc.ScriptRunner=DEBUG
log4j.logger.com.mybatis.sqlmap.engine.impl.SqlMapClientDelegate=DEBUG
log4j.logger.java.sql.Connection=DEBUG
log4j.logger.java.sql.Statement=DEBUG
log4j.logger.java.sql.PreparedStatement=DEBUG
log4j.logger.java.sql.ResultSet=DEBUG
log4j.logger.org.springframework=error
log4j.logger.org.apache=ERROR
log4j.logger.org.mybatis=DEBUG
8.在src里面创建jdbc.properties
jdbc.driver=com.mysql.cj.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/mydb
jdbc.user=root
jdbc.password=root
9.在测试类中进行测试 (书写代码)
package com.yun.test;
import com.yun.bean.Stu;
import com.yun.bean.User;
import com.yun.dao.UserDao;
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.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
public class UserText {
InputStream stream=null;//字节输入流
SqlSessionFactoryBuilder builder=null;//构建器对象
SqlSessionFactory factory=null;//工厂对象
SqlSession sqlSession=null;//sqlSession对象,用来完成jdbc操作
UserDao userDao=null;//接口对接
@Before
public void init() throws IOException {
stream= Resources.getResourceAsStream("mybatis.xml");
builder=new SqlSessionFactoryBuilder();
factory=builder.build(stream);
sqlSession=factory.openSession();
//根据类型创建对应的代理对象
userDao=sqlSession.getMapper(UserDao.class);
}
//根据id查询
@Test
public void textselectByid(){
User user=userDao.selectByuid(2);
System.out.println(user);
}
//全查
@Test
public void textselectAll(){
List<User> userList=userDao.selectAll();
for (User user:userList){
System.out.println(user);
}
}
//添加
@Test
public void textadd() {
User user=new User();
user.setCname("xx");
user.setCinfo("xx");
int n=userDao.add(user);
if(n>0){
System.out.println("添加成功");
}
}
//删除
@Test
public void textdelete(){
int del=userDao.delete(5);
if (del>0){
System.out.println("删除成功");
}
}
//修改
@Test
public void textupdate(){
User oldUser =userDao.selectByuid(3);
System.out.println("修改前:"+oldUser);
oldUser.setCname("移动214");
oldUser.setCinfo("优秀班级");
userDao.update(oldUser);
User newUser=userDao.selectByuid(3);
System.out.println("修改后:"+newUser);
}
@After
public void distory() throws IOException {
sqlSession.commit();
sqlSession.close();
stream.close();
}
}
10.结果展示
全查
根据id查询
修改
添加
删除
两表联查 一对一
1.在bean包中创建实体类
public class Dept {
private Integer did;
private String dname;
private String dinfo;
public Integer getDid() {
return did;
}
public void setDid(Integer did) {
this.did = did;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getDinfo() {
return dinfo;
}
public void setDinfo(String dinfo) {
this.dinfo = dinfo;
}
@Override
public String toString() {
return "Dept{" +
"did=" + did +
", dname='" + dname + '\'' +
", dinfo='" + dinfo + '\'' +
'}';
}
}
2.创建接口DeptDao实现根据id查询的接口
public interface DeptDao {
Dept selectById(int did);
}
3.创建对应的mapper映射配置文件
<select id="selectById" parameterType="int" resultType="com.qi.bean.Dept">
select * from dept where did=#{did};
</select>
4.在EmpDao中进行手动查询关联Dept,根据did查询创建查询id的接口
public interface EmpDao {
Emp selectByEid(int eid);
}
<?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.qi.dao.EmpDao">
<!--定义手动映射关系:数据库中字段 和 类的属性 的映射-->
<resultMap id="empMap" type="emp">
<id property="eid" column="eid"/>
<result property="ename" column="ename" />
<result property="job" column="job" />
<result property="sal" column="sal" />
<result property="phone" column="phone" />
<result property="address" column="address" />
<!--一对一的映射配置association:配置emp中 dept对象中的属性和表字段的对应关系-->
<association column="did" select="com.qi.dao.DeptDao.selectById" property="dept">
</association>
</resultMap>
<select id="selectByEid" parameterType="int" resultMap="empMap">
select * from emp where eid=#{eid};
</select>
</mapper>
5.进行测试(书写代码)
public class EmpTest {
InputStream stream = null;
SqlSessionFactoryBuilder builder = null;
SqlSessionFactory factory = null;
SqlSession sqlSession = null;
EmpDao empDao= null;
@Before
public void init() throws IOException {
stream = Resources.getResourceAsStream("mybatis.xml");
builder = new SqlSessionFactoryBuilder();
factory = builder.build(stream);
sqlSession = factory.openSession();
empDao = sqlSession.getMapper(EmpDao.class);
}
@Test
public void testSelectByeid(){
Emp emp=empDao.selectByEid(2);
System.out.println(emp);
}
@After
public void destory() throws IOException {
sqlSession.commit();
sqlSession.close();
stream.close();
}
}
6.结果展示
两表联查 一对多
1.在Dept中创建集合
public class Dept {
private Integer did;
private String dname;
private String dinfo;
//一个部门包含多个员工,一对多关系就是定义集合
List<Emp> emps;
public List<Emp> getEmps() {
return emps;
}
public void setEmps(List<Emp> emps) {
this.emps = emps;
}
public Integer getDid() {
return did;
}
public void setDid(Integer did) {
this.did = did;
}
public String getDname() {
return dname;
}
public void setDname(String dname) {
this.dname = dname;
}
public String getDinfo() {
return dinfo;
}
public void setDinfo(String dinfo) {
this.dinfo = dinfo;
}
@Override
public String toString() {
return "Dept{" +
"did=" + did +
", dname='" + dname + '\'' +
", dinfo='" + dinfo + '\'' +
", emps=" + emps +
'}';
}
}
2.Emp实体类
package com.qi.bean;
public class Emp {
private Integer eid;
private String ename;
private String job;
private double sal;
private String phone;
private String address;
private Integer did;
public Integer getDid() {
return did;
}
public void setDid(Integer did) {
this.did = did;
}
//一对一关系的定义:把外键的did 定义为相关联的 对象
public Integer getEid() {
return eid;
}
public void setEid(Integer eid) {
this.eid = eid;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public double getSal() {
return sal;
}
public void setSal(double sal) {
this.sal = sal;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "Emp{" +
"eid=" + eid +
", ename='" + ename + '\'' +
", job='" + job + '\'' +
", sal=" + sal +
", phone='" + phone + '\'' +
", address='" + address + '\'' +
", did=" + did +
'}';
}
}
3.根据did一对多查询在Dept接口中创建selectById方法
public interface DeptDao {
Dept selectById(int did);
}
4.创建对应的mapper映射配置文件
<?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.qi.dao.DeptDao">
<resultMap id="deptMap" type="com.qi.bean.Dept">
<id property="did" column="did"/>
<id property="dname" column="dname"/>
<id property="dinfo" column="dinfo"/>
<!--配置一对多关系:自动根据did去关联查询emp表中该did的信息-->
<collection column="did" select="com.qi.dao.EmpDao.selectByDid" property="emps">
</collection>
</resultMap>
<select id="selectById" parameterType="int" resultMap="deptMap">
select * from dept where did=#{did};
</select>
</mapper>
5.把查询的Dept中的值赋值给emps集合中 根据EmpDao中的did查询进行两表查询
public interface EmpDao {
Emp selectByDid(int did);
}
6.对应的mapper映射配置文件
<?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.qi.dao.EmpDao">
<!--定义手动映射关系:数据库中字段 和 类的属性 的映射-->
<select id="selectByDid" resultType="com.qi.bean.Emp">
select * from emp where did=#{did};
</select>
</mapper>
7.进行测试(书写代码)
public class DeptTest {
InputStream stream = null;
SqlSessionFactoryBuilder builder = null;
SqlSessionFactory factory = null;
SqlSession sqlSession = null;
DeptDao deptDao= null;
@Before
public void init() throws IOException {
stream = Resources.getResourceAsStream("mybatis.xml");
builder = new SqlSessionFactoryBuilder();
factory = builder.build(stream);
sqlSession = factory.openSession();
deptDao = sqlSession.getMapper(DeptDao.class);
}
@Test
public void testSelectByDid(){
Dept dept = deptDao.selectById(101);
System.out.println(dept);
}
@After
public void destory() throws IOException {
sqlSession.commit();
sqlSession.close();
stream.close();
}
}
8.结果展示