Mybatis框架学习笔记
Posted 小智RE0
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mybatis框架学习笔记相关的知识,希望对你有一定的参考价值。
本篇Mybatis框架学习笔记;紧跟之前的学习
Mybatis框架学习笔记(2)—>
在mybatis框架核心配置文件中需要学习的配置
configuration(配置)
properties(属性)
settings(设置)
typeAliases(类型别名)
typeHandlers(类型处理器)
objectFactory(对象工厂)
plugins(插件)
environments(环境配置)
environment(环境变量)
transactionManager(事务管理器)
dataSource(数据源)
databaseIdProvider(数据库厂商标识)
mappers(映射器)
文章目录
1.关于在sql语句中使用 #{} 与${} 的区别
使用 #{}
回忆一下整理第一篇笔记时,当时的mapper.xml配置文件中,添加用户的sql;
当时用的是 #{ }
来得到对象中的值
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!--注意 这里对应空间为持久层映射接口-->
<mapper namespace="com.xiaozhi.mapper.UserMapper">
<!--添加新用户的sql-->
<!--这里的parameterType 参数类型 就用刚才配置的别名 user了-->
<insert id="addUser" parameterType="user">
insert into t_user(account,password,address)
values (#{account},#{password},#{address})
</insert>
</mapper>
测试使用
@Test
public void testAddUser(){
//创建用户对象;
User user = new User("点金手","431231w","四川成都");
//使用工具类创建sqlSession;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//调用方法;这里实际上会执行sql语句;
mapper.addUser(user);
//事务提交;
sqlSession.commit();
//关闭sqlSession;
sqlSession.close();
}
可以看看测试打印的日志;
出现了占位符 ?,?,?
也就是说,他用了
PreparedStatement
来进行执行sql的;是比较安全的;可防止sql注入
使用${}
实际上,也可以用${ } ;
Ok,那就来试试;
在UserMapper.xml
中更换sql
<insert id="addUser" parameterType="user">
insert into t_user(account,password,address)
values (${account},${password},${address})
</insert>
执行测试
//使用${}方式传递参数执行sql;
@Test
public void testAddUser2(){
//创建用户对象;
User user = new User("阿飞","123132","四川成都");
//使用工具类创建sqlSession;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//调用方法;这里实际上会执行sql语句;
mapper.addUser(user);
//事务提交;
sqlSession.commit();
//关闭sqlSession;
sqlSession.close();
}
执行,诶,出现错误了;它直接把输入的赋值直接写到sql语句里面了; 而且是把输入的赋值当做数据库的列名了;所以首先提示找不到列名为 阿飞 的列;这里已经错了后面的自然不会再执行下去了;
要知道,这几个属性赋值的时候是字符串哦;在数据库中字符串赋值的时候,要加''
或者""
;
那么,修改一下sql语句吧
<insert id="addUser" parameterType="user">
insert into t_user(account,password,address)
values ('${account}','${password}','${address}')
</insert>
再次执行;
OK,执行成功了;
添加时;它是直接按拼接字符串的方式;将对象赋值给传递进去了;
${}
方式执行sql时,实际上是Statement
的方式;也就是说不安全的那个; 不能防止SQL注入
但是;${}
也是可以使用的,
因为用${}
传递的是列名,而不是传递数据;
2.在执行sql后,获取到数据表的主键值;
在之前进行的添加用户中,由于当时数据表的ID是作为主键自动递增的;
在执行完添加语句后,我想快速的得到这个刚刚添加的数据的ID;
那么直接获取Id,得到的肯定是0
啊;
试试看—>
//在添加用户数据之后,立即得到主键ID的值;
@Test
public void testAddUser3(){
//创建用户对象;
User user = new User("爱喝水","123132","陕西西安");
//使用工具类创建sqlSession;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//调用方法;这里实际上会执行sql语句;
mapper.addUser(user);
System.out.println("当前的用户Id值为-->"+user.getId());
//事务提交;
sqlSession.commit();
//关闭sqlSession;
sqlSession.close();
}
执行一下;用户肯定存入了;但是这里输出得到的ID是0;
看看数据表,该用户的ID是24哦
当然,可以写两个sql语句;就是说,刚刚添加的新用户数据之后,然后我又去根据用户的某个信息查询得到他的ID信息;这种方式是可行的;
但是,还有一种个比较好的方式,在执行sql语句后,不需要去另外执行别的sql语句;也能得到用户的ID;
那就是在UserMapper.xml
的配置文件中,写sql语句的时候;将参数useGeneratedKeys
设置为true;即使用生成的主键;当然还要设置数据库的列名和类中的属性对应;
<!--在执行后,想要得到数据表的主键值 确认使用主键 数据表的列名 实体类的对应属性-->
<insert id="addUser" parameterType="user" useGeneratedKeys="true" keyColumn="id" keyProperty="id">
insert into t_user(account,password,address)
values (#{account},#{password},#{address})
</insert>
再次测试执行;
//在添加用户数据之后,立即得到主键ID的值;
@Test
public void testAddUser4(){
//创建用户对象;
User user = new User("小咸鱼","123132","四川成都");
//使用工具类创建sqlSession;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
UserMapper mapper = sqlSession.getMapper(UserMapper.class);
//调用方法;这里实际上会执行sql语句;
mapper.addUser(user);
System.out.println("当前的用户Id值为-->"+user.getId());
//事务提交;
sqlSession.commit();
//关闭sqlSession;
sqlSession.close();
}
执行;得到了主键ID号
3.写个修改用户信息
用户的实体类,改变一下,也就是添加个新的有参构造方法;以及toString()方法
package com.xiaozhi.pojo;
/**
* @author by CSDN@小智RE0
* @date 2021-10-24 22:07
* 实体类User(用户类)
*/
public class User {
//属性,id,账户,密码,地址;
private int id;
private String account;
private String password;
private String address;
//构造方法;
public User() {
}
public User(int id, String account, String password, String address) {
this.id = id;
this.account = account;
this.password = password;
this.address = address;
}
//这里构造方法初始化时就没包括ID;
public User(String account, String password, String address) {
this.account = account;
this.password = password;
this.address = address;
}
//getter,setter;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", account='" + account + '\\'' +
", password='" + password + '\\'' +
", address='" + address + '\\'' +
'}';
}
}
当然,首先在UserMapper
持久层接口定义方法;
//更新修改用户信息;
void updateUser(User user);
然后在UserMapper.xml
映射文件中编写对应的sql文件
<!--修改用户信息 参数为基本类型,可以不标注-->
<update id="updateUser">
update t_user set account=#{account},password=#{password},address=#{address}
where id=#{id}
</update>
测试执行
//修改用户信息;
@Test
public void updateUser(){
//创建用户对象;
User user = new User(25,"学习mybatis框架","12weds","陕西");
//使用工具类创建sqlSession;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用方法;
userMapper.updateUser(user);
//事务提交;
sqlSession.commit();
//关闭sqlSession;
sqlSession.close();
}
执行成功
4.写个删除用户
在UserMapper
持久层接口定义方法;
//根据ID删除用户;
void deleteUser(int id);
在UserMapper.xml
映射文件中编写对应的sql文件
<!--删除用户信息-->
<delete id="deleteUser">
delete from t_user where id=#{id}
</delete>
测试执行
//删除用户信息;
@Test
public void deleteUser(){
//使用工具类创建sqlSession;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用方法;
userMapper.deleteUser(20);
//事务提交;
sqlSession.commit();
//关闭sqlSession;
sqlSession.close();
}
执行;删除成功;
5.查询所有用户
在UserMapper
持久层接口定义方法;
//查询所有用户;
List<User> findUser();
在UserMapper.xml
映射文件中编写对应的sql文件
<!--查询所有用户-->
<select id="findUser" resultType="user">
select * from t_user
</select>
测试执行
//查询所有用户;
@Test
public void findAllUser(){
//使用工具类创建sqlSession;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用方法;
List<User> user = userMapper.findUser();
System.out.println(user);
//事务提交;
sqlSession.commit();
//关闭sqlSession;
sqlSession.close();
}
执行;
6.根据Id查询用户
在UserMapper
持久层接口定义方法;
//根据用户ID获取;
User findUserById(int id);
在UserMapper.xml
映射文件中编写对应的sql文件
<!--根据Id查询信息-->
<select id="findUserById" resultType="user">
select * from t_user where id=#{id};
</select>
测试执行
//根据Id查询用户信息;
@Test
public void findUserById(){
//使用工具类创建sqlSession;
SqlSession sqlSession = MyBatisUtils.getSqlSession();
//获取代理对象;
UserMapper userMapper = sqlSession.getMapper(UserMapper.class);
//调用方法;
User userById = userMapper.findUserById(25);
System.out.println(userById);
//事务提交;
sqlSession.commit();
//关闭sqlSession;
sqlSession.close();
}
执行成功;
7.配置开启驼峰命名匹配
有没有注意到;前面在查询信息时,没有进行指定要获取的指定属性;它就自动匹配到用户类的对象属性中了;这是由于当时写实体类时,把属性名和数据库的列名一致了
那么,我要是数据表的列名和用户类的属性不相同了呢?
比如说,这里我把用户类的地址属性改了原来是address
;现在我把它改成addRess
,驼峰命名的方式;
package com.xiaozhi.pojo;
/**
* @author by CSDN@小智RE0
* @date 2021-10-27 1:48
* 实体类User(用户类)
*/
public class User {
//属性,id,账户,密码,地址;
private int id;
private String account;
private String password;
private String addRess;
//构造方法;
public User() {
}
public User(int id, String account, String password, String addRess) {
this.id = id;
this.account = account;
this.password = password;
this.addRess = addRess;
}
//这里构造方法初始化时就没包括ID;
public User(String account, String password, String addRess) {
this.account = account;
this.password = password;
this.addRess = addRess;
}
//getter,setter;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getAddRess() {
return addRess;
}
public void setAddRess(String addRess) {
this.addRess = addRess;
}
@Override
public String toString() {
return "User{" +
"id=" + id +
", account='" + account + '\\'' +
", password='" + password + '\\'' +
", addRess='" + addRess + '\\'' +
'}';
}
}
然后我把数据表的地址由address
改为了add_ress
这时我再根据ID查询信息时,地址查不到信息;
实际上,这里需要在mybatis的核心配置文件mybatis-config.xml
中进行一个设置
在settings
下配置mapUnderscoreToCamelCase
为true
是否开启驼峰命名自动映射,即从经典数据库列名 A_COLUMN 映射到经典 Java 属性名 aColumn。
它默认为false关闭状态的;
<?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>
<!--引入外部的资源文件-->
<properties resource="database.properties">
</properties>
<settings>
<!--配置日志-->
<setting name以上是关于Mybatis框架学习笔记的主要内容,如果未能解决你的问题,请参考以下文章