MyBatis 的DRUD
文章目录
基于 xml开发
<!--设置Dao层的映射文件-->
<mappers>
<mapper resource="com/itheima/mapper/IUserMapper.xml"/>
</mappers>
1. MyBatis中查询
先创建实体类User.java
import java.util.Date;
public class User implements Serializable {
private Integer id;
private String username;
private String address;
private Date birthday;
private char sex;
get/set/toString
}
dao
public interface IUserMapper {
/**
* 1. 查询所有用户 返回多条数据,用List集合
*/
List<User> findAllUser ();
}
mapper映射文件中写SQL语句
<!--映射文件要与相对应的mapper接口通过namespace属性进行关联-->
<mapper namespace="com.itheima.dao.IUserMapper">
<!--id为mapper类中对应方法名,resultType为定义的接收类型,一般为对应实体类-->
<select id="findAllUser" resultType="com.itheima.pojo.User">
SELECT * FROM user
</select>
</mapper>
Test
public class TestMyBatis {
//在不同的地方拥戴这些类,需要关闭资源等操作,所以先在外面定义这些类
private InputStream inputStream;
private SqlSession sqlSession;
private IUserMapper iUserMapper;
@Before //在测试模块之前执行、前期的铺垫工作都在这里
public void init() throws IOException {
//1.读取被指文件
inputStream = Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder sqlSessionFactoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory build = sqlSessionFactoryBuilder.build(inputStream);
//3.创建SqlSession对象
sqlSession = build.openSession();
//4.用SqlSession对象生成代理对象
iUserMapper = sqlSession.getMapper(IUserMapper.class);
}
@After //测试模块运行后执行,提交事务,释放资源
public void end() throws IOException {
// 保存时必须——提交事务
sqlSession.commit();
//6.释放资源
inputStream.close();
sqlSession.close();
}
测试类中的代理对象执行方法
/**
* 1. 查所有的用户
*/
@Test
public void findAllTest() {
//5.代理对象执行方法
List<User> allUser = iUserMapper.findAllUser();
for (User user : allUser) {
System.out.println(user);
}
}
2. 添加用户 & 获取被插入数据的 id
dao
//2. 添加用户的方法
void addUser(User user);
mapper
<insert id="addUser" parameterType="com.itheima.pojo.User">
配置插入数据后,获得该条数据表中id
keyProperty属性名称,对应实体类、keyColumn:数据库中对应字段、resultType:结果集类型、order:先运行还是后运行
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
SELECT last_insert_id() //查询最后一条数据的id
</selectKey>
INSERT INTO user (username, address, birthday, sex) VALUES (#{userName}, #{userAddress}, #{userBirthday},
#{userSex})
</insert>
Test
// 添加用户的方法
@Test
public void addUserTest() throws ParseException {
User user = new User();
// 输入子自定义的日期
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
user.setUserName("周润发");
user.setUserAddress("中国香港");
// .parses( ) 方法 注意用双引号
user.setUserBirthday(simpleDateFormat.parse("1989-2-4"));
user.setUserSex('男');
System.out.println("保存之前添加的值:"+ user);
iUserMapper.addUser(user);
// 返回被添加数据的对应 id
System.out.println("保存之后添加的值:"+ user);
}
3. MyBatis 更新
dao
// 3. 更新用户信息
void updateUser(User user);
mapper
<update id="updateUser" parameterType="com.itheima.pojo.User">
UPDATE user
SET username = #{username},
birthday = #{birthday },
sex = #{sex},
address = #{address}
WHERE id = #{id}
</update>
Test
// 更新
@Test
public void updateUserTest() throws ParseException {
User user = new User();
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
//因为没有写根据id查询,所以这里传入id 指定要更改的数据
user.setId(52);
user.setUsername("杀手47");
user.setSex("男");
user.setBirthday(simpleDateFormat.parse("1998-12-1"));
user.setAddress("无国籍人员");
iUserMapper.updateUser(user);
}
4. MyBaits 删除
dao
// 3. 删除用户
void dropUser(Integer id);
mapper
<delete id="dropUser" parameterType="int">
DELETE
FROM user
WHERE id = #{id}
</delete>
Test
// 根据id删除用户
@Test
public void delectUserTest() {
iUserMapper.dropUser(55);
}
5. 根据 id 查询用户信息
dao
// 5. 根据ID查询用户
User findById(Integer id);
mapper
<select id="findById" parameterType="int" resultType="com.itheima.pojo.User">
SELECT * FROM user WHERE id = #{id}
</select>
Test
// 根据ID查询用户
@Test
public void selectOneTest(){
User byId = iUserMapper.findById(52);
System.out.println( byId);
}
6. 模糊查询姓名
dao
// 6. 根据姓名模糊查询 返回多条数据,用List
List<User> findByName(String username);
mapper
<select id="findByName" resultType="com.itheima.pojo.User">
<!-- 这里用模糊查询 LIKE -->
SELECT * FROM user WHERE username like #{username}
</select>
Test
// 通过姓名模糊查询
@Test
public void selectByNameTest(){
// 此处是模糊查询,记得使用 % %
List<User> byName = iUserMapper.findByName("%王%");
for (User user : byName) {
System.out.println(user);
}
}
7. 聚合函数 获得总用户数
dao
// 7. 查询用户总量 返回的是数字,此处为int类型
int userTotal();
mapper
<select id="userTotal" resultType="java.lang.Integer">
<!-- 此处传入id 为查表中id 字段有多少的数据-->
SELECT COUNT(id) from user
</select>
Test
@Test
public void userTotalTest(){
int i = iUserMapper.userTotal();
System.out.println("====" +i);
}
8. OGNL 表达式
-
他是通过对象的取值方法来获取数据。在写法上把 get 给省略了。
-
比如:我们获取用户的名称
- 类中的写法是:user.getUserName() ; 需要get获取
- OGNL 表达式写法:user.username 根据对象直接点出来
-
mybatis中为什么能直接写username,而不用user. 呢:
- 因为在parameterType 中已经提供了属性所属的类,所以次数不需要写对象名
9. 传递 pojo 对象 & pojo包装对象
把实体类对象再包一层——由多个对象组成一个查询条件,实现对数据的查询
建立新的对象QueryVo
// 新建封装user的对象,之后通过这里的user 取username
public class QueryVo {
private User user;
set / get
}
dao
// 根据QueryVo 中的条件查询用户
List<User> findUserByVo(QueryVo vo);
mapper
<!-- 根据QueryVo 中的条件,查询用户 parameterType 指向Vo类 ;resultType 指向实体类-->
<select id="findUserByVo" parameterType="com.itheima.pojo.QueryVo" resultType="com.itheima.pojo.User">
<!-- Vo 类只封装了user对象,没有封装username, 但是可以通过user. 出来 -->
SELECT * FROM user WHERE username LIKE #{user.username}
</select>
Test
// 由多个对象组成一个查询条件,实现对数据的查询
// 根据VO封装类,进行模糊查询
@Test
public void queryVoTest(){
User user = new User();
QueryVo queryVo = new QueryVo();
user.setUsername("%王%"); //加 %% 模糊查询
queryVo.setUser(user); // 把实体类对象传给Vo类
List<User> u1 = iUserMapper.findUserByVo(queryVo); //传给方法Vo对象
for (User u2 : u1) {
System.out.println(u2);
}
}
10. MyBatis 中实体类字段名与数据库不同
实体类
public class User implements Serializable {
private Integer userId; //id
private String userName; //username
private Date userBirthday; //birthday
private String userSex; //sex
private String userAddress; //address
set / get /toString
}
查询所有用户的方法,返回值中,除了userNmae ,其余都为unll
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FVc17XDw-1630683001862)(E:\SSM\bilibili\MarkDown\images\MySQL在windows不区分大小写.png)]
因为MySQL在Window中可以忽略字母的大小写(username —> userName ),而其他的字段在SQL语句运行时,字母不同无法获取( id —> userId )
方法一:起别名
<select id="findAll" resultType="com.itheima.pojo.User">
SELECT id AS userId, username AS userName, birthday AS userBirthday, sex AS userSex, address AS userAddress
FROM user
</select>
方法二:配置查询结果的列名和实体类的属性名建立对应关系
<!-- 通过resultMap 建立实体类和数据库字段的一一对应关系 id:该resultMap的编号 property:实体类字段名 column:数据库字段 -->
<resultMap id="userMap" type="com.itheima.pojo.User">
<!-- 主键字段的对用关系 -->
<id property="userId" column="id"/>
<!-- 非主键字段的对应关系 -->
<result property="userName" column="username"/>
<result property="userBirthday" column="birthday"/>
<result property="userAddress" column="address"/>
<result property="userSex" column="sex"/>
</resultMap>
<!--id为mapper类中对应方法名,resultType为定义的接收类型,一般为对应实体类 如果使用resultMap对应数据库,就不需要resultType -->
<select id="findAll" resultMap="userMap">
/* SELECT id AS userId, username AS userName, birthday AS userBirthday, sex AS userSex, address AS userAddress
FROM user*/
SELECT *
FROM user
</select>
起别名的方式因为是直接基于SQL语句,所以程序运行效率高;
"/>
```xml
<!--id为mapper类中对应方法名,resultType为定义的接收类型,一般为对应实体类 如果使用resultMap对应数据库,就不需要resultType -->
<select id="findAll" resultMap="userMap">
/* SELECT id AS userId, username AS userName, birthday AS userBirthday, sex AS userSex, address AS userAddress
FROM user*/
SELECT *
FROM user
</select>
起别名的方式因为是直接基于SQL语句,所以程序运行效率高;
resultMap的方式配置一个resultMap就可以应用到多个mapper方法中,开发效率高