💡【开发哲学共勉】
在 MyBatis 的世界里,事务提交是对数据变更的郑重承诺,参数绑定藏着对安全的敬畏,资源闭环是对系统的温柔守护,而接口与映射的一 一对应,恰是规范赋予效率的礼物
🎉 前言
本节来讲解一下如何使用MyBatis来对数据库做一个基本的增删改查操作,希望能够帮助到你(๑•̀ㅂ•́)و✧
个人主页:艺杯羹🌿
系列专栏:MyBatis🚀
1. ➕MyBatis添加数据
现在来演示一下如何添加用户
1.1. 持久层接口添加方法
// 写在UserMapper接口里 void add(User user);
1.2. 映射文件添加标签
// 写在UserMapper.xml配置文件中 <insert id="add" parameterType="com.itbaizhan.pojo.User"> insert into user(username,sex,address) values(#{username},#{sex},#{address}) </insert>
1.3. 编写测试方法
// 在测试包下的测试类里进行测试 @Test public void testAdd() throws Exception{ InputStream is = Resources.getResourceAsStream("sqlMapConfig.xml"); SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); SqlSessionFactory factory = builder.build(is); SqlSession session = factory.openSession(); UserMapper mapper = session.getMapper(UserMapper.class); User user = new User("罗阳", "男", "北京"); mapper.add(user); // 提交事务,默认手动提交事务 // 所以要先提交事务,然后再关闭资源 // 如果没有提交事务,虽然不会报错,但是数据不会写到表当中 session.commit(); session.close(); is.close(); }
接口如图:
注意:
- 当接口方法的参数类型为POJO类型时,SQL语句中绑定参数时使用 #{POJO的属性名} 即可
- MyBatis事务默认手动提交,所以在执行完增删改方法后,需要手动调用SqlSession对象的事务提交方法,否则数据库将不发生改变
查询不改变数据库,所以不用提交事务
2. ✏️MyBatis修改数据
因为在操作数据库的时候,像前面的配置获取SqlSession的代码,是可以复用的,所以这里先将这个配置获取SqlSession的代码提取出来
2.1. 代码的优化
MyBatis的测试方法在操作数据库前都需要获取代理对象,操作数据库后都需要释放资源,可以利用Junit的前置后置方法,优化测试类代码
InputStream is = null; SqlSession session = null; UserMapper userMapper = null; @Before public void before() throws IOException { // (1)读取核心配置文件 is = Resources.getResourceAsStream("SqlMapConfig.xml"); // (2)创建SqlSessionFactoryBuilder对象 SqlSessionFactoryBuilder builder = new SqlSessionFactoryBuilder(); // (3)SqlSessionFactoryBuilder对象获取SqlSessionFactory对象 SqlSessionFactory factory = builder.build(is); // (4)SqlSessionFactory对象获取SqlSession对象 session = factory.openSession(); // (5)获取代理对象 userMapper = session.getMapper(UserMapper.class); } @After public void after() throws IOException { // 释放资源 session.close(); is.close(); }
现在来修改一下用户
2.2. 持久层接口添加方法
void update(User user);
2.3. 映射文件添加标签
<update id="update" parameterType="com.yibeigen.pojo.User"> update User set username = #{username}, sex = #{sex}, address=#{address} where id = #{id} </update>
2.4. 编写测试方法
// 这里直接使用Mapper动态代理就可以了(๑•̀ㅂ•́)و✧ @Test public void testUpdate(){ User user = new User(6, "老王", "男", "溆浦"); userMapper.update(user); sqlSession.commit(); }
3. 🗑️MyBatis删除数据与根据Id查询
因为删除和查询都和上面操作差不多,所以这里就两个一起讲了
3.1. 删除用户
- 持久层接口添加方法
void delete(int userId); - 映射文件添加标签
<delete id="delete" parameterType="int"> delete from user where id = #{id} </delete>
注:当方法的参数类型是简单数据类型时,#{}中可以写任意名称
简单数据类型:基本数据类型、字符串等
- 编写测试方法
@Test public void testDelete(){ userMapper.delete(8); session.commit(); }
3.2. 根据ID查询用户
- 持久层接口添加方法
User findById( int userId ); - 映射文件添加标签
<select id="findById" parameterType="int" resultType="com.yibeigen.pojo.User"> select * from user where id = #{userId} </select>
3. 编写测试方法
@Test public void testFindById(){ User user = userMapper.findById(1); System.out.println(user); }
4. 🌫️MyBatis模糊查询
模糊查询一共有三个写法:#, $,
4.1. 使用 # 定义参数
1. 持久层接口添加方法
List findByNameLike(String username);
2. 映射文件添加标签
<select id="findByUsernameLike" parameterType="String" resultType="com.yibeigen.pojo.User"> select * from user where username like #{name} </select>
3. 编写测试方法
@Test public void testFindByNameLike(){ List<User> users = userMapper.findByNameLike("%王%"); for (User user:users){ System.out.println(user); } }
这里使用 # 和上面写的#是一个意思,像这里的第2步映射文件中的 #{name} 就相当于是这个类中的name值
然后我们在测试类中传值的时候,要注意加上 %
我们看到在映射文件中,parameterType 的值为 string 而没有写 java.lang.String
这是因为,系统已经给 java.lang.String取了别名 string,所以直接用就可以了
数据类型 |
别名 |
数据类型 |
别名 |
byte |
_byte |
Byte |
byte |
long |
_long |
Long |
long |
short |
_short |
Short |
short |
int |
_int |
Integer |
int/integer |
int |
_integer |
Double |
double |
double |
_double |
Float |
float |
float |
_float |
Boolean |
boolean |
boolean |
_boolean |
Date |
date |
String |
string |
BigDecimal |
decimal/bigdecimal |
Object |
object |
Map |
map |
HashMap |
hashmap |
List |
list |
ArrayList |
arraylist |
Collection |
collection |
Iterator |
iterator |
4.2. 使用$定义参数
模糊查询如果不想在调用方法时参数加%,可以使用拼接参数的方式设置
Sql:
<select id="findByUsernameLike" parameterType="string" resultType="com.yibeigen.pojo.User"> select * from user where username like '%${value}%' </select> %${value}%:必须这么写
测试方法写法如下:
@Test public void testFindByNameLike(){ List<User> users = userMapper.findByUsernameLike("金"); users.forEach(System.out::println); }
#和$的区别:
- #表示sql模板的占位符,$表示将字符串拼接到sql模板中。
- #可以防止sql注入,一般能用就不用$。
- ${}内部的参数名必须写value。
4.3. 使用 定义参数
如果使用 # 还不想在调用方法的参数中添加 %
可以使用 , 允许我们在 Sql语句以外创建一个变量 并可以将其绑定到当前的Sql语句中。用法如下:
<select id="findByUsernameLike" parameterType="string" resultType="com.yibeigen.pojo.User"> <bind name="likeName" value="'%'+username+'%'"/> select * from user where username like #{likeName} </select>
测试方法写法如下:
@Test public void testFindByNameLike(){ List<User> users = userMapper.findByUsernameLike("金"); users.forEach(System.out::println); }
5. 总结
到此,文章就告一段落,希望能够帮助到你🙂