目录
一、Mybatis中的增删改操作
1、单个insert
mapper接口中
/**
* 增加一本书
*/
int addBook(BookEntity bookEntity);
①使用xml写sql
<!-- 因为配置了别名,所以parameterType不需要写全类名-->
<insert id="addBook" parameterType="BookEntity">
-- 参数与BookEntity中的属性对应,因为mybatis会调用get方法获取BookEntity中的属性
insert into books values (#{id},#{name},#{price})
</insert>
②使用注解
@Insert("insert into books values (#{id},#{name},#{price})")
int addBook(BookEntity bookEntity);
测试:
@Test
public void test(){
BookEntity bookEntity=new BookEntity();
bookEntity.setId(3);
bookEntity.setName("Mybatis从入门到精通");
bookEntity.setPrice(88);
int i = bookMapper.addBook(bookEntity);
if (i==1){
System.out.println("添加成功");
}else {
System.out.println("添加失败");
}
}
2、单个delete
/**
* 根据id删除图书
*/
int deleteBookById(Integer id);
①使用xml写sql
<delete id="deleteBookById" parameterType="java.lang.Integer">
delete from books where id=#{id}
</delete>
②使用注解
@Delete("delete from books where id=#{id}")
int deleteBookById(Integer id);
测试
@Test
public void test(){
int i = bookMapper.deleteBookById(3);
if (i>0){
System.out.println("删除成功");
}
else {
System.out.println("删除失败");
}
}
3、批量select
/**
* 查询全部
*/
List<BookEntity> selectList();
①使用xml写sql
<!-- 查List的时候resultType是List里面的类型-->
<select id="selectList" resultType="BookEntity">
select * from books
</select>
②使用注解
@Select("select * from books")
List<BookEntity> selectList();
测试
@Test
public void test(){
List<BookEntity> bookEntities = bookMapper.selectList();
bookEntities.forEach(System.out::println);
}
4、单个update
/**
* 修改图书
*/
int updateById(BookEntity bookEntity);
①使用xml写sql
<update id="updateById" parameterType="BookEntity">
update books set name=#{name},price=#{price} where id=#{id}
</update>
②使用注解
@Update(" update books set name=#{name},price=#{price} where id=#{id}")
int updateById(BookEntity bookEntity);
测试:
@Test
public void test(){
BookEntity bookEntity=new BookEntity();
bookEntity.setId(1);
bookEntity.setName("Mybatis从入门到入土");
bookEntity.setPrice(1999);
int i = bookMapper.updateById(bookEntity);
if (i==1){
System.out.println("修改成功");
}
else {
System.out.println("修改失败");
}
}
二、数据输入
1、单个简单的类型
mapper接口:
@Select("select * from books where id=#{id}")
BookEntity selectById(Integer id);
单个简单的参数,可以使用任意名称
eg:
@Select("select * from books where id=#{value}")
BookEntity selectById(Integer id);
2、实体类类型参数
Mybatis会根据#{}中传入的数据,加工成getXxx()方法,通过反射在实体类对象中调用这个方法,从而获取到对应的数据。填充到#{}这个位置。所以要保证#{}中的名称与实体类中的名称一致
mapper接口:
@Update(" update books set price=#{price} where name=#{name} ")
int updateByName(BookEntity bookEntity);
3、零散的简单类型数据
待解决问题:当出现多个简单类型参数,mybatis通过反射找不到对应的参数
问题解决:使用 @Param注解指定参数名称
mapper接口:
@Select("select * from books where id=#{id} and name=#{name} and price=#{price}")
List<BookEntity> selectAll(@Param("id") Integer id, @Param("name") String name, @Param("price") Integer price);
4、Map参数的数据类型
①使用场景
有很多零散的参数需要传递,但是没有对应的实体类类型可以使用。使用@Param注解一个一个传入又太麻烦了。所以都封装到Map中
②对应关系
#{}中写Map中的key,会将key对应的将map中 的value封装进去
mapper接口:
这里采用注解,xml配置文件一样
@Select("select * from books where name=#{name} and description=#{description} ")
List<BookEntity> selectByMap(Map<String,String> map);
测试类:
@Test
public void test(){
Map<String,String> map=new HashMap<>();
map.put("name","Mybatis");
map.put("description","是一本好书");
List<BookEntity> bookEntities = bookMapper.selectByMap(map);
bookEntities.forEach(System.out::println);
}
三、数据输出
1、返回单个简单类型数据
设置resultType为int(别名),也可以使用全类名
<select id="selectEmpCount" resultType="int">
select count(*) from t_emp
</select>
2、返回实体类对象
<!-- resultType属性:指定封装查询结果的Java实体类的全类名,如果设置了别名,也可以直接使用别名 -->
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
<!-- Mybatis负责把SQL语句中的#{}部分替换成"?"占位符 -->
<!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
select username , pwd from user where user_id=#{id}
</select>
如果数据库中的表名与实体类的名称不一致?
1、在查询过程中起别名
<select id="selectEmployee" resultType="com.atguigu.mybatis.entity.Employee">
<!-- Mybatis负责把SQL语句中的#{}部分替换成"?"占位符 -->
<!-- 给每一个字段设置一个别名,让别名和Java实体类中属性名一致 -->
select username, pwd as password from user where user_id=#{id}
</select>
2、使用 resulteMap(文章 下面会提到)
3、返回Map类型
适用于SQL查询返回的各个字段综合起来并不和任何一个现有的实体类对应,没法封装到实体类对象中。能够封装成实体类类型的,就不使用Map类型。
eg:查询图书的总数量和平均价格
mapper接口:
Map<String,Object> selectNumAndAvg();
xml配置文件:
<select id="selectNumAndAvg" resultType="java.util.Map" >
select count(*) ,avg(price) from books
</select>
测试类:
@Test
public void test01(){
Map<String, Object> stringObjectMap = bookMapper.selectNumAndAvg();
//遍历map
for (Map.Entry<String, Object> stringObjectEntry : stringObjectMap.entrySet()) {
System.out.println(stringObjectEntry.getKey());
System.out.println(stringObjectEntry.getValue());
}
}
运行结果:
avg(price)
50.5000
count(*)
2
查询的时候起别名
<select id="selectNumAndAvg" resultType="java.util.Map" >
select count(*) as allNum ,avg(price) as avgPrice from books
</select>
返回的map中的key就变为起的别名
avgPrice
50.5000
allNum
2
4、返回List类型
查询结果返回多个实体类对象,希望把多个实体类对象放在List集合中返回。此时不需要任何特殊处理,在resultType属性中还是设置实体类类型即可。
mapper接口:
/**
* 查询全部
*/
List<BookEntity> selectList();
xml配置文件:
<!-- 查List的时候resultType是List里面的类型-->
<select id="selectList" resultType="BookEntity">
select * from books
</select>
5、返回自增主键
mapper接口:
/**
* 增加一本书
*/
int addBook(BookEntity bookEntity);
xml配置文件:
<!-- 因为配置了别名,所以parameterType不需要写全类名-->
<!-- useGeneratedKeys属性字面意思就是"使用生成的主键" -->
<!-- keyProperty属性可以指定主键在实体类对象中对应的属性名,Mybatis会将拿到的主键值存入这个属性 -->
<insert id="addBook" parameterType="BookEntity" useGeneratedKeys="true" keyProperty="id">
insert into books (name,price,description) values (#{name},#{price},#{description})
</insert>
测试类:
@Test
public void test02(){
BookEntity bookEntity=new BookEntity();
bookEntity.setName("Mybatis从入门到精通");
bookEntity.setPrice(88);
bookEntity.setDescription("非常好");
bookMapper.addBook(bookEntity);
System.out.println(bookEntity);
}
返回结果:
BookEntity(id=4, name=Mybatis从入门到精通, price=88, description=非常好)
注意:
Mybatis是将自增主键的值设置到实体类对象中,而不是以Mapper接口方法返回值的形式返回。
不支持自增主键的数据库
而对于不支持自增型主键的数据库(例如 Oracle),则可以使用 selectKey 子元素:selectKey 元素将会首先运行,id 会被设置,然后插入语句会被调用
xml
<insert id="insertEmployee"
parameterType="com.atguigu.mybatis.beans.Employee"
databaseId="oracle">
<selectKey order="BEFORE" keyProperty="id"
resultType="integer">
select employee_seq.nextval from dual
</selectKey>
insert into orcl_employee(id,last_name,email,gender) values(#{id},#{lastName},#{email},#{gender})
</insert>
或者是
xml
<insert id="insertEmployee"
parameterType="com.atguigu.mybatis.beans.Employee"
databaseId="oracle">
<selectKey order="AFTER" keyProperty="id"
resultType="integer">
select employee_seq.currval from dual
</selectKey>
insert into orcl_employee(id,last_name,email,gender) values(employee_seq.nextval,#{lastName},#{email},#{gender})
</insert>
resultMap元素
待解决问题: 结果集(表)中的列名和对象中的字段名称不匹配
如果是UserName与username不匹配,可以配置驼峰映射
yml
mybatis:
#开启驼峰映射
configuration:
map-underscore-to-camel-case: true
那如果是两个完全无关的属性名呢?
解决方案: 使用resultMap元素
eg:
<resultMap id="UserMapper" type="UserEntity">
<result column="u_id" property="id" />
<result column="u_name" property="name" />
<result column="u_pwd" property="pwd" />
</resultMap>
<!-- 此处就使用 结果集对象映射, UserMapper -->
<select id="queryUserList" resultMap="UserMapper">
select u_id, u_name, u_pwd from user1;
</select