【2】. mybatis入门程序:查询用户信息、用户添加、用户修改和删除、mybatis和 Hibernate的适用场景
总结:mybatis开发过程:
- 编写SqlMapConfig.xml(全局)配置文件
- 编写mapper.xml配置文件——即定义statement
- 通过配置文件创建SqlSessionFactory(Test.java中);
通过SqlSessionFactory获取SqlSession;
通过SqlSession操作数据库;
(如果执行的是insert、update、delete方法时,需要调用commit(),提交完后才能真正写入到数据库中)
SqlSession使用完关闭。
(1) 用户查询
1.需求:
根据用户 id(主键)查询用户信息——返回 单条信息
根据用户名字查询用户信息——返回 多条信息
用户添加、删除、修改
2.创建项目:
(总结: classpath即 config文件夹下有一个全局配置文件 SqlMapConfig.xml 、子包 sqlmap下一个属性文件 log4j.properties,一个映射文件 User.xml;有一个 User.java类,它与数据库中表的字段对应;用到的 jar包有 jdbc驱动包、mybatis包、mybatis用到的依赖包)
①导入 jar包(创建 lib文件夹,导入mybatis的 jar包、相关依赖的jar包);
②SqlMapConfig.xml、log4j.properties(全局配置文件、属性文件)(config文件夹下);
③Mapper.xml(表名+Mapper.xml / 表名.xml)
④创建 POJO类 User.java(id、username、age)
SqlMapConfig.xml:< environments>中环境变量 < environment> 可有多个:若两个,< environment id=“mysql”>、< environment id=“oracle”>,此时由< environments default=“X”>来决定用哪个; mapper是在classpath下的 sqlmap文件夹中;
<?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>
<!--环境变量的配置-->
<environments default="mysql">
<environment id="mysql">
<!--事务的配置(此处用JDBC)-->
<transactionManager type="JDBC"/>
<!--数据源的配置(此处用连接池)-->
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/human_resource"/>
<property name="username" value="root"/>
<property name="password" value="12345"/>
</dataSource>
</environment>
</environments>
<!--mapper的配置-->
<mappers>
<mapper resource="sqlmap/User.xml"/>
</mappers>
</configuration>
User.xml: mapper.xml文件中配置的 sql语句,执行每一个 sql,都将封装为 MapperdStatement对象,mapper.xml是以 statement为单位来管理 sql语句的,id用来唯一标识 statement; parameterType 输入参数类型,通过 #{}(#{}内名称任意); resultType 输出参数类型,返回单条或多条记录,要指明类型;#{ } 表示占位符,如果参数是 String类型会自动添加 ’ ',eg: select * from users where username=? ${value} 表示 Sql语句拼接,不会自动再添加 ’ ',eg: select * from users where username=%张% 。
<?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="test">
<select id="findUserById" parameterType="int" resultType="com.iotek.po.User">
select * from Users where id=#{id}
</select>
<select id="findUserByName" parameterType="string" resultType="com.iotek.po.User">
select * from Users where username=#{id} / username like '%${value}%'
</select>
<!-- 添加用户 -->
<insert id="addUser" parameterType="com.iotek.po.User">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select last_insert_id()
</selectKey>
insert into Users(username,age) values(#{username},#{age})
</insert>
<!-- 删除用户 -->
<delete id="deleteUser" parameterType="int">
delete from Users where id=#{id}
</delete>
<!-- 修改用户 -->
<update id="updateUser" parameterType="com.iotek.po.User">
update Users set username=#{username},age=#{age} where id=#{id}
</update>
</mapper>
AppTest.java: 上图所示,首先需要一个 SqlSessionFactory;再通过 SqlSessionFactory.openSession() 得到sqlSession,打开之后要关闭;查询单条记录:sqlSession.selectOne(satatementId,parameter)中第一个参数是 statement,即在 mapper.xml文件中所设置的 id唯一标识符,第二个参数是 mapper.xml文件中 id对应的输入参数 parameterType的类型;查询多条记录:sqlSession.selectList(satatementId,parameter),即如果返回多条记录用 selectList,不能用 selectOne,会抛异常报错。
public class AppTest {
SqlSessionFactory sqlSessionFactory=null;
@Before
public void init() throws IOException {
InputStream inputStream=Resources.getResourcesAsStream("SqlMapConfig.xml");
sqlSessionFactory=new SqlSessionFactoryBuilder().build(inputStream);
}
@Test
public void testFindUserById(){
SqlSession sqlSession=sqlSessionFactory.openSession();
User user=(User) sqlSession.selectOne("findUserById",1);
sqlSession.close();
System.out.println(user.getId()+","+user.getUsername());
}
@Test
public void testFindUserByName(){
SqlSession sqlSession=sqlSessionFactory.openSession();
List<User> users=(User) sqlSession.selectList("findUserByName","tom");
for (User user:users) {
System.out.println(user.getId()+","+user.getUsername());
}
sqlSession.close();
}
@Test
public void testAddUser(){
SqlSession sqlSession=sqlSessionFactory.openSession();
User user=new User("tom",10);
sqlSession.insert("addUser",user);
sqlSession.commit();
sqlSession.close();
System.out.println(当前插入的用户id为+":"+user.getId());
}
@Test
public void testDeleteUser(){
SqlSession sqlSession=sqlSessionFactory.openSession();
sqlSession.delete("deleteUser",2);
sqlSession.commit();
sqlSession.close();
}
@Test
public void testUpdateUser(){
SqlSession sqlSession=sqlSessionFactory.openSession();
//User user=new User(1,"jay",20);
User user=new User();
user.setId(1);
user.setUsername("Hery");
sqlSession.update("updateUser",user);
sqlSession.commit();
sqlSession.close();
}
}
(2) 添加用户
User.xml: 上面中 insert into Users(username,age) values(#{username},#{age}) ; parameterType输入类型可以是简单类型、POJO类型,这里输入多个值(username、age),所以是 User类型;不需要有返回,所以无 resultType;values(?,?),?相当于 #{ },当是基本数据类型,#{ } 中的值任意写,但此中是 POJO类型,是通过类对象中的 get方法取值,即 insert into Users(username,age)中 username是通过类中 getUsername()去取值,去掉 get,首字母小写,所以是 values(#{username},#{age});
【 #{ } 和 ${ } 区别 】:
1.如果使用 #{ } 占位符则必须人为在传入的参数中加 % ;
eg:List< User> list=userMapper.selectUserByName(“%丽”);
2.如果使用 ${ } 则不需要人为在传入的参数中加 % ;
eg:List< User> list=userMapper.selectUserByName(“丽”);
3.order by 排序,用 ${ } 。如:列名通过参数传入 sql,根据传的列名进行排序,用 ${ } ,如果用 #{ } 则无法实现。写为:
eg:order by ${columnName}
<insert id="addUser" parameterType="com.iotek.po.User">
<selectKey keyProperty="id" order="AFTER" resultType="int">
select last_insert_id()
</selectKey>
insert into Users(username,age) values(#{username},#{age})
</insert>
AppTest.java: 上面中调用 sqlSession的 insert方法,insert(,)中第一个参数是 statement的名字,唯一标识 id即 addUser,第二个参数是传入的参数是 User类型的即 user;再调用 commit();
@Test
public void testAddUser(){
SqlSession sqlSession=sqlSessionFactory.openSession();
User user=new User("tom",10);
sqlSession.insert("addUser",user);
sqlSession.commit();
sqlSession.close();
System.out.println(当前插入的用户id为+":"+user.getId());
}
需求:获取新插入记录的 自增主键 值
思路:Mysql中 **last_insert_id()**获得刚插入的记录的自动编号值
User.xml: 上面中 < insert>< /insert>中添加< selectKey>< /selectKey>;order:指获得 < insert>中 sql语句执行前还是执行后的值,即执行顺序(此处想获得执行后的值,所以是 AFTER);resultType返回类型是自动编号的值 int;keyProperty将主键的值设置到 pojo类的哪一个属性上 通过setId(),去掉set,首字母小写即 id;执行 select last_insert_id()方法。
AppTest.java: 上面中输出 当前插入的用户id。
<insert id="addUser" parameterType="com.iotek.po.User">
<selectKey order="AFTER" resultType="int" keyProperty="id">
select last_insert_id()
</selectKey>
insert into Users(username,age) values(#{username},#{age})
</insert>
(3) 删除用户
User.xml: 上面中 < delete>< /delete>;parameterType输入类型 int;
<delete id="deleteUser" parameterType="int">
delete from Users where id=#{id}
</delete>
AppTest.java: 上面中调用 sqlSession的 delete方法,delete(,)中第一个参数是 statement的名字,唯一标识 id即 deleteUser,第二个参数的类型是传入的参数类型 int;
@Test
public void testDeleteUser(){
SqlSession sqlSession=sqlSessionFactory.openSession();
sqlSession.delete("deleteUser",2);
sqlSession.commit();
sqlSession.close();
}
(4) 修改用户
update Users set username=#{username},age=#{age} where id=#{id}
User.xml: 上面中 < update>< /update>;parameterType输入类型是 pojo类;set username=#{username},age=#{age} where id=#{id},可看出(作修改操作时 id必须传值)拿到User类中的 getUsername(),去掉 get,首字母小写;
<update id="updateUser" parameterType="com.iotek.po.User">
update Users set username=#{username},age=#{age} where id=#{id}
</update>
AppTest.java: 上面中调用 sqlSession的 update方法,update(,)中第一个参数是 statement的id,updateUser,第二个参数的类型是传入的参数类型 user;想修改编号为 1的tom年龄10,改为jay年龄20;(若没有 setAge(),即 age未设置值,运行时会成功修改,但 age值为默认值 0;若没有 setName(),即 name未设置值,运行成功后 name值显示为 null;
@Test
public void testUpdateUser(){
SqlSession sqlSession=sqlSessionFactory.openSession();
//User user=new User(1,"jay",20);
User user=new User();
user.setId(1);
user.setUsername("Hery");
sqlSession.update("updateUser",user);
sqlSession.commit();
sqlSession.close();
}
(首页网址: https://blog.csdn.net/qq_41029923/article/details/83472411 )