org.mybatis mybatis 3.5.7 junit junit 4.12 test mysql mysql-connector-java 5.1.3
习惯上命名为
mybatis-config.xml
,这个文件名仅仅只是建议,并非强制要求。将来整合Spring之后,这个配置文件可以省略,所以大家操作时可以直接复制、粘贴。
核心配置文件主要用于配置连接数据库的环境以及MyBatis的全局配置信息
核心配置文件存放的位置是src/main/resources目录下
MyBatis中的mapper接口相当于以前的dao。但是区别在于,mapper仅仅是接口,我们不需要提供实现类
package com.atguigu.mybatis.mapper; public interface UserMapper { /** * 添加用户信息 */ int insertUser();
}
Java概念 | 数据库概念 |
---|---|
类 | 表 |
属性 | 字段/列 |
对象 | 记录/行 |
insert into t_user values(null,'张三','123',23,'女')
一个表对应一个实体类,一个实体类对应一个mapper接口,一个mapper接口对应一个映射文件
public class UserMapperTest {@Testpublic void testInsertUser() throws IOException {//读取MyBatis的核心配置文件InputStream is = Resources.getResourceAsStream("mybatis-config.xml");//获取SqlSessionFactoryBuilder对象SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();//通过核心配置文件所对应的字节输入流创建工厂类SqlSessionFactory,生产SqlSession对象SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);//获取sqlSession,此时通过SqlSession对象所操作的sql都必须手动提交或回滚事务//SqlSession sqlSession = sqlSessionFactory.openSession();//创建SqlSession对象,此时通过SqlSession对象所操作的sql都会自动提交 SqlSession sqlSession = sqlSessionFactory.openSession(true);//通过代理模式创建UserMapper接口的代理实现类对象UserMapper userMapper = sqlSession.getMapper(UserMapper.class);//调用UserMapper接口中的方法,就可以根据UserMapper的全类名匹配元素文件,通过调用的方法名匹配映射文件中的SQL标签,并执行标签中的SQL语句int result = userMapper.insertUser();//提交事务//sqlSession.commit();System.out.println("result:" + result);}
}
SqlSession sqlSession = sqlSessionFactory.openSession(true);
,传入一个Boolean类型的参数,值为true,这样就可以自动提交
log4j
log4j
1.2.17
核心配置文件中的标签必须按照固定的顺序(有的标签可以不写,但顺序一定不能乱):
properties、settings、typeAliases、typeHandlers、objectFactory、objectWrapperFactory、reflectorFactory、plugins、environments、databaseIdProvider、mappers
注意:在resources中创建多级目录时应该时以/分割
insert into t_user values(null,'admin','123456',23,'男','12345@qq.com')
delete from t_user where id = 6
update t_user set username = '张三' where id = 5
注意:
- 查询的标签select必须设置属性resultType或resultMap,用于设置实体类和数据库表的映射关系
- resultType:返回值类型,自动映射,用于属性名和表中字段名一致的情况
- resultMap:自定义映射,用于一对多或多对一或字段名和属性名不一致的情况
- 当查询的数据为多条时,不能使用实体类作为返回值,只能使用集合,否则会抛出异常TooManyResultsException;但是若查询的数据只有一条,可以使用实体类或集合作为返回值
@Test
public void checkLoginByMap() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);Map map = new HashMap<>();map.put("usermane","admin");map.put("password","123456");User user = mapper.checkLoginByMap(map);System.out.println(user);
}
insert into t_user values(null,#{username},#{password},#{age},#{sex},#{email})
@Test
public void insertUser() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);User user = new User(null,"Tom","123456",12,"男","123@321.com");mapper.insertUser(user);
}
@Test
public void checkLoginByParam() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();ParameterMapper mapper = sqlSession.getMapper(ParameterMapper.class);mapper.CheckLoginByParam("admin","123456");
}
{password=123456, sex=男, id=1, age=23, username=admin}
/*** 根据用户id查询用户信息* @param id* @return*/
User getUserById(@Param("id") int id);
/*** 查询所有用户信息* @return*/
List getUserList();
/** * 查询用户的总记录数 * @return * 在MyBatis中,对于Java中常用的类型都设置了类型别名 * 例如:java.lang.Integer-->int|integer * 例如:int-->_int|_integer * 例如:Map-->map,List-->list */
int getCount();
/** * 根据用户id查询用户信息为map集合 * @param id * @return */
Map getUserToMap(@Param("id") int id);
/** * 查询所有用户信息为map集合 * @return * 将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,此时可以将这些map放在一个list集合中获取 */
List
/*** 查询所有用户信息为map集合* @return* 将表中的数据以map集合的方式查询,一条数据对应一个map;若有多条数据,就会产生多个map集合,并且最终要以一个map的方式返回数据,此时需要通过@MapKey注解设置map集合的键,值是每条数据所对应的map集合*/
@MapKey("id") // 将map集合的键设置为id
Map getAllUserToMap();
/*** 根据用户名进行模糊查询* @param username * @return java.util.List* @date 2022/2/26 21:56*/
List getUserByLike(@Param("username") String username);
select * from t_user where username like "%"#{mohu}"%"
是最常用的delete from t_user where id in ('1,2,3')
,这样是将1,2,3
看做是一个整体,只有id为1,2,3
的数据会被删除。正确的语句应该是delete from t_user where id in (1,2,3)
,或者delete from t_user where id in ('1','2','3')
/*** 根据id批量删除* @param ids * @return int* @date 2022/2/26 22:06*/
int deleteMore(@Param("ids") String ids);
delete from t_user where id in (${ids})
//测试类
@Test
public void deleteMore() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);int result = mapper.deleteMore("1,2,3,8");System.out.println(result);
}
/*** 查询指定表中的数据* @param tableName * @return java.util.List* @date 2022/2/27 14:41*/
List getUserByTable(@Param("tableName") String tableName);
/*** 添加用户信息* @param user * @date 2022/2/27 15:04*/
void insertUser(User user);
insert into t_user values (null,#{username},#{password},#{age},#{sex},#{email})
//测试类
@Test
public void insertUser() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();SQLMapper mapper = sqlSession.getMapper(SQLMapper.class);User user = new User(null, "ton", "123", 23, "男", "123@321.com");mapper.insertUser(user);System.out.println(user);//输出:user{id=10, username='ton', password='123', age=23, sex='男', email='123@321.com'},自增主键存放到了user的id属性中
}
resultMap用来处理字段名和属性名不一致、一对多和多对一的映射关系。
可以通过为字段起别名的方式,保证和实体类中的属性名保持一致
可以在MyBatis的核心配置文件中的setting
标签中,设置一个全局配置信息mapUnderscoreToCamelCase,可以在查询表中数据时,自动将_类型的字段名转换为驼峰,例如:字段名user_name,设置了mapUnderscoreToCamelCase,此时字段名就会转换为userName。这种方式的前提必须时字段名符合数据库的规则(使用_),实体类中的属性名符合Java的规则(使用驼峰)。
核心配置文件详解
查询员工信息以及员工所对应的部门信息
public class Emp { private Integer eid; private String empName; private Integer age; private String sex; private String email; private Dept dept;//...构造器、get、set方法等
}
//EmpMapper里的方法
/*** 通过分步查询,员工及所对应的部门信息* 分步查询第一步:查询员工信息* @param * @return com.atguigu.mybatis.pojo.Emp* @date 2022/2/27 20:17*/
Emp getEmpAndDeptByStepOne(@Param("eid") Integer eid);
//DeptMapper里的方法
/*** 通过分步查询,员工及所对应的部门信息* 分步查询第二步:通过did查询员工对应的部门信息* @param* @return com.atguigu.mybatis.pojo.Emp* @date 2022/2/27 20:23*/
Dept getEmpAndDeptByStepTwo(@Param("did") Integer did);
// 在部门表中添加List集合用来存放员工信息
public class Dept {private Integer did;private String deptName;private List emps;//...构造器、get、set方法等
}
// 设置主键
/*** 通过分步查询,查询部门及对应的所有员工信息* 分步查询第一步:查询部门信息* @param did * @return com.atguigu.mybatis.pojo.Dept* @date 2022/2/27 22:04*/
Dept getDeptAndEmpByStepOne(@Param("did") Integer did);
- select:设置分布查询的sql的唯一标识(namespace.SQLId或mapper接口的全类名.方法名)
- column:设置分步查询的条件
/*** 通过分步查询,查询部门及对应的所有员工信息* 分步查询第二步:根据部门id查询部门中的所有员工* @param did* @return java.util.List* @date 2022/2/27 22:10*/
List getDeptAndEmpByStepTwo(@Param("did") Integer did);
@Test
public void getEmpAndDeptByStepOne() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptByStepOne(1);System.out.println(emp.getEmpName());
}
@Test
public void getEmpAndDeptByStepOne() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);Emp emp = mapper.getEmpAndDeptByStepOne(1);System.out.println(emp.getEmpName());System.out.println("----------------");System.out.println(emp.getDept());
}
1=1
1=1
可以用来拼接and
语句,例如:当empName为null时 select * from t_emp where and age = ? and sex = ? and email = ?
,此时where
会与and
连用,SQL语句会报错select * from t_emp where 1= 1 and age = ? and sex = ? and email = ?
,此时不报错
emp_name = #{empName} and
age = #{age}
select * from t_emp
//测试类
@Test
public void getEmpByCondition() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);List emps= mapper.getEmpByCondition(new Emp(null, "张三", null, null, null, null));System.out.println(emps);
}
choose、when、otherwise
相当于if...else if..else
@Test
public void getEmpByChoose() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);List emps = mapper.getEmpByChoose(new Emp(null, "张三", 23, "男", "123@qq.com", null));System.out.println(emps);
}
if a else if b else if c else d
,只会执行其中一个用来处理参数是集合的情况
属性:
,
批量删除
方式1:
为了能在映射文件中通过eids访问参数eids,在mapper接口方法中应该使用@Param标识参数
delete from t_emp where eid in#{eid}
方式2:delete from t_user whereid = #{id}
@Testpublic void deleteMoreByArray() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);int result = mapper.deleteMoreByArray(new Integer[]{6, 7, 8, 9});System.out.println(result);}
批量添加
insert into t_emp values(null,#{emp.empName},#{emp.age},#{emp.sex},#{emp.email},null)
@Test
public void insertMoreByList() {SqlSession sqlSession = SqlSessionUtils.getSqlSession();DynamicSQLMapper mapper = sqlSession.getMapper(DynamicSQLMapper.class);Emp emp1 = new Emp(null,"a",1,"男","123@321.com",null);Emp emp2 = new Emp(null,"b",1,"男","123@321.com",null);Emp emp3 = new Emp(null,"c",1,"男","123@321.com",null);List emps = Arrays.asList(emp1, emp2, emp3);int result = mapper.insertMoreByList(emps);System.out.println(result);
}
标签eid,emp_name,age,sex,email
标签
sqlSession.clearCache();
mybatis-config
中,设置全局配置属性cacheEnabled=“true”,默认为true,不需要设置注意:第三方缓存只能代替MyBatis中的二级缓存,不能代替MyBatis中的一级缓存。
org.mybatis.caches mybatis-ehcache 1.2.1
ch.qos.logback logback-classic 1.2.3
jar包名称 | 作用 |
---|---|
mybatis-ehcache | Mybatis和EHCache的整合包 |
ehcache | EHCache核心包 |
slf4j-api | SLF4J日志门面包 |
logback-classic | 支持SLF4J门面接口的一个具体实现 |
ehcache.xml
,放在resources目录下。
logback.xml
,名字固定,不可改变
[%d{HH:mm:ss.SSS}] [%-5level] [%thread] [%logger] [%msg]%n
属性名 | 是否必须 | 作用 |
---|---|---|
maxElementsInMemory | 是 | 在内存中缓存的element的最大数目 |
maxElementsOnDisk | 是 | 在磁盘上缓存的element的最大数目,若是0表示无穷大 |
eternal | 是 | 设定缓存的elements是否永远不过期。 如果为true,则缓存的数据始终有效, 如果为false那么还要根据timeToIdleSeconds、timeToLiveSeconds判断 |
overflowToDisk | 是 | 设定当内存缓存溢出的时候是否将过期的element缓存到磁盘上 |
timeToIdleSeconds | 否 | 当缓存在EhCache中的数据前后两次访问的时间超过timeToIdleSeconds的属性取值时, 这些数据便会删除,默认值是0,也就是可闲置时间无穷大 |
timeToLiveSeconds | 否 | 缓存element的有效生命期,默认是0.,也就是element存活时间无穷大 |
diskSpoolBufferSizeMB | 否 | DiskStore(磁盘缓存)的缓存区大小。默认是30MB。每个Cache都应该有自己的一个缓冲区 |
diskPersistent | 否 | 在VM重启的时候是否启用磁盘保存EhCache中的数据,默认是false |
diskExpiryThreadIntervalSeconds | 否 | 磁盘缓存的清理线程运行间隔,默认是120秒。每个120s, 相应的线程会进行一次EhCache中数据的清理工作 |
memoryStoreEvictionPolicy | 否 | 当内存缓存达到最大,有新的element加入的时候, 移除缓存中element的策略。 默认是LRU(最近最少使用),可选的有LFU(最不常使用)和FIFO(先进先出 |
org.mybatis mybatis 3.5.9 junit junit 4.13.2 test mysql mysql-connector-java 8.0.27 log4j log4j 1.2.17
org.mybatis.generator mybatis-generator-maven-plugin 1.3.0 org.mybatis.generator mybatis-generator-core 1.3.2 com.mchange c3p0 0.9.2 mysql mysql-connector-java 8.0.27
generatorConfig.xml
如果出现报错:Exception getting JDBC Driver
,可能是pom.xml中,数据库驱动配置错误
dependency中的驱动
mybatis-generator-maven-plugin插件中的驱动
两者的驱动版本应该相同
执行结果(需要引入log4j.xml)
selectByExample
:按条件查询,需要传入一个example对象或者null;如果传入一个null,则表示没有条件,也就是查询所有数据example.createCriteria().xxx
:创建条件对象,通过andXXX方法为SQL添加查询添加,每个条件之间是and关系,对于多个查询条件可以使用链式结构example.createCriteria().andCommissionPctIsNotNull().andDepartmentIdIsNull();
example.or().xxx
:将之前添加的条件通过or拼接其他条件@Test public void testMBG() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);EmpExample example = new EmpExample();//名字为张三,且年龄大于等于20example.createCriteria().andEmpNameEqualTo("张三").andAgeGreaterThanOrEqualTo(20);//或者did不为空example.or().andDidIsNotNull();List emps = mapper.selectByExample(example);emps.forEach(System.out::println);
}
updateByPrimaryKey
:通过主键进行数据修改,如果某一个值为null,也会将对应的字段改为null
mapper.updateByPrimaryKey(new Emp(1,"admin",22,null,"456@qq.com",3));
updateByPrimaryKeySelective()
:通过主键进行选择性数据修改,如果某个值为null,则不修改这个字段
mapper.updateByPrimaryKeySelective(new Emp(2,"admin2",22,null,"456@qq.com",3));
com.github.pagehelper pagehelper 5.2.0
PageHelper.startPage(int pageNum, int pageSize)
开启分页功能 @Test
public void testPageHelper() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//访问第一页,每页四条数据PageHelper.startPage(1,4);List emps = mapper.selectByExample(null);emps.forEach(System.out::println);
}
@Test
public void testPageHelper() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);//访问第一页,每页四条数据Page
Page{count=true, pageNum=1, pageSize=4, startRow=0, endRow=4, total=8, pages=2, reasonable=false, pageSizeZero=false}[Emp{eid=1, empName='admin', age=22, sex='男', email='456@qq.com', did=3}, Emp{eid=2, empName='admin2', age=22, sex='男', email='456@qq.com', did=3}, Emp{eid=3, empName='王五', age=12, sex='女', email='123@qq.com', did=3}, Emp{eid=4, empName='赵六', age=32, sex='男', email='123@qq.com', did=1}]
PageInfo pageInfo = new PageInfo<>(List list, intnavigatePages)
获取分页相关数据 @Test
public void testPageHelper() throws IOException {InputStream is = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();SqlSessionFactory sqlSessionFactory = sqlSessionFactoryBuilder.build(is);SqlSession sqlSession = sqlSessionFactory.openSession(true);EmpMapper mapper = sqlSession.getMapper(EmpMapper.class);PageHelper.startPage(1, 4);List emps = mapper.selectByExample(null);PageInfo page = new PageInfo<>(emps,5);System.out.println(page);
}
PageInfo{
pageNum=1, pageSize=4, size=4, startRow=1, endRow=4, total=8, pages=2,
list=Page{count=true, pageNum=1, pageSize=4, startRow=0, endRow=4, total=8, pages=2, reasonable=false, pageSizeZero=false}[Emp{eid=1, empName='admin', age=22, sex='男', email='456@qq.com', did=3}, Emp{eid=2, empName='admin2', age=22, sex='男', email='456@qq.com', did=3}, Emp{eid=3, empName='王五', age=12, sex='女', email='123@qq.com', did=3}, Emp{eid=4, empName='赵六', age=32, sex='男', email='123@qq.com', did=1}],
prePage=0, nextPage=2, isFirstPage=true, isLastPage=false, hasPreviousPage=false, hasNextPage=true, navigatePages=5, navigateFirstPage=1, navigateLastPage=2, navigatepageNums=[1, 2]}
上一篇:Hive学习——企业级调优
下一篇:Soul 云原生网关最佳实践