软件开发项目实践(二)
1. 利用MyBatis结合Junit、Log4j实现对数据库的增删改查。
导入MyBatis、Junit、Log4j和mysql驱动包,IntelliJ导包操作:File -> Project Structure -> Modules(左侧栏) -> 找到”+”,选择JARs -> 选择对应包路径即可。
确定各个包做的事情:
- MyBatis:主要解决了之前使用JDBC对数据库进行操作的繁杂步骤,是一种ORM。
- Junit:java测试框架。
- Log4j:主要用户log记录。
- mysql驱动:为java连接mysql数据库提供驱动及操作承载。
实验步骤:
安装mysql数据库,创建数据库,创建表。为方便进行实验,我创建的user表结构如下:
1
2
3
4
5
6
7
8
9+------------+-------------+------+-----+-------------------+-----------------------------+
| Field | Type | Null | Key | Default | Extra |
+------------+-------------+------+-----+-------------------+-----------------------------+
| id | int(11) | NO | PRI | NULL | auto_increment |
| passwd | varchar(16) | NO | | NULL | |
| nickname | varchar(20) | NO | | NULL | |
| createTime | timestamp | NO | | CURRENT_TIMESTAMP | |
| updateTime | datetime | YES | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP |
+------------+-------------+------+-----+-------------------+-----------------------------+创建java工程。导包。
编写User实例。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30public class User {
private Integer id;
private String passwd;
private String nickname;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getPasswd() {
return passwd;
}
public void setPasswd(String passwd) {
this.passwd = passwd;
}
public String getNickname() {
return nickname;
}
public void setNickname(String nickname) {
this.nickname = nickname;
}
}编写User.xml mapper文件。该文件可以暂时认为是之前JDBC做的事情,在此配置好User实例中对应的方法要操作数据库的事情。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<!-- mapper标签要指定namespace属性,不然会报错,可看做包名-->
<mapper namespace="com.pjhubs.dao.intf.UserDAO">
<select id="selectUserWithID" parameterType="int" resultType="com.pjhubs.instance.User">
select * from user where id = #{id}
</select>
<select id="selectAllUser" resultType="com.pjhubs.instance.User">
select * from user
</select>
<insert id="insertUser" parameterType="com.pjhubs.instance.User">
insert into user(nickname,passwd) values(#{nickname},#{passwd})
</insert>
<delete id="deleteUserWithID" parameterType="int">
delete from user where id=#{id}
</delete>
<update id="updateUserWithNickname" parameterType="com.pjhubs.instance.User">
update user set nickname=#{nickname} where id=#{id}
</update>
</mapper>编写MyBatis配置文件,SqlMapConfig.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<configuration>
<environments default="development">
<environment id="development">
<transactionManager type="JDBC"/>
<dataSource type="POOLED">
<property name="driver" value="com.mysql.jdbc.Driver"/>
<property name="url" value="jdbc:mysql://localhost:3306/your_database_name?useSSL=false"/>
<property name="username" value="your_database_name"/>
<property name="password" value="your_database_password"/>
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="User.xml"/>
</mappers>
</configuration>编写User接口及其实现。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92// ---------- user interface ---------
import java.util.List;
import com.pjhubs.instance.User;
public interface UserDAO {
public User selectUserWithID(int ID) throws Exception;
public List<User> selectAllUser() throws Exception;
public void insertUser(User user) throws Exception;
public void deleteUserWithID(int ID) throws Exception;
public void updateUserWithNickname(User user) throws Exception;
}
// ---------- user implements -----------
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
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 com.pjhubs.dao.intf.UserDAO;
import com.pjhubs.instance.User;
public class UserDAOImpl implements UserDAO {
public User selectUserWithID(int ID) throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
User user = session.selectOne("user.selectUserWithID", ID);
session.close();
return user;
}
public List<User> selectAllUser() {
List<User> usersList = new ArrayList<User>();
try {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
usersList = session.selectList("user.selectAllUser");
session.close();
} catch (Exception e) {
System.out.println(e);
}
return usersList;
}
public void insertUser(User user) throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
session.insert("user.insertUser", user);
// insert、Update、delete 加上 commit
session.commit();
session.close();
}
public void deleteUserWithID(int ID) throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
session.delete("user.deleteUserWithID", ID);
// insert、Update、delete 加上 commit
session.commit();
session.close();
}
public void updateUserWithNickname(User user) throws Exception {
String resource = "SqlMapConfig.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory factory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession session = factory.openSession();
session.update("user.updateUserWithNickname", user);
// insert、Update、delete 加上 commit
session.commit();
session.close();
}
}使用Junit进行测试。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52import java.util.List;
import org.junit.jupiter.api.Test;
import com.pjhubs.instance.User;
import com.pjhubs.dao.intf.UserDAO;
import com.pjhubs.dao.impl.UserDAOImpl;
public class UserTest {
public void testSelectAllUser() throws Exception {
UserDAO userDAO = new UserDAOImpl();
List<User> userList = userDAO.selectAllUser();
for (User user : userList) {
System.out.println("id:" + user.getId() + "昵称:" + user.getNickname());
}
}
public void testSelectUserWithID() throws Exception {
UserDAO userDAO = new UserDAOImpl();
User user = userDAO.selectUserWithID(1);
System.out.println("id:" + user.getId() + " 昵称:" + user.getNickname());
}
public void testInsertUser() throws Exception {
UserDAO userDAO = new UserDAOImpl();
User user = new User();
user.setNickname("PJHubs");
user.setPasswd("woaiwoziji123");
userDAO.insertUser(user);
}
public void testDeleteUserByID() throws Exception {
UserDAO userDAO = new UserDAOImpl();
userDAO.deleteUserWithID(1);
}
public void testUpdateUserNickname() throws Exception {
UserDAO userDAO = new UserDAOImpl();
User user = new User();
user.setNickname("pjhubs");
user.setId(1);
user.setPasswd("woaiwoziji123");
userDAO.updateUserWithNickname(user);
}
}使用Junit编写测试类,
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51import java.util.List;
import org.junit.jupiter.api.Test;
import com.pjhubs.instance.User;
import com.pjhubs.dao.intf.UserDAO;
import com.pjhubs.dao.impl.UserDAOImpl;
public class UserTest {
public void testSelectAllUser() throws Exception {
UserDAO userDAO = new UserDAOImpl();
List<User> userList = userDAO.selectAllUser();
for (User user : userList) {
System.out.println("id:" + user.getId() + "昵称:" + user.getNickname());
}
}
public void testSelectUserWithID() throws Exception {
UserDAO userDAO = new UserDAOImpl();
User user = userDAO.selectUserWithID(1);
System.out.println("id:" + user.getId() + " 昵称:" + user.getNickname());
}
public void testInsertUser() throws Exception {
UserDAO userDAO = new UserDAOImpl();
User user = new User();
user.setNickname("PJHubs");
user.setPasswd("woaiwoziji123");
userDAO.insertUser(user);
}
public void testDeleteUserByID() throws Exception {
UserDAO userDAO = new UserDAOImpl();
userDAO.deleteUserWithID(1);
}
public void testUpdateUserNickname() throws Exception {
UserDAO userDAO = new UserDAOImpl();
User user = new User();
user.setNickname("pjhubs");
user.setId(1);
user.setPasswd("woaiwoziji123");
userDAO.updateUserWithNickname(user);
}
}
至此经过八个步骤,实验完成,但还有个可以优化的地方,会发现其实在给UserDAO写implements时出现了非常多的重复性代码,经过一番搜索,发现可以使用MyBatis提供的Mapper代理开发模式进行优化,这个模式的意思是说,coder只需要编写mapper接口,可以认为是之前写的UserDAO interface,而不用再写具有相当多的重复性代码的implements,因为MyBatis会自动为Mapper接口生成动态代理实现类,编写Mapper接口类需要注意一下事项:
- mapper接口的全限定名(包名)要和mapper映射文件的namespace的值相同。
- mapper接口的方法名称要和mapper映射文件中的statement的id相同。
- mapper接口的方法参数只能有一个,且类型要和mapper映射文件中statement的parameterType的值保持一致。
- mapper接口的返回值类型要和mapper映射文件中statement的resultType值或resultMap中的type值保持一致。
可见如果想要做一些简单的操作,用这种模式最方便不过了。
接下来,需要修改User.xml文件为:
1 |
|
创建一个新的UserMapper接口类,
1 | import com.pjhubs.instance.User; |
创建一个新的测试类,
1 | import java.util.List; |
2. 自己定义一个线程,每过5秒钟将当前系统的使用内存,用Log4j打印到磁盘和屏幕。
创建一个线程类,
1 | package pjhubs; |
在Main方法中进行调用,
1 | public class Main { |