增删改查分别对应Mybatis中配置文件的四个标签
他们分别是
<!--查询标签-->
<select>
</select>
<!--删除标签-->
<delete>
</delete>
<!--更新标签-->
<update>
</update>
<!--插入标签-->
<insert>
</insert>
我们写的SQL语句就放在他们之中
这些标签都有几个属性
1.id => 方法名称
2.parameterType 参数类型 写全类名
3.resultType 封装的结果类型
例子
1.查询
<!--查询所有用户,这里的user已经起了别名 因此不需要全类名-->
<select id="selectAll" resultType="user">
select * from user;
</select>
2.更新
其中#{}里面的内容是我们的参数(User类的对象)的各个属性
而等号左边的的则是数据库中的字段名
<!--根据对应的id修改属性-->
<update id="updateUser" parameterType="com.tubai.domain.User">
update user set username=#{username},address=#{address},sex=#{sex},birthday=#{birthday}
where id=#{id}
</update>
3.删除
<!--根据id删除对应的user-->
<delete id="deleteUser" parameterType="java.lang.Integer">
delete from user where id = #{uid}
</delete>
4.插入
<insert id="saveUser" parameterType="com.tubai.domain.User">
insert into user(username,address,sex,birthday,id) values(#{username},#{address},#{sex},#{birthday},null);
</insert>
如果我们想要在调用插入方法的时候 获取id值
直接获取是获取不到的
因为我将id设置为自动增长的主键
@Test
public void testSaveUser(){
User user = new User();
user.setUsername("QTQ");
user.setAddress("广东芜湖");
user.setSex("男");
user.setBirthday(new Date());
userDao.saveUser(user);
//因为自动提交的关闭的 因此我们需要手动提交 否则就回滚了
//当然这一行也可以写到close里面 让它关闭前执行
sqlSession.commit();
System.out.println(user);
}
比如我们这里直接输出user
会得到com.tubai.domain.User{id=null, username='QTQ', birthday=Thu Oct 15 14:43:05 CST 2020, sex='男', address='广东芜湖'}
我们发现id是为null的
如果我们想解决这个问题
那么只需要修改刚刚的配置文件
<insert id="saveUser" parameterType="com.tubai.domain.User">
insert into user(username,address,sex,birthday,id) values(#{username},#{address},#{sex},#{birthday},null);
<!--因为我们的id是自动增长的 因此如果想在调用的时候获取id 那么需要加上以下内容-->
<selectKey keyColumn="id" keyProperty="id" resultType="int" order="AFTER">
<!--keyColumn是列名 keyProperty是要设置为目标的哪个属性(需要跟JavaBean对象的属性名一致,因为对应的就是JavaBean中的属性) order表示上面的语句执行之前还是之后我们执行-->
<!--这个方法是mysql自带的 查询最后一个插入的id-->
select last_insert_id();
</selectKey>
</insert>
再执行就会发现我们的id有值了
注意事项
增删改操作是需要提交事务的
因为我们的sqlsession对象是通过这段代码来得到的
sqlSession = factory.openSession();
而这个方法我们查看源代码
public SqlSession openSession() {
return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, false);
}
//发现第三个参数就是自动提交
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit);
因此我们得知 它默认是关闭自动提交的
我们可以在执行日记中看到这样一句话
Setting autocommit to false on JDBC Connection
关闭了自动提交
因此如果我们的方法中必须加上
sqlSession.commit();
来提交我们的事务 不然就回滚了
开启自动提交
如果我们想开启自动提交
那么只需要调用这个有参的方法得到sqlsession对象即可
public SqlSession openSession(boolean autoCommit) {
return this.openSessionFromDataSource(this.configuration.getDefaultExecutorType(), (TransactionIsolationLevel)null, autoCommit);
}
#{}的说明
sql 语句中使用的#{}:
它代表占位符,相当于原来 jdbc 中的PrepareStatement所使用的 ?
具体的数据是由#{}里面的内容决定的。
#{}中内容的写法:
比如我们保存方法的参数是 一个 User 对象,此处要写 User 对象中的属性名称。
它用的是 ognl 表达式。
ognl 表达式:
它是 apache 提供的一种表达式语言,全称是:
Object Graphic Navigation Language 对象图导航语言
它是按照一定的语法格式来获取数据的。
语法格式就是使用 #{对象.对象}的方式
我们JSP中使用的EL表达式也是使用的ognl
#{}中的注意事项
如果我们的pojo类的getter是自动生成的 那么#{}中直接写属性名即可
如果我们的getter是自己写的且不按命名规范
比如我写个
public Integer getID() {
return id;
}
那么#{}中就传除了get以外的名称,比如这里就传#{ID}
模糊查询中的注意事项
比如我们想通过名称模糊查询
我们写了这样一个方法
List<User> findUserByName(String name);
我们在配置文件中有两种实现方式
方式一:
<select id="findUserByName" parameterType="String" resultType="com.tubai.domain.User">
<!--方式一是通过PreparedStatement方式实现的sql语句-->
<!--方式一、如果需要模糊查询 那么需要通过参数来实现-->
select * from user where username like #{username}
</select>
这种方式我们只需要在传入的参数中写响应的符号即可,
比如参数写为=> %飞%
方式二:
<select id="findUserByName" parameterType="String" resultType="com.tubai.domain.User">
<!--方式二是通过Statement方式实现的sql语句 会被sql注入 因此不常用-->
<!--方式二、按照以下写法-->
select * from user where username like '%${value}%'
<!--当然'%'也可以换成'_'-->
<!--其中value是固定写法 因为源码中 value是作为一个key-->
</select>