1.CURD操作
第一步:创建maven工程并导入坐标
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.itheima</groupId> <artifactId>day02_eesy_01mybatisCURD</artifactId> <version>1.0-SNAPSHOT</version> <packaging>jar</packaging> <dependencies> <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</artifactId> <version>3.4.5</version> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>5.1.6</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.12</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.10</version> </dependency> </dependencies> </project>
第二步:创建实体类和dao的接口
package com.itheima.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private Integer id; private String username; private Date birthday; private String sex; private String address; 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 Date getBirthday() { return birthday; } public void setBirthday(Date birthday) { this.birthday = birthday; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } @Override public String toString() { return "User{" + "id=" + id + ", username='" + username + '\'' + ", birthday=" + birthday + ", sex='" + sex + '\'' + ", address='" + address + '\'' + '}'; } }
package com.itheima.dao; import com.itheima.domain.User; import java.util.List; public interface IUserDao { /** * 查询所有用户 * @return */ List<User> findAll(); /** * 保存用户 * @param user */ void saveUser(User user); /** * 更新用户 * @param user */ void updateUser(User user); /** * 根据Id删除用户 * @param userId */ void deleteUser(Integer userId); /** * 根据id查询用户信息 * @param userId * @return */ User findById(Integer userId); /** * 根据名称模糊查询用户信息 * @param username * @return */ List<User> findByName(String username); /** * 查询总用户数 * @return */ int findTotal(); }
第三步:创建Mybatis的主配置文件
<?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"> <!-- mybatis的主配置文件 --> <configuration> <!-- 配置环境 --> <environments default="mysql"> <!-- 配置mysql环境 --> <environment id="mysql"> <!-- 事物类型 --> <transactionManager type="JDBC"></transactionManager> <!-- 配置数据源(连接池) --> <dataSource type="POOLED"> <property name="driver" value="com.mysql.jdbc.Driver" /> <property name="url" value="jdbc:mysql://localhost:3306/eesy_mybatis" /> <property name="username" value="root" /> <property name="password" value="123456" /> </dataSource> </environment> </environments> <!-- 指定映射配置文件的位置,映射配置文件指的是dao独立的配置文件--> <mappers> <mapper resource="com/itheima/dao/IUserDao.xml"/> </mappers> </configuration>
第四步:创建映射配置文件
<?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.itheima.dao.IUserDao"> <!-- 配置查询所有 --> <select id="findAll" resultType="com.itheima.domain.User"> select * from user; </select> <!-- 保存用户 --> <insert id="saveUser" parameterType="com.itheima.domain.User"> insert into user(username,address,sex,birthday)values(#{username},#{address},#{sex},#{birthday}) </insert> <!-- 更新用户 --> <update id="updateUser" parameterType="com.itheima.domain.User"> update user set username=#{username},address=#{address} where id=#{id}; </update> <!-- 删除用户--> <delete id="deleteUser" parameterType="Integer"> delete from user where id=#{uid}; </delete> <!-- 根据id查询用户 --> <select id="findById" parameterType="INT" resultType="com.itheima.domain.User"> select * from user where id = #{uid} </select> <!-- 根据名称模糊查询 --> <select id="findByName" parameterType="string" resultType="com.itheima.domain.User"> select * from user where username like #{name} </select> <!-- 获取用户的总记录条数 --> <select id="findTotal" resultType="int"> select count(id) from user; </select> </mapper>
第五歩:测试程序
package com.itheima.test; import com.itheima.dao.IUserDao; import com.itheima.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.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; /** * 测试mybatis的crud操作 */ public class MybatisTest { private InputStream in; private SqlSession sqlSession; private IUserDao userDao; @Before public void init() throws IOException { // 1.读取文件 in = Resources.getResourceAsStream("SqlMapConfig.xml"); // 2.创建SqlSessionFactory工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); // 3.使用工厂生产SQLSession对象 sqlSession = factory.openSession(); // 4.使用SQLSession创建Dao接口的代理对象 userDao = sqlSession.getMapper(IUserDao.class); } @After public void destroy() throws IOException { // 提交事务 sqlSession.commit(); // 关闭资源 sqlSession.close(); in.close(); } /** * 查询所有用户 */ @Test public void findAll() throws IOException { List<User> users = userDao.findAll(); for (User user : users) { System.out.println(user); } } /** * 保存(插入)用户 */ @Test public void testSave() { User user = new User(); user.setUsername("mybatis saveuser"); user.setAddress("beijing"); user.setSex("男"); user.setBirthday(new Date()); userDao.saveUser(user); } /** * 更新用户信息 */ @Test public void testUpdate(){ User user = new User(); user.setId(52); user.setUsername("mybatis updateUser"); user.setAddress("beijing"); userDao.updateUser(user); } /** * 测试删除操作 */ @Test public void testDelete(){ //5.执行删除方法 userDao.deleteUser(52); } /** * 根据id查询一个用户 */ @Test public void testFindOne(){ //5.执行查询一个方法 User user = userDao.findById(50); System.out.println(user); } /** * 测试模糊查询操作 */ @Test public void testFindByName(){ //5.执行查询一个方法 List<User> users = userDao.findByName("%王%"); for(User user : users){ System.out.println(user); } } /** * 测试查询总记录条数 */ @Test public void testFindTotal(){ //5.执行查询一个方法 int count = userDao.findTotal(); System.out.println(count); } }
问题扩展:新增用户 id
新增用户后,同时还要返回当前新增用户的 id 值,因为 id 是由数据库的自动增长来实现的,所以就相
当于我们要在新增后将自动增长 auto_increment 的值返回。
<!-- 保存用户 --> <insert id="saveUser" parameterType="com.itheima.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>
@Test public void testSave() { User user = new User(); user.setUsername("mybatis saveuser"); user.setAddress("beijing"); user.setSex("男"); user.setBirthday(new Date()); System.out.println("保存操作之前:"+user); //5.执行保存方法 userDao.saveUser(user); System.out.println("保存操作之后:"+user); }
2.OGNL表达式
Object Graphic Navigation Language
对象 图 导航 语言
它是通过对象的取值方法来获取数据。在写法上把get给省略了。
比如:我们获取用户的名称
类中的写法:user.getUsername();
OGNL表达式写法:user.username
mybatis中为什么能直接写username,而不用user.呢:
因为在parameterType中已经提供了属性所属的类,所以此时不需要写对象名
3.传递pojo包装对象
由多个对象组成一个条件,来实现数据的查询
开发中通过 pojo 传递查询条件 ,查询条件是综合的查询条件,不仅包括用户查询条件还包括其它的查询条件(比如将用户购买商品信息也作为查询条件),这时可以使用包装对象传递输入参数。Pojo 类中包含 pojo。
需求:根据用户名查询用户信息,查询条件放到 QueryVo 的 user 属性中
3.1编写QueryVo
package com.itheima.domain; import java.io.Serializable; public class QueryVo implements Serializable { private User user; public User getUser() { return user; } public void setUser(User user) { this.user = user; } }
3.2编写持久层接口
package com.itheima.dao; import com.itheima.domain.QueryVo; import com.itheima.domain.User; import java.util.List; public interface IUserDao { /** * 查询总用户数 * @return */ int findTotal(); /** * 根据queryVo中的查询条件查询用户 */ List<User> findUserByVo(QueryVo vo); }
3.3持久层接口的映射文件
<!--根据queryVo的条件查询用户--> <select id="findUserByVo" parameterType="com.itheima.domain.QueryVo" resultType="com.itheima.domain.User"> select * from user where username like #{user.username} </select>
3.4测试
/** * 测试使用queryVo作为查询条件 */ @Test public void testFindByQueryVo() { QueryVo vo = new QueryVo(); User user = new User(); user.setUsername("%王%"); vo.setUser(user); List<User> users = userDao.findUserByVo(vo); for(User u : users) { System.out.println(u); } }
4.解决实体类属性和数据库列名不对应的两种方式
package com.itheima.domain; import java.io.Serializable; import java.util.Date; public class User implements Serializable { private Integer userId; private String userName; private String userAddress; private String userSex; private Date userBirthday; public Integer getUserId() { return userId; } public void setUserId(Integer userId) { this.userId = userId; } public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } public String getUserAddress() { return userAddress; } public void setUserAddress(String userAddress) { this.userAddress = userAddress; } public String getUserSex() { return userSex; } public void setUserSex(String userSex) { this.userSex = userSex; } public Date getUserBirthday() { return userBirthday; } public void setUserBirthday(Date userBirthday) { this.userBirthday = userBirthday; } @Override public String toString() { return "User{" + "userId=" + userId + ", userName='" + userName + '\'' + ", userAddress='" + userAddress + '\'' + ", userSex='" + userSex + '\'' + ", userBirthday=" + userBirthday + '}'; } }
<!-- 保存用户 --> <insert id="saveUser" parameterType="com.itheima.domain.User"> <!-- 配置插入操作后,获取插入数据的id --> <selectKey keyProperty="userId" keyColumn="id" resultType="int" order="AFTER"> select last_insert_id(); </selectKey> insert into user(username,address,sex,birthday)values(#{userName},#{userAddress},#{userSex},#{userBirthday}) </insert> <!-- 更新用户 --> <update id="updateUser" parameterType="com.itheima.domain.User"> update user set username=#{userName},address=#{userAddress} where id=#{userId}; </update>
/** * 保存(插入)用户 */ @Test public void testSave() { User user = new User(); user.setUserName("mybatis saveuser2"); user.setUserAddress("beijing"); user.setUserSex("男"); user.setUserBirthday(new Date()); System.out.println("保存操作之前:"+user); //5.执行保存方法 userDao.saveUser(user); System.out.println("保存操作之后:"+user); } /** * 更新用户信息 */ @Test public void testUpdate(){ User user = new User(); user.setUserId(53); user.setUserName("mybatis updateUser2"); user.setUserAddress("beijing"); userDao.updateUser(user); }
对于增删改操作,可以利用以上方式,然而这种方式有点繁琐,但是这是在sql语句里进行的操作,相对来说,速度更快。
对于查询所有该如何处理呢?
<!-- 配置查询所有 --> <select id="findAll" resultType="com.itheima.domain.User"> select * from user; </select>
/** * 查询所有用户 */ @Test public void findAll() throws IOException { List<User> users = userDao.findAll(); for (User user : users) { System.out.println(user); } }
结果是除了username之外的值,都封装不进去,因为mysql在Windows上是不区分大小写的,username=userName。
那么该怎么办呢?
4.1起别名
<!-- 配置查询所有 --> <select id="findAll" resultType="com.itheima.domain.User"> select id as userId,username as userName,address as userAddress,sex as userSex,birthday as userBirthday from user; </select>
4.2采用映射配置
<!-- 配置 查询结果的列名和实体类的属性名的对应关系 --> <resultMap id="userMap" type="com.itheima.domain.User"> <!-- 主键字段的对应 --> <id property="userId" column="id"></id> <!--非主键字段的对应--> <result property="userName" column="username"></result> <result property="userAddress" column="address"></result> <result property="userSex" column="sex"></result> <result property="userBirthday" column="birthday"></result> </resultMap> <!-- 配置查询所有 --> <select id="findAll" resultMap="userMap"> select * from user ; </select>
5.Mybatis实现DAO的传统开发方式
5.1持久层Dao
package com.itheima.dao; import com.itheima.domain.User; import java.util.List; public interface IUserDao { /** * 查询所有用户 * @return */ List<User> findAll(); /** * 保存用户 * @param user */ void saveUser(User user); /** * 更新用户 * @param user */ void updateUser(User user); /** * 根据Id删除用户 * @param userId */ void deleteUser(Integer userId); /** * 根据id查询用户信息 * @param userId * @return */ User findById(Integer userId); /** * 根据名称模糊查询用户信息 * @param username * @return */ List<User> findByName(String username); /** * 查询总用户数 * @return */ int findTotal(); }
5.2持久层 Dao实现类
package com.itheima.dao.impl; import com.itheima.dao.IUserDao; import com.itheima.domain.User; import org.apache.ibatis.session.SqlSession; import org.apache.ibatis.session.SqlSessionFactory; import java.util.List; /** * @author 黑马程序员 * @Company */ public class UserDaoImpl implements IUserDao { private SqlSessionFactory factory; public UserDaoImpl(SqlSessionFactory factory){ this.factory = factory; } public List<User> findAll() { //1.根据factory获取SqlSession对象 SqlSession session = factory.openSession(); //2.调用SqlSession中的方法,实现查询列表 List<User> users = session.selectList("com.itheima.dao.IUserDao.findAll");//参数就是能获取配置信息的key //3.释放资源 session.close(); return users; } public void saveUser(User user) { //1.根据factory获取SqlSession对象 SqlSession session = factory.openSession(); //2.调用方法实现保存 session.insert("com.itheima.dao.IUserDao.saveUser",user); //3.提交事务 session.commit(); //4.释放资源 session.close(); } public void updateUser(User user) { //1.根据factory获取SqlSession对象 SqlSession session = factory.openSession(); //2.调用方法实现更新 session.update("com.itheima.dao.IUserDao.updateUser",user); //3.提交事务 session.commit(); //4.释放资源 session.close(); } public void deleteUser(Integer userId) { //1.根据factory获取SqlSession对象 SqlSession session = factory.openSession(); //2.调用方法实现更新 session.update("com.itheima.dao.IUserDao.deleteUser",userId); //3.提交事务 session.commit(); //4.释放资源 session.close(); } public User findById(Integer userId) { //1.根据factory获取SqlSession对象 SqlSession session = factory.openSession(); //2.调用SqlSession中的方法,实现查询一个 User user = session.selectOne("com.itheima.dao.IUserDao.findById",userId); //3.释放资源 session.close(); return user; } public List<User> findByName(String username) { //1.根据factory获取SqlSession对象 SqlSession session = factory.openSession(); //2.调用SqlSession中的方法,实现查询列表 List<User> users = session.selectList("com.itheima.dao.IUserDao.findByName",username); //3.释放资源 session.close(); return users; } public int findTotal() { //1.根据factory获取SqlSession对象 SqlSession session = factory.openSession(); //2.调用SqlSession中的方法,实现查询一个 Integer count = session.selectOne("com.itheima.dao.IUserDao.findTotal"); //3.释放资源 session.close(); return count; } }
5.3持久层映射配置
<?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.itheima.dao.IUserDao"> <!-- 配置查询所有 --> <select id="findAll" resultType="com.itheima.domain.User"> select * from user ; </select> <!-- 保存用户 --> <insert id="saveUser" parameterType="com.itheima.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> <!-- 更新用户 --> <update id="updateUser" parameterType="com.itheima.domain.User"> update user set username=#{username},address=#{address} where id=#{id}; </update> <!-- 删除用户--> <delete id="deleteUser" parameterType="Integer"> delete from user where id=#{uid}; </delete> <!-- 根据id查询用户 --> <select id="findById" parameterType="INT" resultType="com.itheima.domain.User"> select * from user where id = #{uid} </select> <!-- 根据名称模糊查询 --> <select id="findByName" parameterType="string" resultType="com.itheima.domain.User"> select * from user where username like #{name} </select> <!-- 获取用户的总记录条数 --> <select id="findTotal" resultType="int"> select count(id) from user; </select> </mapper>
5.4 测试类
package com.itheima.test; import com.itheima.dao.IUserDao; import com.itheima.dao.impl.UserDaoImpl; import com.itheima.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.junit.After; import org.junit.Before; import org.junit.Test; import java.io.IOException; import java.io.InputStream; import java.util.Date; import java.util.List; /** * 测试mybatis的crud操作 */ public class MybatisTest { private InputStream in; private IUserDao userDao; @Before public void init() throws IOException { // 1.读取文件 in = Resources.getResourceAsStream("SqlMapConfig.xml"); // 2.创建SqlSessionFactory工厂 SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(in); //3.使用工厂对象,创建dao对象 userDao = new UserDaoImpl(factory); } @After public void destroy() throws IOException { in.close(); } /** * 查询所有用户 */ @Test public void findAll() throws IOException { List<User> users = userDao.findAll(); for (User user : users) { System.out.println(user); } } /** * 保存(插入)用户 */ @Test public void testSave() { User user = new User(); user.setUsername("mybatis saveuser2"); user.setAddress("beijing"); user.setSex("男"); user.setBirthday(new Date()); System.out.println("保存操作之前:"+user); //5.执行保存方法 userDao.saveUser(user); System.out.println("保存操作之后:"+user); } /** * 更新用户信息 */ @Test public void testUpdate(){ User user = new User(); user.setId(56); user.setUsername("mybatis updateUser2"); user.setAddress("beijing"); userDao.updateUser(user); } /** * 测试删除操作 */ @Test public void testDelete(){ //5.执行删除方法 userDao.deleteUser(57); } /** * 根据id查询一个用户 */ @Test public void testFindOne(){ //5.执行查询一个方法 User user = userDao.findById(50); System.out.println(user); } /** * 测试模糊查询操作 */ @Test public void testFindByName(){ //5.执行查询一个方法 List<User> users = userDao.findByName("%王%"); for(User user : users){ System.out.println(user); } } /** * 测试查询总记录条数 */ @Test public void testFindTotal(){ //5.执行查询一个方法 int count = userDao.findTotal(); System.out.println(count); } }