mybatis的基本使用
Config配置文件(用于告诉java代码去连接哪一个数据库进行操作)
<?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>
<settings>
<!--在控制台输出发送的sql日志-->
<setting name="logImpl" value="STDOUT_LOGGING"/>
</settings>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<!--目前只关注这部分内容,它的作用就是声明要连接的数据信息-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.cj.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/mybatis"/> //自己的数据库
<property name="username" value="root"/> //用户名
<property name="password" value="1234"/> //密码
</dataSource>
</environment>
</environments>
<mappers>
<!--声明含有sql的接口所在包-->
<package name="com.itheima.mapper"/>
</mappers>
</configuration>
Mapper层
// 1. 这是一个接口
// 2. 接口名:操作的表名+Mapper
public interface UserMapper {
// #{}里面的内容
// 1. 如果参数是对象类型,#{}写的是对象的属性名
@Insert("insert into user values (null,#{name},#{age},#{gender},#{phone})")
void save(User user);
// @Options
// useGeneratedKeys 拿到自增主键
// keyProperty 指定哪个字段是主键
@Options(useGeneratedKeys = true, keyProperty = "id")
@Insert("insert into user values (null,#{name},#{age},#{gender},#{phone})")
void save2(User user);
@Update("update user set name = #{name},age=#{age},gender=#{gender},phone = #{phone} where id=#{id} ")
void update(User user);
@Delete("delete from user where id = #{id}")
void delete(Integer id);
@Delete("delete from user where name = #{name}")
void deleteByName1(String name);
@Delete("delete from user where name = ${name}")
void deleteByName2(String name);
}
测试类
public class UserMapperTest {
@Test
public void testSave() throws IOException {
// 1. 创建对象
User user = new User();
user.setName("张三");
user.setAge(18);
user.setGender(1);
user.setPhone("15515847153");
// 工具类获取sqlSession
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 获取UserMapper对象,调用方法
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.save(user);
// 工具类关闭sqlSession
MyBatisUtil.close(sqlSession);
}
@Test
public void testDeleteByName1() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.deleteByName1("张三");
// delete from user where name = '张三'
MyBatisUtil.close(sqlSession);
}
@Test
public void testDeleteByName2() {
SqlSession sqlSession = MyBatisUtil.getSqlSession();
// 用户名叫作:'李四' or id>1
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
userMapper.deleteByName2(" '李四' or id>1"); // ${}会产生sql注入问题
// delete from user where name = '李四' or id>1
MyBatisUtil.close(sqlSession);
}
}
驼峰映射
当表中字段和类中属性的关系是_和驼峰写法时,可以开启mybatis的自动驼峰映射
<setting name="mapUnderscoreToCamelCase" value="true"/>
起别名
当表中字段和类中属性完全没有关系时,可以使用别名来修改sql返回集中字段的名称
给不对应的字段起别名
//查询
@Select("select id, username, password, name, gender, image, job, entrydate as ed, dept_id, create_time, update_time from emp")
List<Emp> findAll2();
测试
//查询所有
@Test
public void testFindAll2() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> empList = empMapper.findAll2();
empList.forEach(e -> System.out.println(e));//lambda方式打印
MybatisUtil.close(sqlSession);
}
自定义映射
当表中字段和类中属性完全没有关系时,可以通过@Results进行手动结果映射
自定义结果映射
//查询
@Results({//@Results: 自定义结果映射
@Result(column = "entrydate", property = "ed"),//@Result一条映射规则 (column = "数据表中字段名", property = "实体类属性名")
@Result(column = "dept_id", property = "deptId")
})
@Select("select * from emp")
List<Emp> findAll3();
测试
//查询所有
@Test
public void testFindAll3() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> empList = empMapper.findAll3();
empList.forEach(e -> System.out.println(e));//lambda方式打印
MybatisUtil.close(sqlSession);
}
条件查询
当查询方法出现多个查询条件时,需要使用@Param注解设置对应关系
添加条件查询的方法
//#{} 里面的内容
//1. 如果参数是一个对象类型, #{}写的是对象中的属性名
//2. 如果参数是一个简单类型(8基本 + 8包装 +String) ,#{}可以随便写, 但是推荐写方法形参名
//3. 如果参数是多个简单类型的参数, #{}中写的是@Param注解中的值
//条件查询
@Select("select * from emp where name = #{name} and gender = #{gender} and entrydate between #{begin} and #{end}")
List<Emp> findList(@Param("name") String name, @Param("gender") Short gender, @Param("begin") LocalDate begin, @Param("end") LocalDate end);
测试
//条件查询
@Test
public void testFindList() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> empList = empMapper.findList("张三丰", (short) 1, LocalDate.of(2002, 01, 01), LocalDate.of(2023, 12, 31));
empList.forEach(e -> System.out.println(e));//lambda方式打印
MybatisUtil.close(sqlSession);
}
模糊查询
当查询sql中出现模糊查询语法时,需要使用concat函数连接条件,比如根据用户名进行模糊查询 `where name like '%张%'----------------->where name like concat('%',#{username},'%')
** 添加条件查询的方法**
//模糊查询
@Select("select * from emp where name like concat('%',#{name},'%') and gender = #{gender} and entrydate between #{begin} and #{end}")
List<Emp> findListLike(@Param("name") String name, @Param("gender") Short gender, @Param("begin") LocalDate begin, @Param("end") LocalDate end);
** 测试 **
//模糊查询
@Test
public void testFindListLike() {
SqlSession sqlSession = MybatisUtil.getSqlSession();
EmpMapper empMapper = sqlSession.getMapper(EmpMapper.class);
List<Emp> empList = empMapper.findListLike("张", (short) 1, LocalDate.of(2002, 01, 01), LocalDate.of(2023, 12, 31));
empList.forEach(e -> System.out.println(e));//lambda方式打印
MybatisUtil.close(sqlSession);
}
util工具类(进行处理的类 导入即可)
public class MybatisUtil {
private static SqlSessionFactory sqlSessionFactory = null;
//保证SqlSessionFactory仅仅创建一次
static {
try {
//读取配置文件
InputStream stream = Resources.getResourceAsStream("SqlMapConfig.xml");
//创建SqlSessionFactory
sqlSessionFactory = new SqlSessionFactoryBuilder().build(stream);
} catch (Exception e) {
e.printStackTrace();
}
}
//获取sqlSession
public static SqlSession getSqlSession() {
return sqlSessionFactory.openSession();
}
//提交事务 关闭sqlSession
public static void close(SqlSession sqlSession) {
if (sqlSession != null) {
//提交事务
sqlSession.commit();
//释放资源
sqlSession.close();
}
}
}
批量添加数据
<insert id="insertEmp">
insert into emp(id,username,pasword,name,gender,create_time,update_time)
values
<foreach collection="empList"item="emp"separator=",">
(null,#{emp.username},#{emp.password},#{emp.name},#{emp.gender},now(),now())
</foreach>
</insert>
接口中
void insertEmp(@Param("empList") List<emp> empList);
测试类
public void insertEmp(){
SqlSession sqlSession=MybatisUtil.getSqlSession();
EmpMapper mapper=sqlSession.getMapper(EmpMapper.class);
ArrayList<Emp> empList=new ArrayList<>(;
for(int i=0;i<1000;i++){
Emp.emp=new Emp();
emp.setUsernmae("乐迪来喽"+i);
emp.setPassword("1234");
emp.setName("李四"+i);
empList.add(emp)
}
mapper.inserEmp(empList);
MybatisUtil.close(sqlSession);
}
sql中#和$符的区别
- #表示占位符,防止SQL注入问题,同类型SQL只能编译一次 (在{}中写的数据默认添加单引号) 2.$表示字符串的拼接,存在SQL注入问题,每次SQL都重新编译 (在{}中写的数据写啥就是啥)