持久层框架,免不了对数据库的增删改查,记录一下语法,穿插几个要点。
- 字面量和引用类型作为参数
- 自动提交
- 多个参数传递
- 查询结果
实体类
package com.atguigu.mybatis.bean; public class Customer { private Integer id; private String username; private String jobs; private String phone; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getUsername() { return username; } public void setUsername(String username) { this.username = username; } public String getJobs() { return jobs; } public void setJobs(String jobs) { this.jobs = jobs; } public String getPhone() { return phone; } public void setPhone(String phone) { this.phone = phone; } @Override public String toString() { return "Customer [id=" + id + ", username=" + username + ", jobs=" + jobs + ", phone=" + phone + "]"; } } /* create table customer( id int primary key auto_increment, username varchar(50), jobs varchar(50), phone varchar(16) ); */
其中id是自动增长的主键,在mybatis-conf.xml中配置的事务管理是JDBC。
用MyBatis实现Java与SQL分离,最好把Java中的函数作为注释放进XML文件里,容易翻车。
1.增(POJO作为参数传入)
一般参数是实体类,在测试方法里用set方法赋值,再调用接口函数。
参数是引用类型的话,#{属性名}是通过get属性名方法获取值,此时#{}内的属性名不能乱用,如果参数是字面量的话就可以随便写,只要有#{}就行,因为#{}是占位符。
<!-- void insertCustomer(Customer customer); --> <update id="insertCustomer" parameterType="com.atguigu.mybatis.bean.Customer"> insert into customer(id,username,jobs,phone) values(#{id},#{username},#{jobs},#{phone}) </update>
SQL语句也可以写成:insert into customer values(#{id},#{username},#{jobs},#{phone})
测试方法如下:
public class MyBatisTest { @Test public void test() throws Exception { InputStream is=Resources.getResourceAsStream("mybatis-config.xml");//读取配置文件 SqlSessionFactory sessionFactory=new SqlSessionFactoryBuilder().build(is);//构建工厂 SqlSession sqlSession=sessionFactory.openSession();//创建sqlSession CustomerMapper mapper=sqlSession.getMapper(CustomerMapper.class);//创建接口对象 Customer customer=new Customer(); customer.setJobs("老师"); customer.setPhone("10087"); customer.setUsername("老夫子"); mapper.insertCustomer(customer); sqlSession.commit();//手动提交 sqlSession.close();//关闭 } }
这里需要手动提交的原因是SqlSession sqlSession=sessionFactory.openSession();
openSession()默认参数是fasle,传入参数为true可以自动提交。下面测试方法都使用自动提交。
因为id是自动增长的主键,即使没有提交,主键的序号也会+1。
2.删(返回类型)
<!-- Integer deleteCustomerById(Integer id); --> <delete id="deleteCustomerById" parameterType="Integer"> delete from customer where id=#{id} </delete>
在这个函数中,返回的结果类型是Integer,表示对表做出修改的行数,也可以用Boolean类型表示是否成功修改。
3.改(多个参数传递)
(1)将参数 显性地 手动封装在map里进行传递
(2)用注解@Param将参数 隐性地 自动封装在map里进行传递,通过注解指定[键]的名字
<!-- Boolean updateName(Map<String,Object> map); --> <!-- Integer updateName(@Param("oldname")String oldname,@Param("newname")String newname); --> <update id="updateName" > update customer set username=#{newname} where username=#{oldname} </update> <!--在测试函数中两种调用方法 Map<String, Object> map=new HashMap<String, Object>(); map.put("oldname", "66"); map.put("newname","守林鸟"); System.out.println(mapper.updateName(map)); //System.out.println(mapper.updateName("守林鸟","66")); -->
(3)插空
更具传入的参数位置,一个空位一个值,在SQL语句里用#{0},#{1}...#{n}代替,或者#{param1},#{param2},#{param3}。前者是按索引,后者是按第几个数。(个人的eclipse测试一直有问题)
4.查
返回多条记录,XML里的resultType不需要改为List,在Java里用List接收。
<!-- List<Customer> selectByJobs(String jobs); --> <select id="selectByJobs" resultType="com.atguigu.mybatis.bean.Customer"> select * from customer where jobs=#{jobs} </select> <!-- Java测试:List<Customer> list=mapper.selectByJobs("学生"); -->
5.#{}与${}的差别
#{}:占位符;替换为?,自动加上单引号['];防止sql注入;#{任意名};动态解析->预编译->执行;
${}:拼接符;替换为具体值,需要手动加上单引号['];不能防止sql注入;${value};动态解析->编译->执行;
例如传入参数为1:
- select * from t_user where uid=#{uid} ——> select * from t_user where uid=? ——> select * from t_user where uid='1'
- select * from t_user where uid='${uid}' ——> select * from t_user where uid='1' ——> select * from t_user where uid='1'
总之,没事别用${}。
参考&引用
https://blog.csdn.net/siwuxie095/article/details/79190856
学习资料:B站尚硅谷MyBatis视频