创建Maven项目
在pom.xml文件中导包
<dependencies>
<dependency>
<groupId>junitgroupId>
<artifactId>junitartifactId>
<version>4.11version>
<scope>testscope>
dependency>
<dependency>
<groupId>org.mybatisgroupId>
<artifactId>mybatisartifactId>
<version>3.5.1version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>8.0.19version>
dependency>
dependencies>
在Java目录下建包
在resources目录下建mybatis-config.xml文件
编写实体类
连接数据库的准备
在mybatis-config.xml中写配置信息
DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<settings>
<setting name="logImpl" value="STDOUT_LOGGING"/>
settings>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///stusys?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="111111"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/StudentMapper.xml">mapper>
mappers>
configuration>
写数据库连接的工具类
public class MyBatisUtil {
static SqlSessionFactory factory=null;
static {
try {
InputStream in = Resources.getResourceAsStream("mybatis-config.xml");
factory = new SqlSessionFactoryBuilder().build(in);
} catch (IOException e) {
e.printStackTrace();
}
}
public static SqlSession getSqlSession(){
return factory.openSession();
}
}
开始写DAO层(数据连接对象)
写StudentDao接口文件
public interface StudentDao {
List<Student> select();
Student selectById(int id);
int insert(Student student);
int updata(Student student);
int deleteById(int id);
}
写映射文件StudentMapper.xml
DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="StudentMapper">
<select id="select" resultType="com.dx.entity.Student">
select * from student
select>
<select id="selectById" parameterType="int" resultType="com.dx.entity.Student">
select * from student where id=#{id}
select>
<insert id="insert" parameterType="com.dx.entity.Student">
insert into student(sname,age,gender,address,phone,remark) values(#{sname},#{age},#{gender},#{address},#{phone},#{remark})
insert>
<update id="updata" parameterType="com.dx.entity.Student">
update student set sname=#{sname},age=#{age},gender=#{gender},address=#{address},phone=#{phone},remark=#{remark} where id=#{id}
update>
<delete id="deleteById">
delete from student where id = #{id}
delete>
mapper>
写实现类
public class StudentDaoImpl implements StudentDao {
@Override
public List<Student> select() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//传入的第一个参数为:mapper文件中的命名空间名称.sql语句id
List<Student> students = sqlSession.selectList("StudentMapper.select");
sqlSession.close();
return students;
}
@Override
public Student selectById(int id) {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
//传入的第二个参数为:查询条件,如果有多个查询条件应该封装成对象(对象的成员变量名要与sql的字段名保持一致)或使用map
Student student = sqlSession.selectOne("StudentMapper.selectById",id);
sqlSession.close();
return student;
}
@Override
public int insert(Student student) {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
int result = sqlSession.insert("StudentMapper.insert", student);
//增、删、改 都需要提交事务
//jdbc默认自动提交,MyBatis默认手动提交
sqlSession.commit();
sqlSession.close();
return result;
}
@Override
public int updata(Student student) {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
int result = sqlSession.insert("StudentMapper.updata", student);
//增、删、改 都需要提交事务
//jdbc默认自动提交,MyBatis默认手动提交
sqlSession.commit();
sqlSession.close();
return result;
}
@Override
public int deleteById(int id) {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
int result = sqlSession.insert("StudentMapper.deleteById", id);
//增、删、改 都需要提交事务
//jdbc默认自动提交,MyBatis默认手动提交
sqlSession.commit();
sqlSession.close();
return result;
}
}
写测试类
public class MyTest {
@Test
public void crudTest(){
StudentDaoImpl studentDao = new StudentDaoImpl();
//查
// List student = new StudentDaoImpl().select();
// Student student = studentDao.selectById(2);
// System.out.println(student);
//增
// Student student = new Student("莎莎", 22, "1", "zhegnzhou", "1242330", "iafg");
// int res = studentDao.insert(student);
//改
// Student student = new Student(17, "shasha", 22, "1", "zhegnzhou", "1242330", "iafg");
// int res = studentDao.updata(student);
//删
int res = studentDao.deleteById(17);
if (res == 1) {
System.out.println("成功");
} else {
System.out.println("失败");
}
}
}
dao接口+mapper文件
不使用代理模式
SqlSession sqlSession = MybatisUtil.getSqlSession();
//两个参数(Mapper的命名空间名.sql标签的id , [传入的参数] )
Emp emp = sqlSession.selectOne("empNamespace.selectById", 7566);
System.out.println(emp);
sqlSession.close();
使用代理
SqlSession sqlSession = MybatisUtil.getSqlSession();
//获取Mapper代理对象 getMapper(接口.class) 返回值为当前指定接口的实现对象
DeptDao deptDao = sqlSession.getMapper(DeptDao.class);
Dept dept = deptDao.selectById(10);
System.out.println(dept);
sqlSession.close();
<settings>
<setting name="mapUnderscoreToCamelCase" value="true"/>
<setting name="logImpl" value="LOG4J"/>
settings>
<typeAliases>
<typeAlias type="com.dx.entity.Emp" alias="emp"/>
<package name="com.dx.entity"/>
typeAliases>
<environments default="mysql">
<environment id="mysql">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql:///student?serverTimezone=UTC"/>
<property name="username" value="root"/>
<property name="password" value="111111"/>
dataSource>
environment>
<environment id="oracle">
<transactionManager type="JDBC">transactionManager>
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.driver.OracleDriver"/>
<property name="url" value="jdbc:oracle:thin:localhost:1521:orcl"/>
<property name="username" value="root"/>
<property name="password" value="111111"/>
dataSource>
environment>
environments>
<mappers>
<mapper resource="mapper/EmpMapper.xml"/>
<mapper class="com.bjpowernode.dao.EmpDao"/>
<package name="com.bjpowernode.dao"/>
mappers>
# 全局日志配置
log4j.rootLogger=DEBUG, stdout
# MyBatis 日志配置
#局部日志记录配置
log4j.logger.org.mybatis.example.BlogMapper=TRACE
# 控制台输出
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %p %c.%M() --%m%n
### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.file = org.apache.log4j.DailyRollingFileAppender
log4j.appender.file.File = D:/logs/test.log
#log4j.appender.file.Append = true
#log4j.appender.file.Threshold = DEBUG
log4j.appender.file.layout = org.apache.log4j.PatternLayout
log4j.appender.file.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
### 输出DEBUG 级别以上的日志到=E://logs/error.log ###
log4j.appender.E = org.apache.log4j.DailyRollingFileAppender
log4j.appender.E.File =E://logs/error.log
log4j.appender.E.Append = true
log4j.appender.E.Threshold = ERROR
log4j.appender.E.layout = org.apache.log4j.PatternLayout
log4j.appender.E.layout.ConversionPattern = %-d{yyyy-MM-dd HH:mm:ss} [ %t:%r ] - [ %p ] %m%n
/**
* java.util.logging.Logger(JUL)
*/
private Logger logger = Logger.getLogger(Log4jTest.class);
@Test
public void run(){
//错误信息
logger.error("error日志");
//警告信息
logger.warn("warn日志");
//普通信息
logger.info("info日志");
//调试信息
logger.debug("debug日志");
//底层信息
logger.trace("trace日志");
}
自动映射
<select id="selectAll" resultType="com.dx.entity.Emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno desc
select>
手动映射
<resultMap id="ResultMap" type="emp">
<id column="empno" property="empno"/>
<result column="ename" property="ename"/>
<result column="job" property="job"/>
<result column="mgr" property="mgr"/>
<result column="hiredate" property="hiredate"/>
<result column="sal" property="sal"/>
<result column="comm" property="comm"/>
<result column="deptno" property="deptno"/>
resultMap>
<select id="selectAll2" resultMap="ResultMap">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno desc
select>
${}的sql是静态sql
#{}的sql是动态sql
<select id="selectById" parameterType="int" resultType="Emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where empno=#{empno}
select>
<select id="selectById2" parameterType="int" resultType="Emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where empno=${value}
select>
<select id="selectByEname" parameterType="String" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where ename like concat('%',#{name},'%')
select>
<select id="selectByEname2" parameterType="String" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where ename like '%${value}%'
select>
<select id="selectByEname3" parameterType="String" resultType="Emp">
<bind name="keyname" value="'%'+_parameter+'%'"/>
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp where ename like #{keyname}
select>
建议:参数为2-4个使用@Param,参数过多使用实体类或Map集合
mapper.xml
<select id="selectByParam" parameterType="map" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
where deptno=#{aaa}
and sal>=#{bbb}
select>
test.java
@Test
public void selectByMap(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
HashMap<String, Object> map = new HashMap<>();
map.put("aaa",10);
map.put("bbb",2000);
List<Emp> emps = empDao.selectByParam(map);
for (Emp emp : emps) {
System.out.println(emp);
}
sqlSession.close();
}
mapper.xml
<select id="selectByParam2" parameterType="map" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
where deptno=#{deptno}
and sal>=#{sal}
select>
dao.java接口
public List<Emp> selectByParam2(@Param(value="deptno") Integer deptno,@Param("sal") Double sal);
test.java
@Test
public void selectByMap2(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
List<Emp> emps = empDao.selectByParam2(10,3000.0);
for (Emp emp : emps) {
System.out.println(emp);
}
sqlSession.close();
}
使用sql语句
<select id="selectPage" parameterType="map" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
order by empno limit #{page},#{num}
select>
使用 RowBounds()
<select id="selectPage2" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno
select>
public List<Emp> selectPage2(RowBounds rowBounds);
//使用RowBounds(起始坐标,展示条数)实现
RowBounds rowBounds = new RowBounds(10, 5);
List<Emp> emps = empDao.selectPage2(rowBounds);
使用PageHelper插件
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelperartifactId>
<version>5.2.0version>
dependency>
<plugins>
<plugin interceptor="com.github.pagehelper.PageInterceptor">plugin>
plugins>
<select id="selectPage3" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp order by empno
select>
//使用分页插件 PageHelper.startPage(当前页码,每页条数);
PageHelper.startPage(1,5);
List<Emp> emps = empDao.selectPage3();
//在PageHelper提供一个PageInfo的分页工具类
PageInfo<Emp> pageInfo = new PageInfo<>(list);
pageInfo.getList();
System.out.println("当前页码:" + pageInfo.getPageNum());
System.out.println("每页条数:" + pageInfo.getPageSize());
System.out.println("总记录数:" + pageInfo.getTotal());
System.out.println("总页数:" + pageInfo.getPages());
System.out.println("上一页:" + pageInfo.getPrePage());
System.out.println("下一页:" + pageInfo.getNextPage());
System.out.println("是否有上一页:" + pageInfo.isHasPreviousPage());
System.out.println("是否有下一页:" + pageInfo.isHasNextPage());
System.out.println("是否为首页:" + pageInfo.isIsFirstPage());
System.out.println("是否为末页:" + pageInfo.isIsLastPage());
System.out.println("页码数组:" + Arrays.toString(pageInfo.getNavigatepageNums()));
<insert id="insert" parameterType="emp" useGeneratedKeys="true" keyColumn="empno" keyProperty="empno">
insert into emp(ename,job,mgr,hiredate,sal,comm,deptno)
values (#{ename},#{job},#{mgr},#{hiredate},#{sal},#{comm},#{deptno})
insert>
@Test
public void insertTest() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
Emp emp = new Emp("小小", "经理", 100, new Date(), 5600.0, 1000.0, 20);
System.out.println("数据插入前empno="+emp.getEmpno());
empDao.insert(emp);
System.out.println("数据插入后empno="+emp.getEmpno());
sqlSession.commit();
sqlSession.close();
}
if
<select id="selectUseIf" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
where
<if test="ename!=null and ename !='' ">
ename like concat('%',#{ename},'%')
if>
<if test="sal!=null">
and sal >= #{sal}
if>
select>
<select id="selectUseIf2" parameterType="String" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
where
<if test="_parameter!=null and _parameter !='' ">
ename = #{ename}
if>
select>
where和choose
<select id="selectUseWhere" resultType="emp">
select empno,ename,job,mgr,hiredate,sal,comm,deptno from emp
<where>
<if test="ename!=null and ename !='' ">
ename like concat('%',#{ename},'%')
if>
<if test="sal!=null">
and sal >= #{sal}
if>
where>
select>
set
<update id="updateUseSet" parameterType="emp">
update emp
<set>
<if test="ename!=null">
ename=#{ename},
if>
<if test="job!=null">
job=#{job},
if>
set>
where empno=#{empno}
update>
foreach
<delete id="deleteUseForeach" parameterType="int">
delete from emp where empno in
<foreach collection="array" open="(" close=")" separator="," item="id">
#{id}
foreach>
delete>
<delete id="deleteUseForeach2" parameterType="int">
delete from emp where empno in
<foreach collection="list" open="(" close=")" separator="," item="id">
#{id}
foreach>
delete>
Trim
<insert id="insertUseTrim" parameterType="com.dx.entity.Emp">
insert into emp
<trim prefix="(" suffix=")" suffixOverrides=",">
<if test="ename!=null"> ename, if>
<if test="job!=null"> job, if>
<if test="mgr!=null"> mgr, if>
<if test="hiredate!=null"> hiredate, if>
<if test="sal!=null"> sal, if>
<if test="comm!=null"> comm, if>
<if test="deptno!=null"> deptno, if>
trim>
<trim prefix=" values (" suffix=")" suffixOverrides=",">
<if test="ename!=null"> #{ename}, if>
<if test="job!=null"> #{job}, if>
<if test="mgr!=null"> #{mgr}, if>
<if test="hiredate!=null"> #{hiredate}, if>
<if test="sal!=null"> #{sal}, if>
<if test="comm!=null"> #{comm}, if>
<if test="deptno!=null"> #{deptno} if>
trim>
insert>
测试类
@Test
public void if_where_choose_Test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
Emp param = new Emp();
param.setEname("S");
param.setSal(1000.0);
List<Emp> empList = empDao.selectUseIf(param);
List<Emp> empList = empDao.selectUseWhere(param);
for (Emp emp : empList) {
System.out.println(emp);
}
sqlSession.close();
}
@Test
public void set_Test(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
Emp param = new Emp();
param.setEmpno(666);
param.setEname("shasha");
param.setJob("医生");
empDao.updateUseSet(param);
System.out.println("插入成功!");
sqlSession.commit();
sqlSession.close();
}
@Test
public void foreachTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
EmpDao empDao = sqlSession.getMapper(EmpDao.class);
//批量删除-数组
empDao.deleteUseForeach(new Integer[]{1,2,3,4});
//批量删除-集合
empDao.deleteUseForeach2(Arrays.asList(1,2,3,4,5,6));
sqlSession.commit();
System.out.println("删除成功");
sqlSession.close();
}
导包
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.24version>
dependency>
常用注解
@Select
@Insert
@Delete
@Update
简单的sql可以用,复杂的不推荐使用
用法
public interface UserMapper {
@Insert("insert into user (name,pwd) value (#{name},#{pwd})")
Integer insert(User user);
@Delete("delete from user where id = #{id}")
Integer delete(Integer id);
@Select("select id,name,pwd from user ")
List<User> selectAll();
/* 动态sql 写法 */
@Select("")
List<User> selectList(@Param("age") Integer age);
}
一级缓存:在同一个sqlSession中
一级缓存是内存式缓存,必须使用,不能关闭
查询时,先查询一级缓存,如果没有找到数据再发送sql语句查询数据,并将结果放到sqlSession中
@Test
public void firstCacheTest(){
SqlSession sqlSession = MybatisUtils.getSqlSession();
System.out.println("——————————————————————————第一次查询——————————————————————————");
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.selectUserById(2);
System.out.println(user);
//清空一级缓存
//sqlSession.commit();
System.out.println("——————————————————————————第二次查询——————————————————————————");
UserDao userDao2 = sqlSession.getMapper(UserDao.class);
User user2 = userDao2.selectUserById(2);
System.out.println(user2);
System.out.println("——————————————————————————两次结果对比——————————————————————————");
System.out.println(user==user2);
sqlSession.close();
}
二级缓存:在同一个SqlSessionFactory中
二级缓存有三个开关
被缓存的数据需要支持序列化,所以存储的对象必须实现可序列化接口
@Test
public void secondCacheTest(){
System.out.println("——————————————————————————第一次查询——————————————————————————");
SqlSession sqlSession = MybatisUtils.getSqlSession();
UserDao userDao = sqlSession.getMapper(UserDao.class);
User user = userDao.selectUserById(2);
System.out.println(user);
sqlSession.close();
System.out.println("——————————————————————————第二次查询——————————————————————————");
SqlSession sqlSession2 = MybatisUtils.getSqlSession();
UserDao userDao2 = sqlSession2.getMapper(UserDao.class);
User user2 = userDao2.selectUserById(2);
System.out.println(user2);
sqlSession2.close();
System.out.println("——————————————————————————两次结果对比——————————————————————————");
System.out.println(user==user2);
}
id | sname | cid |
---|---|---|
1 | 小李 | 1 |
2 | 小陈 | 2 |
3 | 小郭 | 2 |
4 | 小夏 | 1 |
id | cname |
---|---|
1 | 一班 |
2 | 二班 |
3 | 三班 |
查询学生和其所在的班级
//Dao接口
List<Student> selectStudentAndClasses();
<resultMap id="selectResultMap" type="com.dx.entity.Student">
<id column="id" property="id"/>
<result column="sname" property="sname"/>
<result column="cid" property="cid"/>
<association property="classes" javaType="com.dx.entity.Classes">
<id column="id" property="id"/>
<result column="cname" property="cname"/>
association>
resultMap>
<select id="selectStudentAndClasses" resultMap="selectResultMap">
select s.id,s.sname,s.cid,c.cname from student s join classes c on s.cid=c.id
select>
扩展:使用 代码块 和 继承
<resultMap id="BaseResultMap" type="com.dx.entity.Student">
<id column="id" property="id"/>
<result column="sname" property="sname"/>
<result column="cid" property="cid"/>
resultMap>
<resultMap id="selectResultMap2" type="com.dx.entity.Student" extends="BaseResultMap">
<association property="classes" javaType="com.dx.entity.Classes">
<id column="id" property="id"/>
<result column="cname" property="cname"/>
association>
resultMap>
<sql id="FeildList">
s.id,s.sname,s.cid,c.cname
sql>
<select id="selectStudentAndClasses2" resultMap="selectResultMap">
select <include refid="FeildList">include>
from student s join classes c on s.cid=c.id
select>
查询某个班级里的学生
Classes selectById(Integer id);
<resultMap id="BaseResultMap" type="com.dx.entity.Classes">
<id column="id" property="id"/>
<result column="cname" property="cname"/>
resultMap>
<resultMap id="selectByIdResultMap" type="com.dx.entity.Classes" extends="BaseResultMap">
<collection property="studentList" ofType="com.dx.entity.Student">
<id column="sid" property="id"/>
<result column="sname" property="sname"/>
collection>
resultMap>
<select id="selectById" resultMap="selectByIdResultMap">
select c.id,c.cname,s.id sid,s.sname from classes c left join student s on c.id=s.cid where c.id=#{id}
select>
Dao接口
Classes selectOne(Integer id);
StudentMapper.xml
<select id="selectByCid" resultType="com.dx.entity.Student">
select id,sname
from student where cid=#{cid}
select>
ClassesMapper.xml
<resultMap id="SelectOneResultMap" type="com.dx.entity.Classes" extends="BaseResultMap">
<collection property="studentList" ofType="com.dx.entity.Student"
column="id" select="com.dx.dao.StudentDao.selectByCid">
collection>
resultMap>
<select id="selectOne" parameterType="int" resultMap="SelectOneResultMap">
select id,cname
from classes
where id=#{id}
select>