Mybatis学习(三)增删改查
目录
一、mybatis实现增删改查
项目结构
1、user实体类:实体类属性和数据库列名匹配
package com.mybatis.domain;
public class User {
//实体类属性和数据库列名匹配
private Integer id;
private String username;
private String password;
private String email;
@Override
public String toString() {
return "User{" +
"id=" + id +
", username='" + username + '\'' +
", password='" + password + '\'' +
", email='" + email + '\'' +
'}';
}
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 getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
2、 UserDao接口:定义方法
package com.mybatis.dao;
import com.mybatis.domain.QueryVo;
import com.mybatis.domain.User;
import org.apache.ibatis.annotations.Select;
import java.util.List;
/**
* @Description: 用户持久层接口
*/
public interface UserDao {
//查询所有操作
/* @Select("select * from t_user"),不用配置,用注解*/
List<User> findAll();
//保存用户信息
void saveUser(User user);
//更新用户
void updateUser(User user);
//根据id删除用户
void deleteUser(Integer id);
//根据id查找用户
User selectUserById(Integer id);
//根据名称模糊查询用户信息
List<User> findByName(String username);
//查询总记录数
Integer totalNum();
//根据QueryVo中的条件查询
List<User> findUserByVo(QueryVo vo);
}
3、映射文件UserDao.xml
namespace 即空间命名名称:
绑定dao层接口的全路径,会自动产生代理,自动实现数据的持久化,不需要实现dao层的接口
- <insert> SQL语句 </insert>增
- <delete> SQL语句 </delete>删
- <update> SQL语句 </update>改
- <select> SQL语句 </select>查
id 为方法名称,namespace+id可以映射dao接口的方法
resultType 代表返回值的类型,简单类型、实体类等,如果是实体类需要实体类的全限定类名
resultMap
parameterType 代表方法中参数的类型,
简单类型:比如Integer、int、java.lang.Integer都行,因为配置了别名。
实体类:需要写全限定类名,SQL语句要获取某一属性只需要 # { 属性名 },实体类的属性最好要跟set和get的方法名匹配,OGNL表达式解析对象字段的值
pojo包装对象:下例中com.mybatis.domain.QueryVo
<?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">
<!--绑定dao层接口-->
<mapper namespace="com.mybatis.dao.UserDao">
<!--配置查询所有,id为方法的名称,resultType返回值封装到哪个实体类,实体类的全限定类名-->
<!--查找所有用户-->
<select id="findAll" resultType="com.mybatis.domain.User">
SELECT * FROM t_user;
</select>
<!--保存用户-->
<insert id="saveUser" parameterType="com.mybatis.domain.User">
INSERT into t_user(id,username,password,email)VALUE (#{userid},#{username},#{userpassword},#{useremail});
</insert>
<!--更新用户-->
<update id="updateUser" parameterType="com.mybatis.domain.User">
UPDATE t_user SET id=#{id},username=#{username},password=#{password},email=#{email} WHERE id=#{id};
</update>
<!--根据id删除用户-->
<delete id="deleteUser" parameterType="Integer">
DELETE FROM t_user WHERE id=#{id};
</delete>
<!--根据id查询用户-->
<select id="selectUserById" parameterType="Integer" resultType="com.mybatis.domain.User">
SELECT * FROM t_user WHERE id=#{id};
</select>
<!--根据名称模糊查询用户信息-->
<select id="findByName" parameterType="String" resultType="com.mybatis.domain.User">
<!--测试类要提供百分号,"%王%",占位符,推荐使用-->
SELECT * FROM t_user WHERE username LIKE #{name};
<!--模糊查询的另一种写法,"王",字符串拼接
select * from user where username like '%${value}%';-->
</select>
<!--查询总记录数-->
<select id="totalNum" resultType="Integer">
SELECT count(id) FROM t_user;
</select>
<!--根据queryvo条件查询-->
<select id="findUserByVo" parameterType="com.mybatis.domain.QueryVo" resultType="com.mybatis.domain.User">
SELECT * FROM t_user WHERE username LIKE #{user.username}
</select>
</mapper>
4、测试方法MybatisTest
代理对象userDao,userDao.xxxx( ) ,xxxx和映射文件中的 id=xxxx对应
package com.mybatis;
import com.mybatis.dao.UserDao;
import com.mybatis.domain.QueryVo;
import com.mybatis.domain.User;
import org.apache.ibatis.io.Resources;
import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.apache.ibatis.session.SqlSessionFactoryBuilder;
import org.apache.log4j.lf5.util.Resource;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.io.InputStream;
import java.util.List;
import static org.apache.ibatis.io.Resources.getResourceAsStream;
/*Mybatis案例*/
public class MybatisTest {
private InputStream in;
private SqlSession sqlSession;
private UserDao userDao;
@Before //测试方法之前执行
public void init()throws IOException{
//1.读取配置文件
in= Resources.getResourceAsStream("SqlMapConfig.xml");
//2.创建SqlSessionFactory工厂
SqlSessionFactoryBuilder builder=new SqlSessionFactoryBuilder();
SqlSessionFactory factory=builder.build(in);
//3.使用工厂生产SqlSession对象
sqlSession =factory.openSession();
//4.使用SqlSession创建Dao接口的代理对象
userDao=sqlSession.getMapper(UserDao.class);
}
@After //测试方法之后执行
public void destroy() throws IOException {
//提交事务
sqlSession.commit();
//6.释放资源
sqlSession.close();
in.close();
}
@Test//查询所有记录
public void testFindAll() throws IOException {
//5.使用代理对象执行方法
List<User> users=userDao.findAll();
for (User user:users){
System.out.println(user);
}
}
@Test//保存用户
public void testSave(){
User user=new User();
/*user.setId(4);*/
user.setUsername("杜甫");
user.setUserpassword("dufu");
user.setUseremail("aaa@qq.com");
System.out.println("保存之前:"+user);
//5.使用代理对象执行方法
userDao.saveUser(user);
System.out.println("保存之后:"+user);
}
@Test //测试更新方法
public void testUpdate(){
User user=new User();
user.setUserid(6);
user.setUsername("杜甫001");
user.setUserpassword("dufu");
user.setUseremail("aaa@qq.com");
//5.使用代理对象执行方法
userDao.updateUser(user);
}
@Test //测试删除方法
public void testdeleteUser(){
Integer id=6;
//5.使用代理对象执行方法
userDao.deleteUser(6);
}
@Test //测试根据id查询用户方法
public void selectUserById(){
Integer id=6;
//5.使用代理对象执行方法
User user = userDao.selectUserById(id);
System.out.println(user);
}
@Test //测试根据username查询用户方法
public void findUserByname(){
String name="%王%";
//5.使用代理对象执行方法
List<User> users = userDao.findByName(name);
for (User user:users){
System.out.println(user);
}
}
@Test //测试查询总记录数
public void findtotalNum(){
Integer total=userDao.totalNum();
System.out.println(total);
}
@Test //测试根据findUserByVo查询用户方法
public void findUserByVo(){
QueryVo vo=new QueryVo();
User user=new User();
user.setUsername("%王%");
vo.setUser(user);
//5.使用代理对象执行方法
List<User> users = userDao.findUserByVo(vo);
for (User u:users){
System.out.println(u);
}
}
}
需求一:保存用户后,获取刚刚保存的用户id
映射文件userdao.xml
<selectKey>
标签的参数详解
KeyProperty:实体类属性名称
KeyColumn:数据库列名
resultType:返回值类型
order:是之后执行还是之前执行
<!-- 保存用户-->
<insert id="saveUser" parameterType="com.mybatis.domain.User">
<-- 配置插入操作后,获取插入数据的id-->
<selectKey keyProperty="id" keyColumn="id" resultType="int" order="AFTER">
select last_insert_id();
</selectKey>
insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday});
</insert>
需求二:使用实体类的包装对象作为查询条件
QueryVo.java
public class QueryVo {
private User user;
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
需求三:实体类的属性名和数据库的列名不一致
user.java
package com.mybatis.domain;
public class User {
//和数据库中名字不一样
private Integer userid;
private String username;
private String userpassword;
private String useremail;
}
方法一:起别名,执行效率高,开发效率低
userDao.xml
<!-- 配置查询所有-->
<select id="findAll" resultType="com.zzq.domain.User">
select
id as userid,
username as username,
password as userpassword,
email as useremail,
from
t_user;
</select>
方法二:通过配置的方式
userDao.xml,select标签中resultMap值和resulMap标签中的id值一致
<?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.mybatis.dao.UserDao">
<!--2.通过配置,解决解决实体类属性和数据库列名不匹配-->
<resultMap id="userMap" type="com.mybatis.domain.User">
<!--主键字段的对应-->
<id property="userid" column="id"></id>
<!--非主键字段的对应-->
<result property="username" column="username"></result>
<result property="userpassword" column="password"></result>
<result property="useremail" column="email"></result>
</resultMap>
<!--2.通过配置对应关系-->
<select id="findAll" resultMap="userMap">
SELECT * FROM t_user;
</select>
二、主配置文件中的标签
properties标签:数据库连接
数据库连接信息除了写在dataSource中,还可以写在properties中,还可引入外部配置文件xxx.properties
<properties resource="类路径。xxx.properties"></properties>
typeAliases标签:别名
typeAlias配置别名,只能配置domain中类的别名,type属性指定的是实体类全限定类名,而alias属性指定别名,并且当指定了别名就不再区分大小写了,
package标签用于指定要配置的别名的包,当指定之后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写
mappers标签:映射文件
当package标签指定了dao接口所在的包时,就不需要再写mapper以及resource(或url)或者class了
SqlMapConfig.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!--XML 头部的声明,它用来验证 XML 文档的正确性。-->
<!DOCTYPE configuration
PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<!--mybatis主配置文件-->
<configuration>
<!--配置properties
可以在标签内配置连接数据库的信息,也可以通过属性resource引用外部配置文件
resource属性:指定配置文件的位置,按照类路径的写方法来写
url属性:按url的写法写地址,协议、主机、端口、URI
-->
<properties>
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/bookstore"/>
<property name="username" value="root"/>
<property name="password" value="123456"/>
</properties>
<!--使用typeAliases配置别名,只能配置domain中类的别名-->
<typeAliases>
<!--typeAliases配置别名,type属性指定实体类全限定类名,alias属性指定别名,当指定了别名就不再区分大小写-->
<!--<typeAlias type="com.mybatis.domain.User" alias="user"></typeAlias>-->
<!--package用于指定要配置别名的包,当指定后,该包下的实体类都会注册别名,并且类名就是别名,不再区分大小写-->
<package name="com.mybatis.domain"></package>
</typeAliases>
<!--配置环境-->
<environments default="mysql">
<!--配置mysql的环境-->
<environment id="mysql">
<!--配置事务的类型-->
<transactionManager type="JDBC"></transactionManager>
<!--配置数据源(连接池)-->
<dataSource type="POOLED">
<!--配置连接数据库的基本信息-->
<property name="driver" value="${driver}"/>
<property name="url" value="${url}"/>
<property name="username" value="${username}"/>
<property name="password" value="${password}"/>
</dataSource>
</environment>
</environments>
<!--指定映射配置文件(每个dao独立的配置文件)的位置,-->
<mappers>
<!--<mapper resource="com/mybatis/dao/UserDao.xml"/>-->
<!--如果用注解配置,此处应该使用class属性指定被注解的dao全限定类名-->
<!--<mapper class="com.mybatis.dao.UserDao"/>-->
<!--package指定dao接口所在的包,当指定之后就不需要再写mapper及resource或class了-->
<package name="com.mybatis.dao"></package>
</mappers>
</configuration>
上一篇: <shell多进程理解>